我知道这个问题可以通过生成预先计算的转换来规避,但我真的想使用R的公式功能。这是我的问题的可重现的例子:
生成(相关)玩具数据:
set.seed(123)
test<-data.frame(x=rnorm(100,1,.5),z=factor(sample(c('a','b','c'),100,T)))
test$y<-.3*test$x+0*(test$z=='a')-.07*(test$z=='b')-.15*(test$z=='c')+rnorm(100,0,.1)
运行线性模型:
> lm(y ~ x + z, test)
Call:
lm(formula = y ~ x + z, data = test)
Coefficients:
(Intercept) x zb zc
0.02453 0.27484 -0.08279 -0.12868
看起来不错。第一个因子级别'a'被省略,就像它应该的那样。现在包括数字x和因子z之间的交互:
> lm(y ~ x + z + z:x, test)
Call:
lm(formula = y ~ x + z + z:x, data = test)
Coefficients:
(Intercept) x zb zc x:zb x:zc
0.037008 0.262650 -0.134938 -0.118896 0.049068 -0.009225
lm(y ~ poly(x,2) + z:x, test)
一切都还好。现在使用'poly'函数添加x:
的二次变换> lm(y ~ poly(x, 2) + z + z:x, test)
Call:
lm(formula = y ~ poly(x, 2) + z + z:x, data = test)
Coefficients:
(Intercept) poly(x, 2)1 poly(x, 2)2 zb zc za:x zb:x zc:x
0.33928 1.23017 -0.18029 -0.15478 -0.15574 -0.02749 0.04165 NA
就是这样。它不是在交互项中排除第一级z'a',而是包含在另外两个级别中。现在,za:x ist'别名'因为模型当然是单数的,包括所有三个因子级别。这很糟糕,因为像'car'包中的'vif'这样的函数不起作用:
> vif(lm(y ~ poly(x,2) + z + z:x, test))
Error in vif.lm(lm(y ~ poly(x, 2) + z + z:x, test)) :
there are aliased coefficients in the model
我尝试过y~poly(x,2)+ z + z:poly(x,1)或y~poly(x,2)+ z + relevel(z,ref ='a'):x但似乎没什么用。这是一个错误还是有人可以解释这个结果?有没有办法避免这个问题,仍然按照我的意图使用公式功能?感谢。
答案 0 :(得分:1)
因为公式允许您使用任何函数,所以R无法知道哪些函数将返回等于等式中已有的其他值的值。存在poly()
的特殊编码。
如果您只想添加x
和x^2
字词,则可以
lm(formula = y ~ x + I(x^2) + z + z:x, data = test)
避免一起使用poly()
。你只需要在构建公式时要更加小心。