尝试使用 ggplot 和方程标签绘制不同的线性回归模型
Trying to graph different linear regression models with ggplot and equation labels
这是我正在使用的数据集的输入:
structure(list(X = c(18, 19, 20, 17, 8, 15, 14, 16, 18, 14, 16,
13, 16, 17, 10, 18, 19, 25, 18, 13, 18, 16, 11, 17, 15, 18, 19,
16, 20, 17, 8, 18, 15, 14, 18, 14, 16, 13, 16), Y = c(15, 13,
14, 22, 2, 11, 15, 11, 20, 17, 20, 17, 20, 14, 21, 10, 13, 16,
12, 11, 13, 10, 4, 16, 18, 15, 10, 13, 14, 17, 2, 11, 15, 11,
20, 17, 14, 7, 16), Z = c(32, 42, 37, 34, 32, 39, 44, 49, 36,
31, 36, 37, 37, 45, 46, 48, 36, 42, 36, 25, 36, 39, 26, 32, 33,
38, 33, 44, 46, 34, 32, 39, 44, 49, 36, 31, 36, 37, 37)), class = "data.frame", row.names = c(NA,
-39L))
所以在我 运行 R 中的线性回归之前,我会使用这样一个简单的代码:
library(ggplot2)
library(ggpmisc)
ggplot(data = hw_data,
aes(x=X,
y=Y))+
geom_point()+
geom_smooth(method = lm)+
stat_poly_eq(formula = simple_model,
aes(label = paste(..eq.label.., ..rr.label..,
sep = "~~~~~~")))
这会给我一个带有这种等式标签的图表:
但是,我正在尝试 运行 多元线性回归和层次回归,但是当我尝试添加第三个变量时,我不完全确定如何 1) 得到第三个变量 (Z) 绘制为回归线,以及 2) 得到一个与图形上的模型相符的方程。我正在寻找的是这样的东西:
我需要绘制的两个模型是 (Y ~ X + Z) 和 (Y ~ X * Z)。到目前为止我想出的最好的是:
# One predictor model:
hw_regression_simple <- lm(Y ~ X,
data = hw_data)
# Two predictor model:
hw_regression_two_factors <- lm(Y ~ X + Z,
hw_data)
# Interaction model:
hw_regression_interaction <- lm(Y ~ X * Z,
hw_data)
# Comparison of models:
summary(hw_regression_simple)
summary(hw_regression_two_factors)
summary(hw_regression_interaction)
model <- Y ~ X * Z
ggplot(data = hw_data,
aes(x=X,
y=Y,
color=Z))+
geom_point()+
geom_smooth(method = lm)+
labs(title = "X, Y, and Z Interactions")+
stat_poly_eq()
这给了我这个带有 R 平方和散点图着色的图表,但除此之外没有提供我想要的那么多信息。我怎样才能解决这个问题,使它看起来更像我正在寻找的模型?
如果您在 X
和 Z
上对 Y
进行回归,并且它们都是数值变量(如您的示例中所示),那么简单的线性回归表示 2D plane in 3D space, not a line in 2D space.添加交互项意味着您的回归表示 3D space 中的曲面。尽管有一些方法可以做到这一点,但这可能很难用简单的图表来表示:您展示的吸烟/骑自行车示例中的彩色线条是在 Z 变量的各种(任意)值处穿过回归平面的切片,即显示此类模型的合理方式。
虽然 ggplot 有一些绘制简单模型的快捷方式,但我发现人们经常陷入困境,因为他们试图在 ggplot 中完成所有建模。当你有一个更复杂的模型要绘制时,最好的办法是使用正确的工具来确定你想要绘制的内容,然后使用 ggplot 绘制它。
例如,如果您为交互模型制作预测数据框:
model2 <- lm(Y ~ X * Z, data = hw_data)
predictions <- expand.grid(X = seq(min(hw_data$X), max(hw_data$X), length.out = 5),
Z = seq(min(hw_data$Z), max(hw_data$Z), length.out = 5))
predictions$Y <- predict(model2, newdata = predictions)
然后你可以非常简单地绘制你的交互模型:
ggplot(hw_data, aes(X, Y)) +
geom_point() +
geom_line(data = predictions, aes(color = factor(Z))) +
labs(color = "Z")
您可以轻松地从系数 table 中得出公式,并将其与 paste
粘贴在一起:
labs <- trimws(format(coef(model2), digits = 2))
form <- paste("Y =", labs[1], "+", labs[2], "* x +",
labs[3], "* Z + (", labs[4], " * X * Z)")
form
#> [1] "Y = -69.07 + 5.58 * x + 2.00 * Z + ( -0.13 * X * Z)"
可以使用 geom_text
或 annotation
将其作为注释添加到您的绘图中
更新
一个完整的解决方案,如果你只想让 Z 有 3 个级别,有效的“高”、“中”和“低”,你可以这样做:
library(ggplot2)
model2 <- lm(Y ~ X * Z, data = hw_data)
predictions <- expand.grid(X = quantile(hw_data$X, c(0, 0.5, 1)),
Z = quantile(hw_data$Z, c(0.1, 0.5, 0.9)))
predictions$Y <- predict(model2, newdata = predictions)
labs <- trimws(format(coef(model2), digits = 2))
form <- paste("Y =", labs[1], "+", labs[2], "* x +",
labs[3], "* Z + (", labs[4], " * X * Z)")
form <- paste(form, " R\u00B2 =",
format(summary(model2)$r.squared, digits = 2))
ggplot(hw_data, aes(X, Y)) +
geom_point() +
geom_line(data = predictions, aes(color = factor(Z))) +
geom_text(x = 15, y = 25, label = form, check_overlap = TRUE,
fontface = "italic") +
labs(color = "Z")
这是我正在使用的数据集的输入:
structure(list(X = c(18, 19, 20, 17, 8, 15, 14, 16, 18, 14, 16,
13, 16, 17, 10, 18, 19, 25, 18, 13, 18, 16, 11, 17, 15, 18, 19,
16, 20, 17, 8, 18, 15, 14, 18, 14, 16, 13, 16), Y = c(15, 13,
14, 22, 2, 11, 15, 11, 20, 17, 20, 17, 20, 14, 21, 10, 13, 16,
12, 11, 13, 10, 4, 16, 18, 15, 10, 13, 14, 17, 2, 11, 15, 11,
20, 17, 14, 7, 16), Z = c(32, 42, 37, 34, 32, 39, 44, 49, 36,
31, 36, 37, 37, 45, 46, 48, 36, 42, 36, 25, 36, 39, 26, 32, 33,
38, 33, 44, 46, 34, 32, 39, 44, 49, 36, 31, 36, 37, 37)), class = "data.frame", row.names = c(NA,
-39L))
所以在我 运行 R 中的线性回归之前,我会使用这样一个简单的代码:
library(ggplot2)
library(ggpmisc)
ggplot(data = hw_data,
aes(x=X,
y=Y))+
geom_point()+
geom_smooth(method = lm)+
stat_poly_eq(formula = simple_model,
aes(label = paste(..eq.label.., ..rr.label..,
sep = "~~~~~~")))
这会给我一个带有这种等式标签的图表:
但是,我正在尝试 运行 多元线性回归和层次回归,但是当我尝试添加第三个变量时,我不完全确定如何 1) 得到第三个变量 (Z) 绘制为回归线,以及 2) 得到一个与图形上的模型相符的方程。我正在寻找的是这样的东西:
我需要绘制的两个模型是 (Y ~ X + Z) 和 (Y ~ X * Z)。到目前为止我想出的最好的是:
# One predictor model:
hw_regression_simple <- lm(Y ~ X,
data = hw_data)
# Two predictor model:
hw_regression_two_factors <- lm(Y ~ X + Z,
hw_data)
# Interaction model:
hw_regression_interaction <- lm(Y ~ X * Z,
hw_data)
# Comparison of models:
summary(hw_regression_simple)
summary(hw_regression_two_factors)
summary(hw_regression_interaction)
model <- Y ~ X * Z
ggplot(data = hw_data,
aes(x=X,
y=Y,
color=Z))+
geom_point()+
geom_smooth(method = lm)+
labs(title = "X, Y, and Z Interactions")+
stat_poly_eq()
这给了我这个带有 R 平方和散点图着色的图表,但除此之外没有提供我想要的那么多信息。我怎样才能解决这个问题,使它看起来更像我正在寻找的模型?
如果您在 X
和 Z
上对 Y
进行回归,并且它们都是数值变量(如您的示例中所示),那么简单的线性回归表示 2D plane in 3D space, not a line in 2D space.添加交互项意味着您的回归表示 3D space 中的曲面。尽管有一些方法可以做到这一点,但这可能很难用简单的图表来表示:您展示的吸烟/骑自行车示例中的彩色线条是在 Z 变量的各种(任意)值处穿过回归平面的切片,即显示此类模型的合理方式。
虽然 ggplot 有一些绘制简单模型的快捷方式,但我发现人们经常陷入困境,因为他们试图在 ggplot 中完成所有建模。当你有一个更复杂的模型要绘制时,最好的办法是使用正确的工具来确定你想要绘制的内容,然后使用 ggplot 绘制它。
例如,如果您为交互模型制作预测数据框:
model2 <- lm(Y ~ X * Z, data = hw_data)
predictions <- expand.grid(X = seq(min(hw_data$X), max(hw_data$X), length.out = 5),
Z = seq(min(hw_data$Z), max(hw_data$Z), length.out = 5))
predictions$Y <- predict(model2, newdata = predictions)
然后你可以非常简单地绘制你的交互模型:
ggplot(hw_data, aes(X, Y)) +
geom_point() +
geom_line(data = predictions, aes(color = factor(Z))) +
labs(color = "Z")
您可以轻松地从系数 table 中得出公式,并将其与 paste
粘贴在一起:
labs <- trimws(format(coef(model2), digits = 2))
form <- paste("Y =", labs[1], "+", labs[2], "* x +",
labs[3], "* Z + (", labs[4], " * X * Z)")
form
#> [1] "Y = -69.07 + 5.58 * x + 2.00 * Z + ( -0.13 * X * Z)"
可以使用 geom_text
或 annotation
更新
一个完整的解决方案,如果你只想让 Z 有 3 个级别,有效的“高”、“中”和“低”,你可以这样做:
library(ggplot2)
model2 <- lm(Y ~ X * Z, data = hw_data)
predictions <- expand.grid(X = quantile(hw_data$X, c(0, 0.5, 1)),
Z = quantile(hw_data$Z, c(0.1, 0.5, 0.9)))
predictions$Y <- predict(model2, newdata = predictions)
labs <- trimws(format(coef(model2), digits = 2))
form <- paste("Y =", labs[1], "+", labs[2], "* x +",
labs[3], "* Z + (", labs[4], " * X * Z)")
form <- paste(form, " R\u00B2 =",
format(summary(model2)$r.squared, digits = 2))
ggplot(hw_data, aes(X, Y)) +
geom_point() +
geom_line(data = predictions, aes(color = factor(Z))) +
geom_text(x = 15, y = 25, label = form, check_overlap = TRUE,
fontface = "italic") +
labs(color = "Z")