Lorsque j'essaie de définir mon modèle linéaire dans R comme suit:
lm1 <- lm(predictorvariable ~ x1+x2+x3, data=dataframe.df)
Je reçois le message d'erreur suivant:
Error in `contrasts<-`(`*tmp*`, value = contr.funs[1 + isOF[nn]]) :
contrasts can be applied only to factors with 2 or more levels
Y a-t-il un moyen d'ignorer ceci ou de le réparer? Certaines des variables sont des facteurs et d'autres non.
Si votre variable indépendante (variable RHS) est un facteur ou un caractère prenant une seule valeur, ce type d'erreur se produit.
Exemple: données de l'iris dans 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
Maintenant, si vos données ne concernent qu'une seule espèce:
(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 est numérique (Sepal.Width
) mais en prenant une seule valeur, par exemple 3, le modèle s'exécutera, mais vous obtiendrez NA
comme coefficient de cette variable, comme suit:
(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
Solution : Il n'y a pas assez de variation de variable dépendante avec une seule valeur. Vous devez donc supprimer cette variable, qu’elle soit numérique, variable de caractère ou facteur.
Mis à jour selon les commentaires: Puisque vous savez que l'erreur ne se produira qu'avec un facteur/caractère, vous pouvez vous concentrer uniquement sur ceux-ci et voir si la longueur des niveaux de ces variables à facteurs est 1 (DROP) ou supérieure à 1 ( AUCUNE CHUTE).
Pour voir si la variable est un facteur ou non, utilisez le code suivant:
(l <- sapply(iris, function(x) is.factor(x)))
# Sepal.Length Sepal.Width Petal.Length Petal.Width Species
# FALSE FALSE FALSE FALSE TRUE
Ensuite, vous pouvez obtenir le cadre de données des variables de facteur uniquement
m <- iris[, l]
Maintenant, trouvez le nombre de niveaux de variables factorielles, si vous en avez besoin
ifelse(n <- sapply(m, function(x) length(levels(x))) == 1, "DROP", "NODROP")
Remarque: Si le niveau de la variable facteur est unique, il faut abandonner cette variable.
Il semble qu'au moins un de vos prédicteurs, x1
, x2
ou x3
, ne comporte qu'un seul niveau de facteur et constitue donc une constante.
Jettes un coup d'oeil à
lapply(dataframe.df[c("x1", "x2", "x3")], unique)
pour trouver les différentes valeurs.
Metrics and Svens répondent à la situation habituelle, mais pour nous qui travaillons dans des environnements non anglais, si vous avez des caractères exotiques (å, ä, ö) dans votre variable de personnage, vous obtiendrez le même résultat, même si vous avez plusieurs niveaux de facteurs.
Levels <- c("Pri", "För")
donne l'erreur de contraste, alors que Levels <- c("Pri", "For")
ne le fait pas
C'est probablement un bug.
Ce message d'erreur peut également se produire lorsque les données contiennent NA
s.
Dans ce cas, le comportement dépend des valeurs par défaut (voir la documentation), et peut-être que tous les cas avec NA
dans les colonnes mentionnées dans les variables sont supprimés en silence. Il se peut donc bien qu’un facteur produise effectivement plusieurs résultats, mais il n’a qu’un seul résultat lorsqu’il se limite aux cas sans NA
.
Dans ce cas, pour corriger l'erreur, modifiez le modèle (supprimez le facteur problématique de la formule) ou modifiez les données (c.-à-d. Complétez les observations).
Si l'erreur se produit parce que vos données contiennent des NA, vous devez définir les options de la fonction glm () de la manière dont vous souhaitez traiter les cas de NA. Vous trouverez plus d'informations à ce sujet dans un article pertinent ici: https://stats.stackexchange.com/questions/46692/how-the-na-values-are-treated-in-glm-in-r
Ceci est une variation de la réponse fournie par @Metrics et éditée par @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,])))
Ici, après avoir identifié les variables factorielles, la seconde sapply
calcule le pourcentage d'enregistrements appartenant à chaque niveau/catégorie de la variable. Ensuite, il identifie le nombre de niveaux supérieurs à 99,5% ou inférieurs à 0,5% (mes seuils arbitraires).
Il renvoie ensuite le nombre de niveaux valides et le taux d’incidence de chaque niveau dans chaque variable catégorielle.
Les variables dont le niveau zéro dépasse les seuils ne doivent pas être supprimées, tandis que les autres doivent être supprimées du modèle linéaire.
Le dernier bloc de données facilite l'affichage des résultats. Il est codé en dur pour cet ensemble de données car toutes les variables factorielles sont binomiales. Ce bloc de données peut être assez facilement générique.