【问题标题】:ggplot2: fit logarithmic stat_smooth to geom_ribbonggplot2:将对数 stat_smooth 拟合到 geom_ribbon
【发布时间】:2019-01-17 17:28:51
【问题描述】:

我正在尝试在ggplot2 中绘制拟合模型效果,作为effects 包返回的图的替代方案,我遇到了使用stat_smooth 拟合对数转换置信带的问题geom_ribbon。与geom_ribbon 的典型用途不同,我不需要计算波段——eff 对象给了我波段的限制——我只需要对它们进行对数转换。有很多关于如何为 geom_line(例如,R, ggplot2: Fit curve to scatter plot)执行此操作的信息,但到目前为止我还没有为 geom_ribbon 找到任何东西。

数据:

myEffs <- structure(list(TargetVowelDur = c(0.03, 0.4, 0.8, 1, 2), fit = c(-0.467790933985126, 
0.823476426481035, 1.16901542809292, 1.28025414059112, 1.625793142203
), se = c(0.087385175843338, 0.0895697786138634, 0.0922444075008412, 
0.0932736493340376, 0.0969532573361368), lower = c(-0.639066303684154, 
0.647919224725754, 0.98821594070963, 1.09743733420847, 1.43576428623844
), upper = c(-0.296515564286098, 0.999033628236315, 1.34981491547621, 
1.46307094697376, 1.81582199816757)), class = "data.frame", row.names = c(NA, 
-5L), transformation = function (eta) 
eta, .Names = c("TargetVowelDur", "fit", "se", "lower", "upper"
))

按原样传递geom_line 会产生4 个连接线段,而不是对数曲线,因此标准解决方案是添加stat_smooth

library(ggplot2)
p1 <- ggplot(myEffs, aes(x=TargetVowelDur, y=fit)) +
  geom_line(stat="smooth", method="lm", formula=y~log(x))
p1

一切都好。按照同样的逻辑,我们应该可以将stat_smooth 添加到geom_ribbon,但这样做会使情节保持不变

p2 <- p1 + 
  geom_ribbon(aes(ymin=lower, ymax=upper), stat="smooth", method="lm", formula=y~log(x))
p2

如果我们窥探p2 的构建,我们会发现geom_ribbonyminymax 是相同的,尽管upperlower 列是不相同的:

> print(lapply(ggplot_build(p2)$data, head))
[[1]]
           x           y        ymin        ymax           se PANEL group colour size linetype alpha
1 0.03000000 -0.46779093 -0.46779093 -0.46779093 2.568169e-15     1    -1  black  0.5        1    NA
2 0.05493671 -0.16620173 -0.16620173 -0.16620173 2.136541e-15     1    -1  black  0.5        1    NA
3 0.07987342  0.02037031  0.02037031  0.02037031 1.887702e-15     1    -1  black  0.5        1    NA
4 0.10481013  0.15581841  0.15581841  0.15581841 1.720023e-15     1    -1  black  0.5        1    NA
5 0.12974684  0.26221720  0.26221720  0.26221720 1.598524e-15     1    -1  black  0.5        1    NA
6 0.15468354  0.34985293  0.34985293  0.34985293 1.506906e-15     1    -1  black  0.5        1    NA

[[2]]
           x           y        ymin        ymax           se PANEL group colour   fill size linetype alpha
1 0.03000000 -0.46779093 -0.46779093 -0.46779093 2.568169e-15     1    -1     NA grey20  0.5        1    NA
2 0.05493671 -0.16620173 -0.16620173 -0.16620173 2.136541e-15     1    -1     NA grey20  0.5        1    NA
3 0.07987342  0.02037031  0.02037031  0.02037031 1.887702e-15     1    -1     NA grey20  0.5        1    NA
4 0.10481013  0.15581841  0.15581841  0.15581841 1.720023e-15     1    -1     NA grey20  0.5        1    NA
5 0.12974684  0.26221720  0.26221720  0.26221720 1.598524e-15     1    -1     NA grey20  0.5        1    NA
6 0.15468354  0.34985293  0.34985293  0.34985293 1.506906e-15     1    -1     NA grey20  0.5        1    NA

> myEffs$upper - myEffs$lower
[1] 0.3425507 0.3511144 0.3615990 0.3656336 0.3800577

如何让stat_smoothgeom_ribbon 一起玩得开心?

【问题讨论】:

  • 为什么不在 c(0.03, 2) 之间采样更多点并获得拟合值和 CI?使用smooth 获得的值可能与您从模型中获得的不同。
  • 我同意@mt1022 的观点,即解决方案是以更精细的x 变量分辨率获得预测值。例如,您可以将您的 x 设为 seq(.03, 2, by = .1) 进行预测。那么一旦你得到y和CI的预测值,你就可以直接使用geom_line()geom_ribbon()。如果事情仍然不够顺利,请在seq() 中使用较小的by
  • 也就是说,在预测点本身上使用geom_line()geom_ribbon() 而不是平滑。我喜欢! @ mt1022,你介意把这个写下来作为答案吗?我将对其进行编辑以提供数据并接受它作为最佳答案。

标签: r ggplot2


【解决方案1】:

我的解决方案是绘制三条线(数据,上和下),然后使用“上”和“下”线的数据来创建灰色区域;丝带。

library(ggplot2)
g1 <- ggplot(myEffs) + 
  geom_line(aes(x = TargetVowelDur, y = fit), stat = "smooth", method = "lm", formula=y~log(x)) + 
  geom_line(aes(x = TargetVowelDur, y = upper), color = "red", stat = "smooth", method = "lm", formula=y~log(x)) + 
  geom_line(aes(x = TargetVowelDur, y = lower), color = "blue", stat = "smooth", method = "lm", formula=y~log(x))

g1

# build plot object for rendering 
gg1 <- ggplot_build(g1)

# extract data from the upper and lower lines
df2 <- data.frame(x = gg1$data[[1]]$x,
                  ymin = gg1$data[[2]]$y,
                  ymax = gg1$data[[3]]$y) 

# use the lm data to add the ribbon to the plot 
g1 +  geom_ribbon(data = df2, aes(x = x, ymin = ymin, ymax = ymax), fill = "grey", alpha = 0.4)

基于@Henrik 在this post 中的回答

【讨论】:

    猜你喜欢
    • 2021-09-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-14
    • 1970-01-01
    • 2016-06-26
    • 1970-01-01
    相关资源
    最近更新 更多