如何调试"对比只能应用于具有2个或更多级别的因素"错误?

时间:2017-05-26 11:16:25

标签: r regression lm glm r-faq

以下是我正在使用的所有变量:

str(ad.train)
$ Date                : Factor w/ 427 levels "2012-03-24","2012-03-29",..: 4 7 12 14 19 21 24 29 31 34 ...
 $ Team                : Factor w/ 18 levels "Adelaide","Brisbane Lions",..: 1 1 1 1 1 1 1 1 1 1 ...
 $ Season              : int  2012 2012 2012 2012 2012 2012 2012 2012 2012 2012 ...
 $ Round               : Factor w/ 28 levels "EF","GF","PF",..: 5 16 21 22 23 24 25 26 27 6 ...
 $ Score               : int  137 82 84 96 110 99 122 124 49 111 ...
 $ Margin              : int  69 18 -56 46 19 5 50 69 -26 29 ...
 $ WinLoss             : Factor w/ 2 levels "0","1": 2 2 1 2 2 2 2 2 1 2 ...
 $ Opposition          : Factor w/ 18 levels "Adelaide","Brisbane Lions",..: 8 18 10 9 13 16 7 3 4 6 ...
 $ Venue               : Factor w/ 19 levels "Adelaide Oval",..: 4 7 10 7 7 13 7 6 7 15 ...
 $ Disposals           : int  406 360 304 370 359 362 365 345 324 351 ...
 $ Kicks               : int  252 215 170 225 221 218 224 230 205 215 ...
 $ Marks               : int  109 102 52 41 95 78 93 110 69 85 ...
 $ Handballs           : int  154 145 134 145 138 144 141 115 119 136 ...
 $ Goals               : int  19 11 12 13 16 15 19 19 6 17 ...
 $ Behinds             : int  19 14 9 16 11 6 7 9 12 6 ...
 $ Hitouts             : int  42 41 34 47 45 70 48 54 46 34 ...
 $ Tackles             : int  73 53 51 76 65 63 65 67 77 58 ...
 $ Rebound50s          : int  28 34 23 24 32 48 39 31 34 29 ...
 $ Inside50s           : int  73 49 49 56 61 45 47 50 49 48 ...
 $ Clearances          : int  39 33 38 52 37 43 43 48 37 52 ...
 $ Clangers            : int  47 38 44 62 49 46 32 24 31 41 ...
 $ FreesFor            : int  15 14 15 18 17 15 19 14 18 20 ...
 $ ContendedPossessions: int  152 141 149 192 138 164 148 151 160 155 ...
 $ ContestedMarks      : int  10 16 11 3 12 12 17 14 15 11 ...
 $ MarksInside50       : int  16 13 10 8 12 9 14 13 6 12 ...
 $ OnePercenters       : int  42 54 30 58 24 56 32 53 50 57 ...
 $ Bounces             : int  1 6 4 4 1 7 11 14 0 4 ...
 $ GoalAssists         : int  15 6 9 10 9 12 13 14 5 14 ...

这是我想要适应的魅力:

ad.glm.all <- glm(WinLoss ~ factor(Team) + Season  + Round + Score  + Margin + Opposition + Venue + Disposals + Kicks + Marks + Handballs + Goals + Behinds + Hitouts + Tackles + Rebound50s + Inside50s+ Clearances+ Clangers+ FreesFor + ContendedPossessions + ContestedMarks + MarksInside50 + OnePercenters + Bounces+GoalAssists, 
                  data = ad.train, family = binomial(logit))

我知道它有很多变量(计划是通过前向变量选择减少)。但即使知道很多变量,他们要么是int,要么是因素;据我所知,事情应该与glm一起工作。但是,每当我尝试适应这个模型时,我得到:

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

我认为哪种R不是因为某种原因将我的因子变量视为因子变量?

即使是简单的事情:

ad.glm.test <- glm(WinLoss ~ factor(Team), data = ad.train, family = binomial(logit))

没有工作! (相同的错误消息)

这就是:

ad.glm.test <- glm(WinLoss ~ Clearances, data = ad.train, family = binomial(logit))

会工作!

任何人都知道这里发生了什么?为什么我不能将这些因子变量适合我的glm ??

提前致谢!

-Troy

2 个答案:

答案 0 :(得分:1)

根据我十分钟前的经验,这种情况可能发生在一个类别不止一个但NA较多的情况下。以Kaggle Houseprice Dataset为例, 如果您加载了数据并进行了简单的回归,

cols = colnames(train.df)
for (col in cols){
  if(is.factor(train.df[[col]])){
    cat(col, ' has ', length(levels(train.df[[col]])), '\n')
  }
}

您将收到相同的错误。我还尝试测试每个因素的级别数,但没有一个说它低于2个级别。

summary(train.df)

因此,很长一段时间后,我使用train.df = subset(train.df, select=-c(Id, PoolQC,Fence, MiscFeature, Alley, Utilities)) lm1 = lm(SalePrice ~ ., data = train.df) 来查看每个列的详细信息,并删除了一些列,终于可以了:

fill.na.with.mode = function(df){
    cols = colnames(df)
    for (col in cols){
        if(class(df[[col]])=='factor'){
            x = summary(df[[col]])
            mode = names(x[which.max(x)])
            df[[col]][is.na(df[[col]])]=mode
        }
        else{
            df[[col]][is.na(df[[col]])]=0
        }
    }
    return (df)
}

并删除其中任何一个,回归将无法再次运行,并出现相同的错误(我已经对自己进行了测试)。

另一种调试带有大量NA的错误的方法是,用列中最常见的属性替换每个NA。请注意以下方法不能调试,其中NA是列的模式,我建议手动删除这些列或替换这些列,而不是像这样对整个数据集应用函数:

{{1}}

及以上属性通常具有1400多个NA和10个有用值,因此,即使它们具有3或4个级别,您也可能希望删除这些垃圾属性。我猜想有一个函数计算每列中有多少个NA会有所帮助。

答案 1 :(得分:0)

也许作为第一步非常快,就是要验证您确实有至少两个因素。我找到的快捷方法是:

df %>% dplyr::mutate_all(as.factor) %>% str