2017-05-11 86 views
1

假設我有一個隨機數據表,並且我想遍歷其子集。在數據表子集上循環

例如

DT <- data.table(date = rep(c(1979,1980,1981,1982),3), 
Id = rep(c(1,2,3),each = 4), 
x1 = c(10, 40, 80,12,13,19,9,5,22,13,49,110), 
x2 = sample(100,12,replace=T), 
x3 = sample(100,12,replace=T)) 

我也有以下功能:

test <- function(x){x[,3:5]/100} 

假設我遍歷ID,應用功能「測試」到DataTable的子集,並保存一切都在一個列表:

resultinglist <- vector("list",3) 

for (i in 1:3){resultinglist[[i]] <- test(DT[Id == i])} 

到目前爲止,這是直截了當的。現在我的問題是,對於非常大的數據集,這可能需要一段時間。因此:該代碼是否可以以任何方式進行優化,也許這樣就不會創建數據表子集的副本?

特別是,我不知道如果我通過DT[id == i]運作test會發生什麼?這是正確的方法嗎?例如,我也可以嘗試循環並在每次迭代過濾,然後在過濾的數據表上應用一些代碼。

感謝您的任何提示。

回答

1

我會去與split(test(DT), DT$Id)

> system.time(resultinglist1<- split(test(DT), DT$Id)) 
    user system elapsed 
    0.002 0.000 0.002 

> resultinglist <- vector("list",3) 
> system.time(for (i in 1:3){resultinglist[[i]] <- test(DT[Id == i])}) 
    user system elapsed 
    0.015 0.000 0.016 

即使考慮到這幾個數據點花費的時間1/8(我的機器上)。

+0

有趣,即使'split'不是專門爲數據對象生成的嗎?此外,過濾可能更復雜,但可能拆分也可以處理多個過濾器。 在我接受這個之前,如果有人有想法,我會等待另一種方法。也許有更多數據可用的方式。謝謝! – user3032689

+1

您可以看到split.data.table方法存在但隱藏。但是,有一個幫助頁面。 –

+0

@ user3032689數據表具有自己的「split」功能。這就是說,對於更復雜的過濾,你可以做'split(test(DT),DT [,。(Id,Id2)])'' –

1

有一個split.data.table方法:看?split.data.table這樣試試:

> split(DT, by=c("Id"), flatten=FALSE) 
$`1` 
    date Id x1 x2 x3 
1: 1979 1 10 26 74 
2: 1980 1 40 17 5 
3: 1981 1 80 43 51 
4: 1982 1 12 35 96 

$`2` 
    date Id x1 x2 x3 
1: 1979 2 13 8 65 
2: 1980 2 19 66 69 
3: 1981 2 9 69 27 
4: 1982 2 5 4 80 

$`3` 
    date Id x1 x2 x3 
1: 1979 3 22 100 29 
2: 1980 3 13 28 83 
3: 1981 3 49 53 55 
4: 1982 3 110 89 7 

如果你想提取3〜5列可能是:

lapply(split(DT, by=c("Id"), flatten=FALSE), subset, select=3:5) 
$`1` 
    x1 x2 x3 
1: 10 26 74 
2: 40 17 5 
3: 80 43 51 
4: 12 35 96 

$`2` 
    x1 x2 x3 
1: 13 8 65 
2: 19 66 69 
3: 9 69 27 
4: 5 4 80 

$`3` 
    x1 x2 x3 
1: 22 100 29 
2: 13 28 83 
3: 49 53 55 
4: 110 89 7 

參見?subset.data.table