使GLM适合重叠的数据子集

时间:2015-09-16 18:21:56

标签: r optimization data.table glm

我需要将glms放到相同大数据集(~7M行)的各个重叠子集中,然后将这些模型对象保存在某处,所以我希望找到最快的方法来执行此操作。

我对R的整个data.table方面相当新,但我认为使用data.tables而不是data.frames至少应该改进过滤方面。

然而,鉴于我需要使模型适合的子集重叠,我不能只使用" by"关于data.table的论点。

我的数据看起来像这样:

IndepVar DepVar Flag1 Flag2 Flag3
1        14     G     B     G
0        21     B     B     G
1        19     G     G     B
etc.

基本上,对于每种可能的标志组合,我需要过滤" G"数据上的标志并适合glm。 即我需要适合以下模型: 所有数据,Flag1 =" G"数据,Flag2 =" G"数据,Flag1和Flag2 =" G"数据,Flag3 =&#数据34; G"等

自然,子集重叠。这可能需要使用更大的数据集,要查看的标志远远超过3个。

"最快"基于我有限的知识,我能想到的方式就像:

#DT exists as data.table
allConditions <-c(parse(text="Flag1==\"G\""),parse(text="Flag2==\"G\""),...)
getGlm <- function(condition, dataTable){
    glmModel <- dataTable[eval(condition),glm(IndepVar~DepVar,data=.SD)]
    save(...)
}
lapply(X=conditions,FUN=getGlm,dataTable=DT)

换句话说,将Glm逻辑包装在一个接受&#34;条件&#34;的函数中,然后在所有明确定义的标志组合上调用lapply。

但这仍需要几分钟。这里有很大的改进空间,还是我在数据的众多不同子集上调用glm的性质有限?

道歉,如果其中任何一个是错综复杂且不清楚的,那么任何有关优化的帮助都会受到高度赞赏。

1 个答案:

答案 0 :(得分:1)

所以你需要为每个模型保存整个glm对象吗?我不知道是否有比使用lapply更好的方式,那么。

以下是一些随机数据:

set.seed(123)
DT <- data.table(I=rnorm(1e3), D=rnorm(1e3), F1=sample(c('G', 'B'), 1e3, replace=T), F2=sample(c('G', 'B'), 1e3, replace=T),F3=sample(c('G', 'B'), 1
e3, replace=T))
DT
                I           D F1 F2 F3
   1: -0.56047565 -0.99579872  G  G  G
   2: -0.23017749 -1.03995504  B  B  G
   3:  1.55870831 -0.01798024  B  B  G
   4:  0.07050839 -0.13217513  B  B  B
   5:  0.12928774 -2.54934277  G  G  G
  ---                                 
 996: -0.08997520  0.07664366  G  B  G
 997:  1.07051604  0.25516476  B  B  G
 998: -1.35110039  0.27744682  G  B  G
 999: -0.52261670  0.53685602  B  B  B
1000: -0.24919068 -0.46048557  G  B  B

然后创建一个指示“组”的列(即标志的组合):

DT[, group := interaction(F1, F2, F3)]
DT
                I           D F1 F2 F3 group
   1: -0.56047565 -0.99579872  G  G  G G.G.G
   2: -0.23017749 -1.03995504  B  B  G B.B.G
   3:  1.55870831 -0.01798024  B  B  G B.B.G
   4:  0.07050839 -0.13217513  B  B  B B.B.B
   5:  0.12928774 -2.54934277  G  G  G G.G.G
  ---                                       
 996: -0.08997520  0.07664366  G  B  G G.B.G
 997:  1.07051604  0.25516476  B  B  G B.B.G
 998: -1.35110039  0.27744682  G  B  G G.B.G
 999: -0.52261670  0.53685602  B  B  B B.B.B
1000: -0.24919068 -0.46048557  G  B  B G.B.B

现在我们可以使用lapply并保存对象:

myLevels <- DT[, unique(as.numeric(group))]
myGLMs <- lapply(myLevels, function(x) DT[as.numeric(group) == x, glm(I ~ D)])
str(myGLMs, max=1)
List of 8
 $ :List of 30
  ..- attr(*, "class")= chr [1:2] "glm" "lm"
 $ :List of 30
  ..- attr(*, "class")= chr [1:2] "glm" "lm"
 $ :List of 30
  ..- attr(*, "class")= chr [1:2] "glm" "lm"
 $ :List of 30
  ..- attr(*, "class")= chr [1:2] "glm" "lm"
 $ :List of 30
  ..- attr(*, "class")= chr [1:2] "glm" "lm"
 $ :List of 30
  ..- attr(*, "class")= chr [1:2] "glm" "lm"
 $ :List of 30
  ..- attr(*, "class")= chr [1:2] "glm" "lm"
 $ :List of 30
  ..- attr(*, "class")= chr [1:2] "glm" "lm"

在我的系统上,1e6行和3个标志,它花费了2秒。增加到4个标志,花费了相同的时间。增加到6个标志,花费了2秒。

当我增加到1e7行,6个标记时,花费22秒(计算所有交互只需5秒)。