在图表上添加回归线方程和R^2

317

我想知道如何在ggplot上添加回归线方程和R^2。 我的代码是:

library(ggplot2)

df <- data.frame(x = c(1:100))
df$y <- 2 + 3 * df$x + rnorm(100, sd = 40)
p <- ggplot(data = df, aes(x = x, y = y)) +
            geom_smooth(method = "lm", se=FALSE, color="black", formula = y ~ x) +
            geom_point()
p

任何帮助都将不胜感激。


1
对于lattice图形,请参见latticeExtra::lmlineq() - Josh O'Brien
@JoshO'Brien 错误:'lmlineq'不是来自'namespace:latticeExtra'的导出对象 - robertspierre
10个回答

310

这里是一个解决方案

# GET EQUATION AND R-SQUARED AS STRING
# SOURCE: https://groups.google.com/forum/#!topic/ggplot2/1TgH-kG5XMA

lm_eqn <- function(df){
    m <- lm(y ~ x, df);
    eq <- substitute(italic(y) == a + b %.% italic(x)*","~~italic(r)^2~"="~r2, 
         list(a = format(unname(coef(m)[1]), digits = 2),
              b = format(unname(coef(m)[2]), digits = 2),
             r2 = format(summary(m)$r.squared, digits = 3)))
    as.character(as.expression(eq));
}

p1 <- p + geom_text(x = 25, y = 300, label = lm_eqn(df), parse = TRUE)

编辑。我找到了这段代码的来源。这是 ggplot2 谷歌小组中原帖的链接

输出


2
@JonasRaedle在我的电脑上关于使用annotate获得更好的文本的评论是正确的。 - IRTFM
3
在我的电脑上,这看起来与发布的输出完全不同,标签被重复覆盖了很多次,导致标签文本变得厚重和模糊。首先将标签传递给一个数据框可以解决问题(请参见我在下面评论中的建议)。 - PatrickT
@PatrickT:删除aes()和相应的)aes用于将数据框变量映射到视觉变量- 这里不需要,因为只有一个实例,所以您可以将所有内容放入主要的geom_text调用中。我会将其编辑到答案中。 - naught101
4
对于那些想要得到 r 和 p 值而非 R2 和方程式的人: eq <- substitute(italic(r)"="rvalue*","italic(p)"="~pvalue, list(rvalue = sprintf("%.2f",sign(coef(m)[2])*sqrt(summary(m)$r.squared)), pvalue = format(summary(m)$coefficients[2,4], digits = 2)))(说明:这段代码是用来生成包含回归分析结果的报告中的一小部分。其中的代码变量已经在上下文中定义好了,因此 ChatGPT 只需翻译即可。) - Jerry T
1
默认情况下,geom_text将为数据框中的每一行绘制,导致模糊和性能问题,正如几个人所提到的。要解决这个问题,可以将传递给geom_text的参数包装在aes()中,并传递一个空数据框,例如:geom_text(aes(x = xpoint, y = ypoint, label = lm(df)), parse = TRUE, data.frame())。请参见https://dev59.com/PbLma4cB1Zd3GeqPWSdm。 - nelliott
显示剩余4条评论

255

我的ggpmisc程序包中的stat_poly_eq()函数可以基于线性模型拟合在图形上添加文本标签。(统计学中,stat_ma_eq()stat_quant_eq()函数同样支持主要轴回归和分位数回归。每个eq函数都有一个相匹配的line绘图函数。)

我已经在2023-03-30更新了这篇关于'ggpmisc'(>= 0.5.0)和'ggplot2'(>= 3.4.0)的答案。主要更改是使用'ggpmisc'(==0.5.0)中添加的use_label()函数来组装标签并映射它们。虽然aes()after_stat()的使用没有改变,但use_label()使映射和组装标签的编码更简单。

在示例中,我使用stat_poly_line()代替stat_smooth(),因为它具有与stat_poly_eq()相同的默认值,用于methodformula。在所有代码示例中,我省略了stat_poly_line()的附加参数,因为它们与添加标签的问题无关。
library(ggplot2)
library(ggpmisc)
#> Loading required package: ggpp
#> 
#> Attaching package: 'ggpp'
#> The following object is masked from 'package:ggplot2':
#> 
#>     annotate

# artificial data
df <- data.frame(x = c(1:100))
df$y <- 2 + 3 * df$x + rnorm(100, sd = 40)
df$yy <- 2 + 3 * df$x + 0.1 * df$x^2 + rnorm(100, sd = 40)

