繁体   English   中英

R中的lm:“对比”错误的解决方法

[英]lm in R: Workaround for 'contrasts' error

我正在使用大量数据(5,000万行)和biglm软件包创建线性模型。 这是通过首先基于数据块创建线性模型,然后通过读取更多数据块(100万行)并使用来自“ biglm”的“更新”功能来更新模型来完成的。 我的模型使用年份(具有20个水平的因子),温度以及一个为1或0的因子变量is_paid。 代码看起来像这样:

model = biglm(output~year:is_paid+temp,data = df) #creates my original model from a starting data frame, df
newdata = file[i] #This is just an example of me getting a new chunk of data in; don't worry about it
model = update(model,data = newdata) #this is where the update to the new model with the new data happens

问题是is_paid因子变量几乎始终为0。因此,有时当我读入一块数据时,is_paid列中的每个值都将为0,并且显然会出现以下错误:

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

因此,基本上,我需要一种让模型接受更新而又不会因为在新数据块中没有两个不同因素而生气的方法。

我想到的一种方法是始终将一行实际数据的is_paid值设置为“ 1”,然后将其添加到新块中。 这样,不仅有多种因素,而且我仍在添加真实数据。 代码看起来像这样:

#the variable 'line' is a single line of data that has a '1' for is_paid
newdata = file[i] #again, an example of me reading in a new chunk of data. I know that this doesn't make sense by itself
newdata = rbind(line,newdata) #add in the sample line with '1' in is_paid to newdata
model = update(model,newdata) #update the data

这是我的数据的示例:

output  year    temp is_paid
1100518     12     40   0
2104518     12     29   0   
1100200     15     17   0   
1245110     16     18   0 
5103128     14     30   0 

这是我的示例行的示例,它是is_paid为1的真实记录:

output  year temp is_paid
31200599 12  49     1

是否会在同一行中一遍又一遍地添加变量变量的系数? 我在一些伪代码上进行了测试,这看起来不像一遍又一遍地更新具有相同记录的模型会影响它,但是我很怀疑。

我觉得有一种更优雅,更聪明的方法可以做到这一点。 我一直在阅读R教程,似乎有一种方法可以设置lm模型的对比度。 我看了'lm'中的'contrasts'参数,但是什么都找不到。 我认为您无论如何都无法在biglm中设置对比,这是我需要使用的。 非常感谢您能想到的任何见解或解决方案。

* is_paid的数字变量与因子变量的比较:

df.num = data.frame(a = c(1:10),b = as.factor(rep(c(1,2,3,4,5),each = 2)),c = c(rep(0,each = 5),rep(1,each = 5)))
df.factor = data.frame(a = c(1:10),b = as.factor(rep(c(1,2,3,4,5),each = 2)),c = as.factor(c(rep(0,each = 5),rep(1,each = 5))))

mod.factor = lm(a~b:c,data = df.factor)
mod.num = lm(a~b:c,data = df.num)

> mod.factor

Call:
lm(formula = a ~ b:c, data = df.factor)
Coefficients:
(Intercept)        b1:c0        b2:c0        b3:c0        b4:c0        b5:c0        b1:c1  
    9.5         -8.0         -6.0         -4.5           NA           NA           NA  
  b2:c1        b3:c1        b4:c1        b5:c1  
     NA         -3.5         -2.0           NA  


 Call:
 lm(formula = a ~ b:c, data = df.num)

Coefficients:
(Intercept)         b1:c         b2:c         b3:c         b4:c         b5:c  
    3.0           NA           NA          3.0          4.5          6.5  

这里的结论是,如果is_paid为数字,则将更改模型。

****我还稍微修改了模型,以查看两个因素的相互作用,而不仅仅是三个变量。 这意味着我不能将is_paid视为数字(我认为)

将Ben Bolker的评论变成答案,并提供一些更好模拟的数据的证据。

只需连续对待您的两级因素即可。 这与将其视为因素相同。

例:

df.num = data.frame(a = rnorm(12),
                    b = as.factor(rep(1:4,each = 3)),
                    c = rep(0:1, 6))
df.factor = df.num
df.factor$c = factor(df.factor$c)

mod.factor = lm(a~b*c - 1,data = df.factor)
mod.num = lm(a~b*c - 1,data = df.num)

all(coef(mod.factor) == coef(mod.num))
# [1] TRUE

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM