web-dev-qa-db-ja.com

Rで線形モデルを定義する際の対照的なエラー

次のようにRで線形モデルを定義しようとすると:

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

次のエラーメッセージが表示されます。

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

これを無視する方法や修正する方法はありますか?一部の変数は要因であり、一部はそうではありません。

40
REnthusiast

独立変数(RHS変数)が1つの値のみをとる因子または文字である場合、そのタイプのエラーが発生します。

例: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  

ここで、データが1つの種のみで構成されている場合:

(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

解決策:値が1つだけの従属変数には十分な変動がありません。そのため、数値変数、文字変数、因子変数に関係なく、その変数を削除する必要があります。

コメントごとに更新:エラーはファクター/キャラクターでのみ発生することがわかっているため、それらにのみ焦点を当て、それらのファクター変数のレベルの長さが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")

注:因子変数のレベルが1つだけの場合、それが変数であるため、ドロップする必要があります。

57
Metrics

予測子の少なくとも1つ、x1x2、またはx3には1つの因子レベルしかなく、したがって定数であるようです。

見て

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

異なる値を見つけます。

14
Sven Hohenstein

メトリクスとスベンスは通常の状況に対処しますが、キャラクター変数に異国のキャラクター(å、ä、ö)が含まれている場合、非英語環境で作業する私たちにとっては、複数の因子レベルがあっても同じ結果が得られます。

Levels <- c("Pri", "För")はコントラストエラーを与えますが、Levels <- c("Pri", "For")は与えません

これはおそらくバグです。

3
ErrantBard

このエラーメッセージは、データにNAsが含まれている場合にも発生する可能性があります。

この場合、動作はデフォルト(ドキュメントを参照)に依存し、変数に記載されている列にNAが含まれるすべてのケースは、暗黙のうちに削除されます。そのため、ファクターには実際にいくつかの結果がありますが、NAのないケースに制限する場合、ファクターには1つの結果しかありません。

この場合、エラーを修正するには、モデルを変更する(式から問題のある要素を削除する)か、データを変更します(つまり、ケースを完成させます)。

2
jarauh

データにNAがあるためにエラーが発生した場合、NAケースの処理方法のglm()関数オプションを設定する必要があります。詳細については、関連する投稿を参照してください: https://stats.stackexchange.com/questions/46692/how-the-na-values-are-treatment-in-glm-in-r

0
Sadiaz

これは、@ Metricsが提供し、@ 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,])))

ここでは、因子変数を識別した後、2番目のsapplyは、変数の各レベル/カテゴリに属する​​レコードの割合を計算します。次に、99.5%を超えるレベルまたは0.5%未満の発生率(私の任意のしきい値)を識別します。

次に、有効なレベルの数と各カテゴリ変数の各レベルの発生率を返します。

しきい値を超えるゼロレベルの変数は削除しないでください。一方、他の変数は線形モデルから削除する必要があります。

最後のデータフレームにより、結果を簡単に表示できます。すべての因子変数は二項変数であるため、このデータセットにはハードコードされています。このデータフレームは、十分に簡単に汎用化できます。

0
dk_b