# using default formula, label and methods
ggplot(data = df, aes(x = x, y = y)) +
  stat_poly_line() +
  stat_poly_eq() +
  geom_point()


# assembling a single label with equation and R2
ggplot(data = df, aes(x = x, y = y)) +
  stat_poly_line() +
  stat_poly_eq(use_label(c("eq", "R2"))) +
  geom_point()


# assembling a single label with equation, adjusted R2, F-value, n, P-value
ggplot(data = df, aes(x = x, y = y)) +
  stat_poly_line() +
  stat_poly_eq(use_label(c("eq", "adj.R2", "f", "p", "n"))) +
  geom_point()


# assembling a single label with R2, its confidence interval, and n
ggplot(data = df, aes(x = x, y = y)) +
  stat_poly_line() +
  stat_poly_eq(use_label(c("R2", "R2.confint", "n"))) +
  geom_point()


# adding separate labels with equation and R2
ggplot(data = df, aes(x = x, y = y)) +
  stat_poly_line() +
  stat_poly_eq(use_label("eq")) +
  stat_poly_eq(label.y = 0.9) +
  geom_point()


# regression through the origin
ggplot(data = df, aes(x = x, y = y)) +
  stat_poly_line(formula = y ~ x + 0) +
  stat_poly_eq(use_label("eq"),
               formula = y ~ x + 0) +
  geom_point()


# fitting a polynomial
ggplot(data = df, aes(x = x, y = yy)) +
  stat_poly_line(formula = y ~ poly(x, 2, raw = TRUE)) +
  stat_poly_eq(formula = y ~ poly(x, 2, raw = TRUE), use_label("eq")) +
  geom_point()


# adding a hat as asked by @MYaseen208 and @elarry
ggplot(data = df, aes(x = x, y = y)) +
  stat_poly_line() +
  stat_poly_eq(eq.with.lhs = "italic(hat(y))~`=`~",
               use_label(c("eq", "R2"))) +
  geom_point()


# variable substitution as asked by @shabbychef
# same labels in equation and axes
ggplot(data = df, aes(x = x, y = y)) +
  stat_poly_line() +
  stat_poly_eq(eq.with.lhs = "italic(h)~`=`~",
               eq.x.rhs = "~italic(z)",
               use_label("eq")) +
  labs(x = expression(italic(z)), y = expression(italic(h))) +
  geom_point()


# grouping as asked by @helen.h
dfg <- data.frame(x = c(1:100))
dfg$y <- 20 * c(0, 1) + 3 * df$x + rnorm(100, sd = 40)
dfg$group <- factor(rep(c("A", "B"), 50))

ggplot(data = dfg, aes(x = x, y = y, colour = group)) +
  stat_poly_line() +
  stat_poly_eq(use_label(c("eq", "R2"))) +
  geom_point()


# A group label is available, for grouped data
ggplot(data = dfg, aes(x = x, y = y, linetype = group, grp.label = group)) +
  stat_poly_line() +
  stat_poly_eq(use_label(c("grp", "eq", "R2"))) +
  geom_point()


# use_label() makes it easier to create the mappings, but when more
# flexibility is needed like different separators at different positions,
# as shown here, aes() has to be used instead of use_label().
ggplot(data = dfg, aes(x = x, y = y, linetype = group, grp.label = group)) +
  stat_poly_line() +
  stat_poly_eq(aes(label = paste(after_stat(grp.label), "*\": \"*",
                                 after_stat(eq.label), "*\", \"*",
                                 after_stat(rr.label), sep = ""))) +
  geom_point()


# a single fit with grouped data as asked by @Herman
ggplot(data = dfg, aes(x = x, y = y)) +
  stat_poly_line() +
  stat_poly_eq(use_label(c("eq", "R2"))) +
  geom_point(aes(colour = group))


# facets
ggplot(data = dfg, aes(x = x, y = y)) +
  stat_poly_line() +
  stat_poly_eq(use_label(c("eq", "R2"))) +
  geom_point() +
  facet_wrap(~group)

使用reprex v2.0.2于2023年3月30日创建


