R语言lm()在移除截距的多二元分类预测变量模型中仍出现参考类的原因咨询
R
lm() 移除截距时多分类预测变量的拟合逻辑 核心底层规则
lm()生成设计矩阵的逻辑完全依赖内置的model.matrix()函数,即使公式加了-1移除截距,基础哑变量生成规则不会改变:
- 默认情况下,k个水平的分类变量(factor)会生成k-1个对比哑变量,始终保留第一个水平作为参考组,不生成对应哑变量。
- 当公式中加入
-1移除截距时,model.matrix()会触发唯一的补全规则:遍历公式右侧的项,遇到第一个分类变量时,将它的哑变量从k-1个扩充为k个,用这组全水平哑变量替代被移除的截距项;后续所有分类变量、交互项都严格按照默认的k-1规则生成,不会再做任何扩充。
输出偏差的产生原因
公式value ~ name*Treat-1会被自动展开为value ~ name + Treat + name:Treat -1,按照上述规则生成的列结构完全对应实际输出的结果:
- 第一个分类变量为
name(2个水平:Y1、Y2),被触发补全规则,生成2个全水平哑变量nameY1、nameY2,无参考组,这部分结果符合预期。 - 第二个分类变量为
Treat(2个水平:0、0.5),未触发补全规则,按照默认规则生成1个哑变量Treat0.5,保留Treat=0作为参考组,这是Treat仍存在参考组的核心原因。 - 交互项严格匹配主效应的哑变量列生成,因此只会出现
nameY2:Treat0.5,不会生成nameY1:Treat0.5——因为nameY1基准状态与Treat参考组交叉的效应,已经被前面的主效应列吸收。
实现预期输出的调整方法
如果需要达到预期效果,即两个分类变量都不设置跨组的全局参考基准,所有Treat的效应都按name的分组拆分,避免生成不随name变化的全局Treat主效应列,只需要调整公式写法:
将原公式替换为lm(value ~ name + name:Treat -1, data = dat),展开后的列结构为:
- 全水平的name哑变量:
nameY1、nameY2 - 与name完全绑定的Treat交互哑变量:
nameY1:Treat0.5、nameY2:Treat0.5
该结构完全匹配预期输出的列设置,不会出现单独的全局Treat0.5主效应列。
注意:如果模型包含3个及以上分类变量,希望所有分类变量都不设置参考组,需要手动给每个分类变量的
contrasts属性指定为全水平对比形式,仅靠-1的自动补全规则无法实现全部变量的全水平哑变量生成。
内容的提问来源于stack exchange,提问作者rnorouzian
相关产品推荐
相关产品推荐

