如果您的自变量(RHS 变量)是一个因子或一个字符,它只取一个值,那么就会发生这种类型的错误。
示例:R中的虹膜数据
(model1 <- lm(Sepal.Length ~ Sepal.Width + Species, data=iris))
# Call:
# lm(formula = Sepal.Length ~ Sepal.Width + Species, data = iris)
# Coefficients:
# (Intercept) Sepal.Width Speciesversicolor Speciesvirginica
# 2.2514 0.8036 1.4587 1.9468
现在,如果您的数据仅包含一个物种:
(model1 <- lm(Sepal.Length ~ Sepal.Width + Species,
data=iris[iris$Species == "setosa", ]))
# Error in `contrasts<-`(`*tmp*`, value = contr.funs[1 + isOF[nn]]) :
# contrasts can be applied only to factors with 2 or more levels
如果变量是数字 (Sepal.Width) 但仅取单个值(例如 3),则模型会运行,但您将得到 NA 作为该变量的系数,如下所示:
(model2 <-lm(Sepal.Length ~ Sepal.Width + Species,
data=iris[iris$Sepal.Width == 3, ]))
# Call:
# lm(formula = Sepal.Length ~ Sepal.Width + Species,
# data = iris[iris$Sepal.Width == 3, ])
# Coefficients:
# (Intercept) Sepal.Width Speciesversicolor Speciesvirginica
# 4.700 NA 1.250 2.017
解决方案:因变量只有一个值的变化不够。因此,您需要删除该变量,无论它是数字变量还是字符变量还是因子变量。
根据 cmets 更新:由于您知道错误只会发生在因子/字符上,因此您可以只关注那些并查看这些因子变量的级别长度是否为 1(DROP ) 或大于 1 (NODROP)。
要查看变量是否为因子,请使用以下代码:
(l <- sapply(iris, function(x) is.factor(x)))
# Sepal.Length Sepal.Width Petal.Length Petal.Width Species
# FALSE FALSE FALSE FALSE TRUE
那么就可以只获取因子变量的数据框了
m <- iris[, l]
现在,找到因子变量的级别数,如果这是一个你需要删除它
ifelse(n <- sapply(m, function(x) length(levels(x))) == 1, "DROP", "NODROP")
注意:如果因子变量的级别只有一个,那就是变量,你必须放弃。