【问题标题】:Adding a 3rd order polynomial and its equation to a ggplot in r将三阶多项式及其方程添加到 r 中的 ggplot
【发布时间】:2012-08-14 09:21:18
【问题描述】:

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

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)

如何添加三阶多项式?我试过了:

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)

【问题讨论】:

    标签: r ggplot2


    【解决方案1】:

    第 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")
    


    第 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)
    

    【讨论】:

    • lm_eqn 函数用于线性回归,不适用于三次多项式
    • 让我大吃一惊的一件事 - formula 需要引用 yx 而不是 data.frame 中的变量名。令人困惑的是,在 OP 的示例中,变量名称恰好是 xy
    【解决方案2】:

    答案 1,是一个好的开始,但它不是所要求的 3 次多项式,并且不能正确处理参数估计的负值。最简单的是使用包polynom。我将展示一个没有定义函数的版本,因为在这种情况下,真的应该使用 ggplot stat_

    下面我将展示如何生成文本以用作任何次数多项式的解析标签。我使用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)
    

    最后一点:方差随均值的增加而增加,因此使用 lm() 和 3 次多项式模型可能不是分析这些数据的最佳方法。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-02
    相关资源
    最近更新 更多