Error en contrastes al definir un modelo lineal en R

Cuando bash definir mi modelo lineal en R de la siguiente manera:

lm1 <- lm(predictorvariable ~ x1+x2+x3, data=dataframe.df) 

Aparece el siguiente mensaje de error:

 Error in `contrasts<-`(`*tmp*`, value = contr.funs[1 + isOF[nn]]) : contrasts can be applied only to factors with 2 or more levels 

¿Hay alguna manera de ignorar esto o arreglarlo? Algunas de las variables son factores y otras no.

Si su variable independiente (variable RHS) es un factor o un personaje que toma solo un valor, entonces ese tipo de error ocurre.

Ejemplo: datos de iris en 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 

Ahora, si sus datos constan de una sola especie:

 (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 

Si la variable es numérica ( Sepal.Width ) pero tomando solo un único valor, digamos 3, entonces el modelo se ejecuta pero obtendrá NA como coeficiente de esa variable de la siguiente manera:

 (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 

Solución : no hay suficiente variación en la variable dependiente con solo un valor. Por lo tanto, debe descartar esa variable, independientemente de si se trata de una variable numérica o de carácter o factor.

Actualizado según comentarios: ya que sabe que el error solo ocurrirá con factor / carácter, puede enfocarse solo en esos y ver si la duración de los niveles de esas variables de factor es 1 (DROP) o mayor que 1 (NODROP).

Para ver si la variable es un factor o no, use el siguiente código:

 (l < - sapply(iris, function(x) is.factor(x))) # Sepal.Length Sepal.Width Petal.Length Petal.Width Species # FALSE FALSE FALSE FALSE TRUE 

Entonces puede obtener el dataframe de variables de factor solamente

 m < - iris[, l] 

Ahora, encuentre la cantidad de niveles de las variables de los factores, si es así, debe soltar esa

 ifelse(n < - sapply(m, function(x) length(levels(x))) == 1, "DROP", "NODROP") 

Nota: Si los niveles de la variable de factor son solo uno, entonces esa es la variable, debe soltar.

Parece que al menos uno de tus predictores, x1 , x2 o x3 , tiene solo un nivel de factor y, por lo tanto, es una constante.

Mira esto

 lapply(dataframe.df[c("x1", "x2", "x3")], unique) 

para encontrar los diferentes valores

Metrics y Svens responden a la situación habitual, pero para nosotros que trabajamos en entornos no ingleses si tienes caracteres exóticos (å, ä, ö) en tu variable de carácter obtendrás el mismo resultado, incluso si tienes múltiples niveles de factor.

Levels < - c("Pri", "För") dan el error de contraste, mientras que los Levels < - c("Pri", "For") no

Esto es probablemente un error.

Este mensaje de error también puede ocurrir cuando los datos contienen NA s.

En este caso, el comportamiento depende de los valores predeterminados (ver documentación), y tal vez todos los casos con NA en las columnas mencionadas en las variables se eliminan en silencio. Por lo tanto, es posible que un factor tenga varios resultados, pero el factor solo tiene un resultado cuando se restringe a los casos sin NA .

En este caso, para corregir el error, cambie el modelo (elimine el factor problemático de la fórmula) o cambie los datos (es decir, complete los casos).

Esta es una variación de la respuesta proporcionada por @Metrics y editada por @Max Ghenis …

 l < - sapply(iris, function(x) is.factor(x)) m <- iris[,l] n <- sapply( m, function(x) { y <- summary(x)/length(x) len <- length(y[y<0.005 | y>0.995]) cbind(len,t(y))} ) drop_cols_df < - data.frame(var = names(l[l]), status = ifelse(as.vector(t(n[1,]))==0,"NODROP","DROP" ), level1 = as.vector(t(n[2,])), level2 = as.vector(t(n[3,]))) 

Aquí, después de identificar las variables de los factores, el segundo calcula sapply qué porcentaje de registros pertenece a cada nivel / categoría de la variable. Luego identifica el número de niveles por encima del 99.5% o por debajo del índice de incidencia del 0.5% (mis umbrales arbitrarios).

A continuación, devuelve el número de niveles válidos y la tasa de incidencia de cada nivel en cada variable categórica.

Las variables con niveles cero que cruzan los umbrales no deben descartarse, mientras que las otras deben eliminarse del modelo lineal.

El último dataframe hace que ver los resultados sea fácil. Está codificado para este conjunto de datos, ya que todas las variables de factores son binomiales. Este dataframe puede hacerse genérico con la suficiente facilidad.