使用替代绘制方程并在图中的单独线上进行r平方

时间:2014-11-19 19:31:24

标签: r plot ggplot2 regression substitution

关于包含线性回归方程和r平方的图的注释,有很多关于SO的问题和答案。许多是此question代码的版本,它注释了ggplot2图。我希望将这些回归术语作为单独的行包含在图中。而不是:

y = b + mx, r2 = 0.xxx 

如下图所示,我更喜欢:

y = b + mx 
r2 = 0.xxx

有没有办法使用substitute来制作换行符?我试图插入\n"\n"而不是",",但这些都没有成功。如果没有,是否有其他类似的方法来产生这样的结果?不可否认,我在确定下面替代代码所使用的语法方面基本上没有成功。 ~似乎是插入一个空格,我不知道*做了什么,等等。

# https://stackoverflow.com/q/7549694/1670053
p <- ggplot(data = cars, aes(x = speed, y = dist)) +
  geom_smooth(method =lm, se=F) + geom_point()

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 + annotate("text", x = 7.5, y = 100, label = lm_eqn(lm(dist ~ speed, cars)), 
                  colour="black", size = 5, parse=TRUE)

plot from example code produced using ggplot2 and the cars dataset

1 个答案:

答案 0 :(得分:1)

如果使用BondedDust建议的plotmath引擎有问题,我猜以下可能是一个解决方法。它使用两个标签函数:一个用于等式,一个用于r2。

p <- ggplot(data = cars, aes(x = speed, y = dist)) +
  geom_smooth(method =lm, se=F) + geom_point()

# lm equation
lm_eqn = function(m) {
  l <- list(a = format(coef(m)[1], digits = 2),
            b = format(abs(coef(m)[2]), digits = 2));
  if (coef(m)[2] >= 0)  {
    eq <- substitute(italic(y) == a + b %.% italic(x),l)
  } else {
    eq <- substitute(italic(y) == a - b %.% italic(x),l)    
  }
  as.character(as.expression(eq));                 
}

# r2
lm_eqn2 = function(m) {
  l <- list(r2 = format(summary(m)$r.squared, digits = 3));
  eq <- substitute(italic(r)^2~"="~r2,l)
  as.character(as.expression(eq));                 
}

p1 <- p + annotate("text", x = 7.1, y = 100, label = lm_eqn(lm(dist ~ speed, cars)), 
                  colour="black", size = 5, parse=TRUE) 
p2 <- p1 + annotate("text", x = 6.5, y = 90, label = lm_eqn2(lm(dist ~ speed, cars)), 
                    colour="black", size = 5, parse=TRUE) 

然而,为了使两条线左对齐,需要一些试验和错误。这个解决方案可能不仅仅是在没有函数的情况下注释文本的优势。

plot produced by r code

此代码效果稍好,但您仍需要将annotate中的y值调整为数据集。

p1 <- p + annotate("text", x=min(cars$speed), y=max(cars$dist), 
                   label = lm_eqn(lm(dist ~ speed, cars)), 
                   parse=T, hjust = 0, vjust = 1) + 
                   annotate("text", x = min(cars$speed), y = (max(cars$dist)-10), 
                   label = lm_eqn2(lm(dist ~ speed, cars)), 
                   parse=T, hjust = 0)

ggplot2 with annotated text using max and min value r2

我也尝试使用Inf / -Inf设置x和y值,但事情并不像你想要的那样排成一行。需要一些试验和错误才能让两行文本都与x边缘对齐。

p1 <- p + annotate("text", x=-Inf, y=Inf, 
                   label = lm_eqn(lm(dist ~ speed, cars)), 
                   parse=T, hjust = 0, vjust = 1) + 
  annotate("text", x = -Inf, y = Inf, 
           label = lm_eqn2(lm(dist ~ speed, cars)), 
           parse=T, hjust = 0, vjust=2)

ggplot2 plot annotated using Inf for x and y values