web-dev-qa-db-fra.com

Erreur de contraste lors de la définition d'un modèle linéaire dans R

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.

33
REnthusiast

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. 

49
Metrics

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.

14
Sven Hohenstein

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.

3
ErrantBard

Ce message d'erreur peut également se produire lorsque les données contiennent NAs.

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).

2
jarauh

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

0
Sadiaz

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. 

0
dk_b