4
需要注意的是,公式中的 xy 是指绘图层中的 xy 数据,而不一定是在构建 my.formula 时处于范围内的数据。因此,该公式应始终使用 x 和 y 变量? - shabbychef
3
很好的点子@elarry!这与R语言的parse()函数有关。通过反复试验,我发现aes(label = paste(..eq.label.., ..rr.label.., sep = "*plain(\",\")~"))可以完成任务。 - Pedro J. Aphalo
1
@PedroAphalo,在同一图中使用stat_poly_eq函数对不同组是否可行?我在我的aes()调用中指定了color=和linetype=,然后还调用了geom_smooth(method="rlm"),目前为每个组提供了一个回归线,我想打印出唯一的方程式。 - helen.h
1
通常情况下,回归分析中会优先选择R2,因此在stat_poly_eq()返回的数据中没有预定义的r.label。您可以使用来自“ggpmisc”包的stat_fit_glance(),它将R2作为数字值返回。请参阅帮助页面中的示例,并将stat(r.squared)替换为sqrt(stat(r.squared)) - Pedro J. Aphalo
1
@MacUser 现在已经测试过了:summary.fun = function(x) {x[["eq.label"]]} 可以正常工作,当然,您也可以在函数内部使用 <<-assign() 将方程保存到变量中。但是,在测试时我注意到,当使用除了默认值 output.type = "expression" 之外的其他选项时,eq.label 存在问题。这个问题现在已经在 GitHub 上的 ggpmisc 版本中得到解决。现在,帮助页面中也添加了使用 summary.fun = function(x) {x[["eq.label"]]} 的示例。 - Pedro J. Aphalo
显示剩余39条评论

110

我修改了stat_smooth和相关函数的几行代码,创建了一个新函数,增加了拟合方程和R平方值。这个新函数同样可以在分面图上使用!

library(devtools)
source_gist("524eade46135f6348140")
df = data.frame(x = c(1:100))
df$y = 2 + 5 * df$x + rnorm(100, sd = 40)
df$class = rep(1:2,50)
ggplot(data = df, aes(x = x, y = y, label=y)) +
  stat_smooth_func(geom="text",method="lm",hjust=0,parse=TRUE) +
  geom_smooth(method="lm",se=FALSE) +
  geom_point() + facet_wrap(~class)

输入图像描述

我使用了 @Ramnath 回答中的代码来格式化公式。 stat_smooth_func 函数并不是很健壮,但调整它应该不难。

https://gist.github.com/kdauria/524eade46135f6348140。如果出现错误,请尝试更新ggplot2


2
非常感谢。这个不仅适用于 facets,甚至适用于 groups。我发现它在分段回归中非常有用,例如 stat_smooth_func(mapping=aes(group=cut(x.val,c(-70,-20,0,20,50,130))),geom="text",method="lm",hjust=0,parse=TRUE),结合来自 https://dev59.com/qWIj5IYBdhLWcg3w8ZUF 的 EvaluateSmooths。 - Julian
1
@aelwan,请根据您的喜好更改以下行:https://gist.github.com/kdauria/524eade46135f6348140#file-ggplot_smooth_func-r-L104-L107。然后在您的脚本中“source”整个文件。 - kdauria
1
如果我在每个facet_wrap中有几个方程,并且在每个facet_wrap中有不同的y_values,那该怎么办?有什么建议如何修复方程的位置?我尝试了使用hjust、vjust和angle的几个选项,使用此示例https://www.dropbox.com/s/9lk9lug2nwgno2l/R2_facet_wrap.docx?dl=0,但我无法将所有方程式都带到每个facet_wrap的相同级别。 - shiny
4
@aelwan,方程式的位置是由这些代码行决定的:https://gist.github.com/kdauria/524eade46135f6348140#file-ggplot_smooth_func-r-L110-L111。我在Gist中将“xpos”和“ypos”作为函数的参数进行了设置。因此,如果您想让所有的方程式重叠在一起,只需设置“xpos”和“ypos”。否则,“xpos”和“ypos”将从数据中计算得出。如果您想要更高级的效果,向函数内添加一些逻辑不应该太难。例如,也许您可以编写一个函数来确定图表上哪个部分有最多的空白区域,并将函数放置在那里。 - kdauria
6
使用source_gist函数时遇到错误:Error in r_files[[which]] : invalid subscript type 'closure'。请参考此帖子以获取解决方案:https://dev59.com/OVoT5IYBdhLWcg3wngu1。 - Matifou
显示剩余12条评论

79

我已修改了Ramnath的帖子,以使其更通用,因此它接受线性模型作为参数而不是数据框,并更适当地显示负值。

