最近,我正在比较两个统计练习,发现 R 中相同输入的不同输出可能是 R 的无意行为,对吗?
model1 <- lm(rent ~ area + bath, data = rent99)
coefficients1 <- coef(model1)
# Using a matrix without an intercept column
X <- cbind(rent99$area, rent99$bath)
model2 <- lm(rent99$rent ~ X[, 1] + X[, 2])
coefficients2 <- coef(model2)
# Both coefficients1 and coefficients2 should be identical
coefficients1
coefficients2
输出:
(Intercept) area bath1
144.149195 4.587025 100.661413
(Intercept) X[, 1] X[, 2]
43.487782 4.587025 100.661413
我假设系数相同,因为输入数据是相同的
bath
是因子变量。
让我们重现一下:
set.seed(42)
x <- sample(0:1, 100, TRUE)
DF <- data.frame(x = factor(x),
y = 0.1 + 5 * x + rnorm(100))
coef(lm(y ~ x, data = DF))
#(Intercept) x1
# 0.03815139 5.06531032
coef(lm(DF$y ~ cbind(DF$x)))
#(Intercept) cbind(DF$x)
#-5.027159 5.065310
问题是你使用了
cbind
。它生成一个矩阵,而矩阵只能容纳一种数据类型,并且不能容纳 S3 对象(例如因子)。
因此,
cbind
在您的示例中的作用类似于as.numeric
:
as.numeric(DF$x)
# [1] 1 1 1 1 2 2 2 2 1 2 1 2 1 2 1 1 2 2 2 2 1 1 1 1 1 2 1 1 1 1 2 2 2 2 1 2 1 2 2 2 1 1 2 2 2 2 2 2 2 1 2 1 2 2 2 2 1 2 1 1 1 2 2 2 2 2 2 1 2 1 2 1 2 2 2
# [76] 2 1 1 1 1 2 1 2 1 1 2 2 1 1 1 1 2 1 2 2 2 1 2 2 2
如您所见,它返回因子变量的内部整数。基本上,您将该变量从 0/1 重新编码为 1/2。这就是为什么第二个截距是
144.149195 - 1 * 100.661413
。