R 拆分列表需要很长时间

标签 r algorithm split 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)

如您所见,它有 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 

这非常有效,可以准确地提供我需要的输出。但是,当我增加单个列中的数字范围时,例如以下数据集中的 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 

您可以看到,只需将 3 个值添加到 A 即可使处理时间增加三倍。现在,当我向 BDJ 添加更多值时会发生什么情况,就像这样?

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

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

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

testSetLists <- testSetLists[sapply(testSetLists, function(x) dim(x)[1]) > 0]

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

最佳答案

看起来计算花了这么长时间,因为 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 

另请注意我是如何使用指示拆分的列,而不是一次手动编写一个列。

关于R 拆分列表需要很长时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36950700/

相关文章:

java - 如何在 java 中使用 split() 拆分字符为 "["的字符串

r - 运行 R 脚本后无法杀死 worker

arrays - 测量阵列连续性

r - 控制ggplot2图例位置而不改变轴的比例

algorithm - 带正方形的网格的最小精确覆盖;额外削减

algorithm - A* 表示未加权图表

c# - 如何通过列表属性将对象拆分为对象列表 C#

c - 如何分割和保存

r - 在ggplot2中为时间序列数据绘制带有置信区间的平均值

python - 操作系统错误 : cannot load library 'C:\Program Files\R\R-4.0.2\bin\x64\R.dll' : error 0x7e