lm_eqn = function(m) {

  l <- list(a = format(coef(m)[1], digits = 2),
      b = format(abs(coef(m)[2]), digits = 2),
      r2 = format(summary(m)$r.squared, digits = 3));

  if (coef(m)[2] >= 0)  {
    eq <- substitute(italic(y) == a + b %.% italic(x)*","~~italic(r)^2~"="~r2,l)
  } else {
    eq <- substitute(italic(y) == a - b %.% italic(x)*","~~italic(r)^2~"="~r2,l)    
  }

  as.character(as.expression(eq));                 
}

使用方式将更改为:

p1 = p + geom_text(aes(x = 25, y = 300, label = lm_eqn(lm(y ~ x, df))), parse = TRUE)

18
看起来不错!但我正在多个面板上绘制geom_points,其中基于面板变量的数据框有所不同。我该怎么做? - bshor
26
Jayden的解决方案效果很好,但字体看起来非常丑陋。我建议更改使用方法如下:p1 = p + annotate("text", x = 25, y = 300, label = lm_eqn(lm(y ~ x, df)), colour="black", size = 5, parse=TRUE) 编辑:这也解决了您在图例中可能遇到的任何字母显示问题。 - Jonas Raedle
1
@ Jonas,不知道为什么我得到了“无法将类“lm”强制转换为数据框”的错误。这个替代方案可以解决问题:df.labs <- data.frame(x = 25, y = 300, label = lm_eqn(df))p <- p + geom_text(data = df.labs, aes(x = x, y = y, label = label), parse = TRUE) - PatrickT
1
@PatrickT - 如果你使用Ramnath的解决方案调用lm_eqn(lm(...)),那么你会得到这个错误消息。你可能在尝试了那个解决方案后尝试了这个,但忘记确保你已经重新定义了lm_eqn - Hamy
@PatrickT:你能把你的回答单独写成一个答案吗?我很乐意投票支持! - JelenaČuklina

32

以下是最简单的代码,适用于每个人

注意:显示Pearson's Rho而不是R^2。

library(ggplot2)
library(ggpubr)

