owned this note
owned this note
Published
Linked with GitHub
# 如何印出方程式與統計量到`ggplot`圖上
###### tags: `用R做` `學習筆記`
在[用 R 配適邏輯式族群生長曲線](/Gn27cCNxTnenaxBshHSTKg)文章中,最後輸出了族群成長的邏輯式函數配適結果;如果可以在圖中加上函數的方程式,那就可以傳達更多資訊了。於是在這裡嘗試了幾個作法,其中需要用到 `ggpmisc` 套件,也可以在 `ggplot` 中手動輸出方程式。
## 使用`ggpmisc`把方程式加在圖上
```java=
library(ggplot2)
library(ggpmisc)
#原先的圖
p <- ggplot(data = data, aes(x = Year, y = Population)) +
geom_line(data = predict, aes(x = x, y = y), size = 1) +
geom_point(color = "blue",size = 4) +
labs(x = "Year", y = "Estimated population size") +
scale_x_continuous(breaks = seq(2000, 2022, 2)) +
scale_y_continuous(labels = scales::comma) +
theme_bw() +
theme(axis.text = element_text(size = 12),
axis.title = element_text(size = 16),
panel.grid.minor = element_blank())
#加上方程式
format = "y=%6.0f/(1+exp(-%4.0f-%1.2fx))"
p + ggpmisc::stat_poly_eq(formula = NULL, output.type = "numeric", parse = F,
mapping = aes(label = sprintf(format, L, k, k0)),
label.x = "left", label.y = "top", size = 8)
#如果要使用parse=T,就要改變format的寫法
format = '"y"~"="~%6.0f~"/(1+exp(-"~%4.0f~"-"~%1.2f~"x))"'
p + ggpmisc::stat_poly_eq(formula = NULL, output.type = "numeric", parse = T,
mapping = aes(label = sprintf(format, L, k, k0)),
label.x = "left", label.y = "top", size = 8)
```
輸出的結果如下圖:

在這邊因為直接使用 $f(x)=\frac{L}{1+e^{-k-K_0\times x)}}$ 這個形式,所以在 $k$ 值的地方出現了 2 個負號,這是可以在 `format` 變數中調整的。
如果想要使用數學式,`ggpmisc` 套件也有提供相關功能,主要是調整 `parse` 參數,並使用[符合 `plotmath` 的輸入型式](https://www.rdocumentation.org/packages/grDevices/versions/3.6.2/topics/plotmath),讓程式的圖形裝置能夠把標準輸入轉譯為方程式。以下為調整後的程式碼:
```java=
format = "y==frac(%.6g, 1 + e^{-(%.4g + %.2g*x)})"
#要調整output.type與parse的值
p + ggpmisc::stat_poly_eq(formula = NULL, output.type = "LaTex", parse = T,
mapping = aes(label = sprintf(format, L, k, k0)),
label.x = "left", label.y = "top", size = 8)
```
如此一來,就可以印出美美的方程式到圖上了:

除此之外,`ggpmisc` 也可以輸出簡單線性迴歸的方程式與 *R<sup>2</sup>*、*p* 等統計值,詳見[說明書](https://cran.r-project.org/web/packages/ggpmisc/ggpmisc.pdf)。
如果今天不想用 `ggpmisc`,想純以 `ggplot2` 把方程式印在圖上,也是有辦法的。
## 使用`ggplot2`的功能把方程式加在圖上
如果了解 `sprintf()` 跟 `parse` 的妙處,其實用 `ggplot2` 的 `geom_text()` 功能,就可以直接輸出數學式子到圖上了:
```java=
p + geom_text(aes(x = min(x), y = max(y) - 0.1 * diff(range(y)),
label = sprintf("y==frac(%.6g, {1 + e^{-(%.4g + %.2g*x)}})", L, k, k0)),
parse = TRUE, size = 8, check_overlap = TRUE, hjust = 0)
```
出圖如下:

`geom_text()` 雖然需要指定文字標籤的 x,y 座標位置,但只要善用資料的特性,就可以快速完成指定,自由度也高些。
以上就是一些在 `ggplot2` 的出圖中加上方程式的方法。如果今天做的是簡單線性迴歸或者二元多次方程式的迴歸需要印出方程式之外的統計量,我會選擇 `ggpmisc`;如果只要印出方程式,那麼兩種方法差異不大;若是像這次的例子是邏輯式方程式,我就會使用 `geom_text()`,不會多呼叫一個套件函式了。
<span style="font-size:30px">🐕🦺</span><font color="dcdcdc">2023.10.25</font>