循环遍历数据表的子集

时间:2017-05-11 21:04:50

标签: r data.table

假设我有一个随机数据表,我想循环其子集。

e.g。

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,将函数'test'应用于datatable的子集并将所有内容保存在列表中:

resultinglist <- vector("list",3)

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

到目前为止,这是直截了当的。现在我的问题是,对于非常大的数据集,这可能需要一段时间。因此:这个代码可以以任何方式进行优化,也许不会产生数据表子集的副本吗?

特别是,我想知道如果我将DT[id == i]传递给函数test会发生什么?这是正确的方法吗?例如,我也可以尝试循环并在每次迭代时过滤,然后在过滤的数据表上应用一些代码。

感谢任何提示。

2 个答案:

答案 0 :(得分:1)

我会选择> 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

EXPOSE 8002
COPY entrypoint.sh /code/
WORKDIR /code
ENTRYPOINT ["sh", "entrypoint.sh"]

即使只有少量数据点,也需要1/8的时间(在我的机器上)。

答案 1 :(得分: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