簡體   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