2012-08-14 61 views
23

我绘制了以下数据并添加了一个黄土平滑器。我想添加一个三阶多项式及其方程(包括残差)到图中。有什么建议?在r中添加三阶多项式及其方程到ggplot

set.seed(1410) 
dsmall<-diamonds[sample(nrow(diamonds), 100), ] 
df<-data.frame("x"=dsmall$carat, "y"=dsmall$price) 

p <-ggplot(df, aes(x, y)) 
p <- p + geom_point(alpha=2/10, shape=21, fill="blue", colour="black", size=5) 

#Add a loess smoother 
p<- p + geom_smooth(method="loess",se=TRUE) 

enter image description here

我如何添加一个3阶多项式?我曾尝试过:

p<- p + geom_smooth(method="lm", se=TRUE, fill=NA,formula=lm(y ~ poly(x, 3, raw=TRUE)),colour="red") 

最后如何将三阶多项式方程和残差加到图上? 我曾尝试:

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


data.label <- data.frame(x = 1.5,y = 10000,label = c(lm_eqn(df))) 


p<- p + geom_text(data=data.label,aes(x = x, y = y,label =label), size=8,family="Times",face="italic",parse = TRUE) 

回答

33

第1部分:以适应多项式,使用参数:

  • method=lm - 你这样做是正确
  • formula=y ~ poly(x, 3, raw=TRUE) - 即不要在呼叫这个包裹到lm

代码:

p + stat_smooth(method="lm", se=TRUE, fill=NA, 
       formula=y ~ poly(x, 3, raw=TRUE),colour="red") 

enter image description here


第2部分:添加方程式:

  • 修改你的函数lm_eqn()正确指定数据源lm - 你在错误的地方
  • 有一个右括号
  • 使用annotate()来定位标签,而不是geom_text

代码:

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


p + annotate("text", x=0.5, y=15000, label=lm_eqn(df), hjust=0, size=8, 
      family="Times", face="italic", parse=TRUE) 

enter image description here

+0

谢谢!这很清楚。 – Elizabeth 2012-08-14 14:37:06

6

答案1,是一个良好的开端,但它不是一个3阶多项式为要求,并能妥善处理不能与参数估计负值。最简单的就是使用包polynom。我将展示一个没有定义函数的版本,因为在这种情况下,应该使用一个ggplotstat_

下面我将展示如何生成要用作任何度数多项式的解析标签的文本。我使用signif()而不是format(),因为这对于参数估计更有用。另请注意,face不再需要。使用family = "Times"不是便携式的,使用"serif"可以实现同样的效果。所有的辛苦工作都由as.character.polynomial()完成!

library(polynom) 
library(ggplot2) 

set.seed(1410) 
dsmall <- diamonds[sample(nrow(diamonds), 100), ] 
df <- data.frame("x"=dsmall$carat, "y"=dsmall$price) 

my.formula <- y ~ poly(x, 3, raw = TRUE) 
p <- ggplot(df, aes(x, y)) 
p <- p + geom_point(alpha=2/10, shape=21, fill="blue", colour="black", size=5) 
p <- p + geom_smooth(method = "lm", se = FALSE, 
        formula = my.formula, 
        colour = "red") 

m <- lm(my.formula, df) 
my.eq <- as.character(signif(as.polynomial(coef(m)), 3)) 
label.text <- paste(gsub("x", "~italic(x)", my.eq, fixed = TRUE), 
       paste("italic(R)^2", 
        format(summary(m)$r.squared, digits = 2), 
        sep = "~`=`~"), 
        sep = "~~~~") 

p + annotate(geom = "text", x = 0.2, y = 15000, label = label.text, 
      family = "serif", hjust = 0, parse = TRUE, size = 4) 

enter image description here

最后请注意:方差与平均值增加,所以使用lm()和3阶多项式模型可能是不适合这些数据的分析,最好的办法。

+0

我发现有一个[ggplot2在这个问题上的常见问题](http://stackoverflow.com/questions/7549694/ggplot2-adding-regression-line-equation-and-r2-on-graph)。但是,我的答案中的方法是不同的。 – 2016-01-09 23:22:07