df <- data.frame(x = c(1:100)
df$y <- 2 + 3 * df$x + rnorm(100, sd = 40)
p <- ggplot(data = df, aes(x = x, y = y)) +
        geom_smooth(method = "lm", se=FALSE, color="black", formula = y ~ x) +
        geom_point()+
        stat_cor(label.y = 35)+ #this means at 35th unit in the y axis, the r squared and p value will be shown
        stat_regline_equation(label.y = 30) #this means at 30th unit regresion line equation will be shown

p

我的数据集的一个例子


与上述问题相同,在您的图中显示的是rho而不是R²! - matmar
4
你可以仅将R2添加到这里:stat_cor(aes(label = ..rr.label..)) - Matifou
我认为这是最简单的解决方案,对标签位置有最好的控制(我无法找到一种简单的方法来使用stat_poly_eq将R ^ 2放在方程式下面),并且可以与“stat_regline_equation()”结合使用以绘制回归方程。 - JJGabe
2
'ggpubr'似乎没有在积极维护,因为在GitHub上有许多未解决的问题。无论如何,在stat_regline_equation()stat_cor()中的许多代码都是从我的包'ggpmisc'中未经确认地复制而来的。它是从stat_poly_eq()中取出的,后者正在积极维护,并且自从被复制以来已经获得了几个新功能。示例代码只需要进行最小的编辑即可与'ggpmisc'配合使用。 - Pedro J. Aphalo
@PedroJ.Aphalo 尽管我同意您的观点,即如果从您的软件包中获取代码,则应该得到确认,但我仍然认为 stat_poly_eq() 更加繁琐。由于我无法轻松地将 label=..eq.label..label=..rr.label.. 分开放置在网格上并直观地放置它们,这意味着我将继续喜欢使用 stat_cor()stat_regline_equation()。这当然是我的个人意见,可能不被其他用户共享,但这些都是需要考虑的一些事情,因为您仍在积极更新 ggpmisc - JJGabe
显示剩余3条评论

21

使用 ggpubr

library(ggpubr)

# reproducible data
set.seed(1)
df <- data.frame(x = c(1:100))
df$y <- 2 + 3 * df$x + rnorm(100, sd = 40)

# By default showing Pearson R
ggscatter(df, x = "x", y = "y", add = "reg.line") +
  stat_cor(label.y = 300) +
  stat_regline_equation(label.y = 280)

输入图像描述

# Use R2 instead of R
ggscatter(df, x = "x", y = "y", add = "reg.line") +
  stat_cor(label.y = 300, 
           aes(label = paste(..rr.label.., ..p.label.., sep = "~`,`~"))) +
  stat_regline_equation(label.y = 280)

## compare R2 with accepted answer
# m <- lm(y ~ x, df)
# round(summary(m)$r.squared, 2)
# [1] 0.85

输入图片说明


你看过一种简洁的编程方式来指定 label.y 的数字吗? - Mark Neal
@MarkNeal 可以先获取 y 的最大值,然后乘以 0.8。label.y = max(df$y) * 0.8 - zx8754
1
@MarkNeal 说得好,或许可以在 GitHub 的 ggpubr 上提交问题作为功能请求。 - zx8754
1
自动定位问题已在此处提交 [https://github.com/kassambara/ggpubr/issues/247] - Mark Neal
1
@zx8754,您的图中显示了rho而不是R²,有没有简单的方法来显示R²? - matmar
显示剩余2条评论

17

我非常喜欢@Ramnath的解决方案。为了允许我们自定义回归公式(而不是将y和x固定为字面变量名称),并将p值添加到输出中(正如@Jerry T所评论的那样),以下是修改后的代码:

lm_eqn <- function(df, y, x){
    formula = as.formula(sprintf('%s ~ %s', y, x))
    m <- lm(formula, data=df);
    # formating the values into a summary string to print out
    # ~ give some space, but equal size and comma need to be quoted
    eq <- substitute(italic(target) == a + b %.% italic(input)*","~~italic(r)^2~"="~r2*","~~p~"="~italic(pvalue), 
         list(target = y,
              input = x,
              a = format(as.vector(coef(m)[1]), digits = 2), 
              b = format(as.vector(coef(m)[2]), digits = 2), 
             r2 = format(summary(m)$r.squared, digits = 3),
             # getting the pvalue is painful
             pvalue = format(summary(m)$coefficients[2,'Pr(>|t|)'], digits=1)
            )
          )
    as.character(as.expression(eq));                 
}

geom_point() +
  ggrepel::geom_text_repel(label=rownames(mtcars)) +
  geom_text(x=3,y=300,label=lm_eqn(mtcars, 'hp','wt'),color='red',parse=T) +
  geom_smooth(method='lm')

在这里输入图片描述 很遗憾,这在facet_wrap或facet_grid中不起作用。


非常整洁,我已经在这里引用了这里。澄清一下 - 在geom_point()之前,您的代码是否缺少ggplot(mtcars, aes(x = wt, y = mpg, group=cyl))+?一个半相关的问题 - 如果我们在ggplot的aes()中引用hpwt,那么我们能否获取它们以在调用lm_eqn时使用,这样我们只需要在一个地方编码?我知道我们可以在ggplot()调用之前设置xvar =“hp”,并在两个位置使用xvar来替换hp,但这感觉是不必要的。 - Mark Neal
真是一个非常好的解决方案!感谢分享! - Luis

5

另一个选项是使用dplyrbroom库创建自定义函数,用于生成方程式:

get_formula <- function(model) {
  
  broom::tidy(model)[, 1:2] %>%
    mutate(sign = ifelse(sign(estimate) == 1, ' + ', ' - ')) %>% #coeff signs
    mutate_if(is.numeric, ~ abs(round(., 2))) %>% #for improving formatting
    mutate(a = ifelse(term == '(Intercept)', paste0('y ~ ', estimate), paste0(sign, estimate, ' * ', term))) %>%
    summarise(formula = paste(a, collapse = '')) %>%
    as.character
  
}

lm(y ~ x, data = df) -> model
get_formula(model)
#"y ~ 6.22 + 3.16 * x"

scales::percent(summary(model)$r.squared, accuracy = 0.01) -> r_squared

现在我们需要将文本添加到图表中:
p + 
  geom_text(x = 20, y = 300,
            label = get_formula(model),
            color = 'red') +
  geom_text(x = 20, y = 285,
            label = r_squared,
            color = 'blue')

plot


4
这个答案中提供的公式样式启发,一个更通用的方法(适用于多个预测器+latex输出作为选项)可以是:
print_equation= function(model, latex= FALSE, ...){
    dots <- list(...)
    cc= model$coefficients
    var_sign= as.character(sign(cc[-1]))%>%gsub("1","",.)%>%gsub("-"," - ",.)
    var_sign[var_sign==""]= ' + '

    f_args_abs= f_args= dots
    f_args$x= cc
    f_args_abs$x= abs(cc)
    cc_= do.call(format, args= f_args)
    cc_abs= do.call(format, args= f_args_abs)
    pred_vars=
        cc_abs%>%
        paste(., x_vars, sep= star)%>%
        paste(var_sign,.)%>%paste(., collapse= "")

    if(latex){
        star= " \\cdot "
        y_var= strsplit(as.character(model$call$formula), "~")[[2]]%>%
            paste0("\\hat{",.,"_{i}}")
        x_vars= names(cc_)[-1]%>%paste0(.,"_{i}")
    }else{
        star= " * "
        y_var= strsplit(as.character(model$call$formula), "~")[[2]]        
        x_vars= names(cc_)[-1]
    }

    equ= paste(y_var,"=",cc_[1],pred_vars)
    if(latex){
        equ= paste0(equ," + \\hat{\\varepsilon_{i}} \\quad where \\quad \\varepsilon \\sim \\mathcal{N}(0,",
                    summary(MetamodelKdifEryth)$sigma,")")%>%paste0("$",.,"$")
    }
    cat(equ)
}
model参数需要一个lm对象,latex参数是一个布尔值用于请求简单字符或LaTeX格式的公式,...参数将其值传递给format函数。
我还添加了一个选项,以便将其输出为LaTeX,这样您就可以像这样在rmarkdown中使用此函数:

```{r echo=FALSE, results='asis'}
print_equation(model = lm_mod, latex = TRUE)
```

现在如何使用它:
df <- data.frame(x = c(1:100))
df$y <- 2 + 3 * df$x + rnorm(100, sd = 40)
df$z <- 8 + 3 * df$x + rnorm(100, sd = 40)
lm_mod= lm(y~x+z, data = df)

print_equation(model = lm_mod, latex = FALSE)

这段代码的输出结果为:y = 11.3382963933174 + 2.5893419 * x + 0.1002227 * z

如果我们要求一个LaTeX方程式,并将参数舍入为3个数字:

print_equation(model = lm_mod, latex = TRUE, digits= 3)

这会得到: LaTeX方程

2

与@zx8754和@kdauria的回答类似,只不过使用了ggplot2ggpubr。我更喜欢使用ggpubr,因为它不需要像这个问题的顶部答案那样使用自定义函数。

library(ggplot2)
library(ggpubr)

df <- data.frame(x = c(1:100))
df$y <- 2 + 3 * df$x + rnorm(100, sd = 40)

ggplot(data = df, aes(x = x, y = y)) +
  stat_smooth(method = "lm", se=FALSE, color="black", formula = y ~ x) +
  geom_point() +
  stat_cor(aes(label = paste(..rr.label..)), # adds R^2 value
           r.accuracy = 0.01,
           label.x = 0, label.y = 375, size = 4) +
  stat_regline_equation(aes(label = ..eq.label..), # adds equation to linear regression
                        label.x = 0, label.y = 400, size = 4)

这里插入图像描述

可以在上面的图中添加p值

ggplot(data = df, aes(x = x, y = y)) +
  stat_smooth(method = "lm", se=FALSE, color="black", formula = y ~ x) +
  geom_point() +
  stat_cor(aes(label = paste(..rr.label.., ..p.label.., sep = "~`,`~")), # adds R^2 and p-value
           r.accuracy = 0.01,
           p.accuracy = 0.001,
           label.x = 0, label.y = 375, size = 4) +
  stat_regline_equation(aes(label = ..eq.label..), # adds equation to linear regression
                        label.x = 0, label.y = 400, size = 4)

在此输入图片描述

如果您有多个组,则使用facet_wrap()也可以很好地运行。

df$group <- rep(1:2,50)

ggplot(data = df, aes(x = x, y = y)) +
  stat_smooth(method = "lm", se=FALSE, color="black", formula = y ~ x) +
  geom_point() +
  stat_cor(aes(label = paste(..rr.label.., ..p.label.., sep = "~`,`~")),
           r.accuracy = 0.01,
           p.accuracy = 0.001,
           label.x = 0, label.y = 375, size = 4) +
  stat_regline_equation(aes(label = ..eq.label..),
                        label.x = 0, label.y = 400, size = 4) +
  theme_bw() +
  facet_wrap(~group)

enter image description here


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接