R语言中glm()生成设计矩阵报错的解决方法咨询
问题:glm模型生成设计矩阵时的因子水平错误
先将mtcars数据的vs、am转为因子,分别用lm()和glm()拟合mpg ~ vs*am模型;随后修改数据将am统一设为"0",基于拟合模型生成设计矩阵:
mtcars_alt <- mtcars |> dplyr::mutate(vs = factor(vs), am = factor(am)) mod_lm <- lm(mpg ~ vs*am, data = mtcars_alt) mtcars_alt |> dplyr::mutate(am = "0") |> model.matrix(mod_lm, data = _) mod_glm <- glm(mpg ~ vs*am, data = mtcars_alt) mtcars_alt |> dplyr::mutate(am = "0") |> model.matrix(mod_glm, data = _)
使用lm()时运行正常,但使用glm()时抛出错误:
Error in `contrasts<-`(`*tmp*`, value = contr.funs[1 + isOF[nn]]) : contrasts can be applied only to factors with 2 or more levels
原因与解决办法
问题根源
lm()的model.matrix会自动沿用原模型中因子的水平定义,即使新数据里该因子只有一个水平也能正常生成矩阵;但glm()的model.matrix会重新检查新数据的因子水平,当am被统一设为"0"后,新数据里的am因子只剩一个水平,无法生成对比矩阵,因此报错。
修正方案
修改新数据时,保留原因子的所有水平,即使所有观测值都是同一个水平。可以通过factor()函数显式指定levels参数实现:
# 修正后的glm部分代码 mtcars_alt |> dplyr::mutate(am = factor("0", levels = levels(mtcars_alt$am))) |> model.matrix(mod_glm, data = _)
完整可运行代码
mtcars_alt <- mtcars |> dplyr::mutate(vs = factor(vs), am = factor(am)) # lm部分正常运行 mod_lm <- lm(mpg ~ vs*am, data = mtcars_alt) mtcars_alt |> dplyr::mutate(am = "0") |> model.matrix(mod_lm, data = _) # glm部分修正后运行 mod_glm <- glm(mpg ~ vs*am, data = mtcars_alt) mtcars_alt |> dplyr::mutate(am = factor("0", levels = levels(mtcars_alt$am))) |> model.matrix(mod_glm, data = _)
内容的提问来源于stack exchange,提问作者Stefan Hansen
相关产品推荐
相关产品推荐

