我正在尝试在数据的一个子集上运行lm(),但遇到了问题。
dt = data.table(y = rnorm(100), x1 = rnorm(100), x2 = rnorm(100), x3 = as.factor(c(rep('men',50), rep('women',50)))) # sample data
lm( y ~ ., dt) # Use all x: Works
lm( y ~ ., dt[x3 == 'men']) # Use all x, limit to men: doesn't work (as expected)
上述方法不可行,因为数据集只包含男性,我们无法将性别变量x3包含在模型中。但是...
lm( y ~ . -x3, dt[x3 == 'men']) # Exclude x3, limit to men: STILL doesn't work
lm( y ~ x1 + x2, dt[x3 == 'men']) # Exclude x3, with different notation: works great
这是公式中“减号”符号的问题吗?请给予建议。注意:我当然可以用其他方式完成;例如,在将变量放入lm()之前,我可以排除它们。但我正在教授这个知识点,我不想让学生感到困惑,因为我已经告诉他们他们可以使用公式中的减号符号来排除变量。
model.matrix(y ~ . - x3, data = dt[x3 == "men"])
和model.matrix(y ~ x1 + x2, data = dt[x3 == "men"])
都能运作(lm
在内部调用model.matrix
)。两种模型矩阵唯一的区别是一个包含"contrasts"
属性(仍然包含x3
),并在后续的lm
过程中被使用,可能导致您看到的错误。因此,我认为问题与model.matrix
在删除项时创建和存储设计矩阵的方式有关。 - Maurits Eversterms(y ~ . -x3, data=dt, simplify=TRUE)
来“展开”.
来获取一个简化公式,但是奇怪的是它仍然在变量属性中保留了x3
,这会使lm
函数出错。 - MrFlickneg.out=
选项可能与此有关。从实施了neg.out=
的terms
的 S 帮助文件中: 标志控制输入带 "-" 符号的术语的处理方式。如果为TRUE,则将检查术语以进行取消,否则将被忽略。如果为FALSE,则将保留负术语(具有负顺序)。 - thelatemaillm
在修改过的数据上调用model.matrix
。一开始,lm
会组合并评估以下表达式:mf <- stats::model.frame( y ~ . -x3, dt[x3=="men"], drop.unused.levels=TRUE )
。这会导致x3
成为单级别因子。然后在mf
上调用model.matrix()
,而不是原始数据,从而导致我们观察到的错误。 - Artem Sokolov