在 ggplot2 中创建平滑线和置信区间形成 lmer 模型的新手问题
Newbie problems with creating smooth lines and confidence intervals form lmer model in ggplot2
对不起,这是一个愚蠢的简单问题,但我已经尝试了我在网上找到的所有解决方案,但都无济于事。这也是我第一次 post 在这里,我试图遵循格式方面的规则。可笑的是,我已经完全达到了我想要的效果,将绘图保存为 png,然后当我几周后返回代码时它不起作用,现在我无法复制我拥有的东西。
我试着在这里给出一些示例数据(从这个网站借用一些虚构的数据——希望没问题)。
tempEf <- data.frame(
N = rep(c("1", "2","1", "2","1", "2","1"), each=5, times=11),
Myc = rep(c("1", "2", "3", "4", "5"), each=1, times=77),
TRTYEAR = runif(385, 1, 15),
site = rep(c(1:77), each=5, times=1),#77 sites
Asp = runif(385, 1, 5)
)
# Make up some response data
tempEf$r <- 2*tempEf$TRTYEAR +
-8*as.numeric(tempEf$Myc=="1") +
4*as.numeric(tempEf$N=="1") +
0.1*tempEf$TRTYEAR * as.numeric(tempEf$N=="1") +
0.2*tempEf$TRTYEAR*as.numeric(tempEf$Myc=="1") +
-11*as.numeric(tempEf$Myc=="1")*as.numeric(tempEf$N=="1")+
0.5*tempEf$TRTYEAR*as.numeric(tempEf$Myc=="1")*as.numeric(tempEf$N=="1")+
as.numeric(tempEf$site) + #Random intercepts; intercepts will increase by 1
tempEf$TRTYEAR/10*rnorm(385, mean=0, sd=2) #Add some noise
#fit model
library(lme4)
model <- lmer(r ~ Myc * N + TRTYEAR + Asp + (1|site), data=tempEf)
tempEf$fit <- predict(model) #Add model fits to dataframe
我的目标是:
根据 lmer 模型计算拟合值和 95% 置信区间
根据我的因变量 ("r") 分别绘制“Myc”的 2 个水平的拟合值 ("fit"),根据 Myc 着色。出于此图的目的,我想忽略 N 和 Asp(在我的真实数据中,这些是控制变量,在模型中很重要但不重要)
将我的 95% 置信区间添加到这 2 行
这一切看似简单,其实大错特错!
我在这里获得了我的拟合值和 95% CI,这给了我拟合值、upr 和 lwr:
predicted_EF<-predictInterval(model, tempEf)
然后我将它们添加到我的原始数据框中:
tempEf<-cbind(tempEf,predicted_EF)
然后我这样做:
ggplot(tempEf,aes(TRTYEAR, r, group=Myc, col=Myc )) +
geom_line(aes(y=fit, lty=Myc), size=0.8) +
geom_point(alpha = 0.3) +
theme_bw()
这给了我锯齿状的线条,如下所示:
crappy graph
我可以使用 geom_smooth 而不是 geom_line,它给出了平滑的线条,但我相信这是将线条拟合到原始数据,而不是模型拟合值?我还可以使用 geom_abline 为 Myc 的每个级别拟合单独的回归线(使用拟合变量),但也不确定这是否正确。
ggplot(tempEf,aes(TRTYEAR, r, group=Myc, col=Myc, fill = Myc)) +
geom_smooth(method="lm",se = FALSE)+
geom_point(alpha = 0.3)+
theme_bw()
然后尝试使用我的 upr 和 lwr 变量添加 95% 的置信区间导致锯齿状的置信带:
ggplot(tempEf,aes(TRTYEAR, r, group=Myc, col=Myc, fill = Myc)) +
geom_smooth(method="lm",se = FALSE)+
geom_point(alpha = 0.3) +
geom_ribbon(alpha=0.1,
aes(ymin=lwr,ymax=upr,fill = Myc, colour = NA))+
theme_bw()
如何获得具有平滑置信区间的平滑线?我做错了什么(很多,我敢肯定!)。
感谢您的帮助。
我认为这是一个 "classical" 效果图(或估计的边际均值)任务。您可以使用 ggeffects-package 轻松完成此操作,网站上有大量示例。
根据您的数据,您只需调用 ggpredict(model, c("TRTYEAR", "Myc"))
:
library(ggeffects)
pred <- ggpredict(model, c("TRTYEAR", "Myc"))
pred
#>
#> # Predicted values of r
#> # x = TRTYEAR
#>
#> # Myc = AM
#> x predicted std.error conf.low conf.high
#> 0 0.797 0.737 -0.647 2.241
#> 2 5.361 0.727 3.936 6.786
#> 6 14.489 0.716 13.085 15.892
#> 8 19.052 0.715 17.652 20.453
#> 10 23.616 0.716 22.213 25.020
#> 16 37.308 0.737 35.863 38.752
#>
#> # Myc = ECM
#> x predicted std.error conf.low conf.high
#> 0 -5.575 0.737 -7.019 -4.130
#> 2 -1.011 0.727 -2.436 0.415
#> 6 8.117 0.716 6.713 9.520
#> 8 12.681 0.715 11.280 14.081
#> 10 17.244 0.716 15.841 18.648
#> 16 30.936 0.737 29.492 32.380
#>
#> Adjusted for:
#> * N = Nhigh
#> * Asp = 2.99
#> * site = 0 (population-level)
plot(pred)
#> Loading required namespace: ggplot2
plot(pred, add.data = TRUE)
由 reprex package (v0.3.0)
创建于 2019-12-11
ggeffects
包看起来超级棒,非常值得一试。为了回答您关于为 Myc 的每个级别分别放置多行的问题,ggplot(aes(group = ))
调用中的 interaction
函数始终是快速执行此操作的便捷工具。在您的例子中,您包含了四个分类变量,其中一个是按颜色编码的。将其他三个拆分为每个(在每个子组下)给出直线和色带:
ggplot(tempEf, aes(TRTYEAR, r, group = interaction(site, N, Myc), col=Myc, fill = Myc)) +
geom_point(alpha = 0.3) +
geom_line(aes(y = fit)) +
geom_ribbon(aes(ymin = lwr, ymax = upr), alpha = 0.1, colour = NA)
给出一组代表每个 Myc
x site
x N
分组的线条和色带。我认为根据您的要求,它是您想要的其他输出(来自 ggeffects
),但万一这仍然是一个有用的工具:
对不起,这是一个愚蠢的简单问题,但我已经尝试了我在网上找到的所有解决方案,但都无济于事。这也是我第一次 post 在这里,我试图遵循格式方面的规则。可笑的是,我已经完全达到了我想要的效果,将绘图保存为 png,然后当我几周后返回代码时它不起作用,现在我无法复制我拥有的东西。
我试着在这里给出一些示例数据(从这个网站借用一些虚构的数据——希望没问题)。
tempEf <- data.frame(
N = rep(c("1", "2","1", "2","1", "2","1"), each=5, times=11),
Myc = rep(c("1", "2", "3", "4", "5"), each=1, times=77),
TRTYEAR = runif(385, 1, 15),
site = rep(c(1:77), each=5, times=1),#77 sites
Asp = runif(385, 1, 5)
)
# Make up some response data
tempEf$r <- 2*tempEf$TRTYEAR +
-8*as.numeric(tempEf$Myc=="1") +
4*as.numeric(tempEf$N=="1") +
0.1*tempEf$TRTYEAR * as.numeric(tempEf$N=="1") +
0.2*tempEf$TRTYEAR*as.numeric(tempEf$Myc=="1") +
-11*as.numeric(tempEf$Myc=="1")*as.numeric(tempEf$N=="1")+
0.5*tempEf$TRTYEAR*as.numeric(tempEf$Myc=="1")*as.numeric(tempEf$N=="1")+
as.numeric(tempEf$site) + #Random intercepts; intercepts will increase by 1
tempEf$TRTYEAR/10*rnorm(385, mean=0, sd=2) #Add some noise
#fit model
library(lme4)
model <- lmer(r ~ Myc * N + TRTYEAR + Asp + (1|site), data=tempEf)
tempEf$fit <- predict(model) #Add model fits to dataframe
我的目标是:
根据 lmer 模型计算拟合值和 95% 置信区间
根据我的因变量 ("r") 分别绘制“Myc”的 2 个水平的拟合值 ("fit"),根据 Myc 着色。出于此图的目的,我想忽略 N 和 Asp(在我的真实数据中,这些是控制变量,在模型中很重要但不重要)
将我的 95% 置信区间添加到这 2 行
这一切看似简单,其实大错特错!
我在这里获得了我的拟合值和 95% CI,这给了我拟合值、upr 和 lwr:
predicted_EF<-predictInterval(model, tempEf)
然后我将它们添加到我的原始数据框中:
tempEf<-cbind(tempEf,predicted_EF)
然后我这样做:
ggplot(tempEf,aes(TRTYEAR, r, group=Myc, col=Myc )) +
geom_line(aes(y=fit, lty=Myc), size=0.8) +
geom_point(alpha = 0.3) +
theme_bw()
这给了我锯齿状的线条,如下所示: crappy graph
我可以使用 geom_smooth 而不是 geom_line,它给出了平滑的线条,但我相信这是将线条拟合到原始数据,而不是模型拟合值?我还可以使用 geom_abline 为 Myc 的每个级别拟合单独的回归线(使用拟合变量),但也不确定这是否正确。
ggplot(tempEf,aes(TRTYEAR, r, group=Myc, col=Myc, fill = Myc)) +
geom_smooth(method="lm",se = FALSE)+
geom_point(alpha = 0.3)+
theme_bw()
然后尝试使用我的 upr 和 lwr 变量添加 95% 的置信区间导致锯齿状的置信带:
ggplot(tempEf,aes(TRTYEAR, r, group=Myc, col=Myc, fill = Myc)) +
geom_smooth(method="lm",se = FALSE)+
geom_point(alpha = 0.3) +
geom_ribbon(alpha=0.1,
aes(ymin=lwr,ymax=upr,fill = Myc, colour = NA))+
theme_bw()
如何获得具有平滑置信区间的平滑线?我做错了什么(很多,我敢肯定!)。
感谢您的帮助。
我认为这是一个 "classical" 效果图(或估计的边际均值)任务。您可以使用 ggeffects-package 轻松完成此操作,网站上有大量示例。
根据您的数据,您只需调用 ggpredict(model, c("TRTYEAR", "Myc"))
:
library(ggeffects)
pred <- ggpredict(model, c("TRTYEAR", "Myc"))
pred
#>
#> # Predicted values of r
#> # x = TRTYEAR
#>
#> # Myc = AM
#> x predicted std.error conf.low conf.high
#> 0 0.797 0.737 -0.647 2.241
#> 2 5.361 0.727 3.936 6.786
#> 6 14.489 0.716 13.085 15.892
#> 8 19.052 0.715 17.652 20.453
#> 10 23.616 0.716 22.213 25.020
#> 16 37.308 0.737 35.863 38.752
#>
#> # Myc = ECM
#> x predicted std.error conf.low conf.high
#> 0 -5.575 0.737 -7.019 -4.130
#> 2 -1.011 0.727 -2.436 0.415
#> 6 8.117 0.716 6.713 9.520
#> 8 12.681 0.715 11.280 14.081
#> 10 17.244 0.716 15.841 18.648
#> 16 30.936 0.737 29.492 32.380
#>
#> Adjusted for:
#> * N = Nhigh
#> * Asp = 2.99
#> * site = 0 (population-level)
plot(pred)
#> Loading required namespace: ggplot2
plot(pred, add.data = TRUE)
由 reprex package (v0.3.0)
创建于 2019-12-11ggeffects
包看起来超级棒,非常值得一试。为了回答您关于为 Myc 的每个级别分别放置多行的问题,ggplot(aes(group = ))
调用中的 interaction
函数始终是快速执行此操作的便捷工具。在您的例子中,您包含了四个分类变量,其中一个是按颜色编码的。将其他三个拆分为每个(在每个子组下)给出直线和色带:
ggplot(tempEf, aes(TRTYEAR, r, group = interaction(site, N, Myc), col=Myc, fill = Myc)) +
geom_point(alpha = 0.3) +
geom_line(aes(y = fit)) +
geom_ribbon(aes(ymin = lwr, ymax = upr), alpha = 0.1, colour = NA)
给出一组代表每个 Myc
x site
x N
分组的线条和色带。我认为根据您的要求,它是您想要的其他输出(来自 ggeffects
),但万一这仍然是一个有用的工具: