我需要将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的性质有限?
道歉,如果其中任何一个是错综复杂且不清楚的,那么任何有关优化的帮助都会受到高度赞赏。
答案 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
秒)。