R拆分列表需要很长时间

bla*_*p07 1 algorithm split r data.table

我有一个data.table我需要分成列表.这是一个示例数据集:

testSet <- data.table(A = 1:2, B = 4:5, C = rep(7:8, times = 50), 
                        D = 9:10, E = 15:16, F = 24:25, G = 27:28,
                        H = 29:30, I = 32:33, J = 35:36, K = 1:50)
Run Code Online (Sandbox Code Playgroud)

如您所见,它有11列,每列都是数字.我需要按10列中的值进行拆分,以便创建列表列表.我创建了以下功能代码(Macbook Air供参考):

system.time(testSetLists <- split(testSet, 
                list(testSet[["A"]], testSet[["B"]], testSet[["C"]],
                        testSet[["D"]], testSet[["E"]], testSet[["F"]], 
                        testSet[["G"]], testSet[["H"]], testSet[["I"]], 
                        testSet[["J"]])))

>    user  system elapsed 
    0.759   0.109   0.731 
Run Code Online (Sandbox Code Playgroud)

这完美地工作,并给我我所需的输出.但是,当我在一列中增加数字范围时,如A下面的数据集中所示:

testSet <- data.table(A = 1:5, B = 4:5, C = rep(7:8, times = 50), 
                        D = 9:10, E = 15:16, F = 24:25, G = 27:28,
                        H = 29:30, I = 32:33, J = 35:36, K = 1:50)

system.time(testSetLists <- split(testSet, 
                list(testSet[["A"]], testSet[["B"]], testSet[["C"]],
                        testSet[["D"]], testSet[["E"]], testSet[["F"]], 
                        testSet[["G"]], testSet[["H"]], testSet[["I"]], 
                        testSet[["J"]])))

>    user  system elapsed 
    2.139   0.301   2.054 
Run Code Online (Sandbox Code Playgroud)

您可以通过添加3个值来实现执行时间,A使处理时间增加三倍.现在,当我添加更多的值会发生什么B,D以及J,像这样?

testSet <- data.table(A = 1:5, B = 4:9, C = rep(7:8, times = 50), 
                        D = 9:14, E = 15:16, F = 24:25, G = 27:28,
                        H = 29:30, I = 32:33, J = 35:56, K = 1:50)

system.time(testSetLists <- split(testSet, 
                list(testSet[["A"]], testSet[["B"]], testSet[["C"]],
                        testSet[["D"]], testSet[["E"]], testSet[["F"]], 
                        testSet[["G"]], testSet[["H"]], testSet[["I"]], 
                        testSet[["J"]])))

>    user  system elapsed 
  179.356  21.311 176.562
Run Code Online (Sandbox Code Playgroud)

如您所见,当每列中有100个左右的唯一数据点时,此解决方案是站不住脚的.

我可以使用此函数删除所有空列表:

testSetLists <- testSetLists[sapply(testSetLists, function(x) dim(x)[1]) > 0]
Run Code Online (Sandbox Code Playgroud)

我的问题是:如何在没有极高CPU时间的情况下获取相同的输入并获得相同的输出?R中的任何选项都在桌面上.

nic*_*ola 5

似乎计算耗时很长,因为split试图确定所提供因素的每个组合.但是,drop=TRUE可以设置参数,因此只保留具有元素的组合.在您的最后一个数据集上,在我的电脑上:

system.time(testSetLists <- split(testSet,testSet[,.SD,.SDcols=names(testSet)[1:10]]))
#   user  system elapsed 
#128.111   0.343 128.930
system.time(testSetLists <- split(testSet,testSet[,.SD,.SDcols=names(testSet)[1:10]],drop=TRUE))
#   user  system elapsed 
#  0.048   0.000   0.048 
Run Code Online (Sandbox Code Playgroud)

还要注意我是如何使用指示拆分的列,而不是一次手动写一个.