R

时间:2018-10-30 05:35:42

标签: r data.table tibble

我有一个data.table值,可以在其中循环计算汇总统计信息,并寻求汇总汇总结果以进行其他处理。但是,由于聚合的结果,循环处理时间出乎意料地冗长,因此我正在寻求更快的解决方案。

该方法非常类似于此处讨论的方法(Assign a vector to a specific existing row of data table in R)。

代码(出于可读性考虑,对进行了略微删节,但保留了示例性的内容):

library(data.table);
x <- data.table(matrix(double(),nrow=10000,ncol=120));
system.time({for (i in NROW(x):1) {
    m <- matrix(rnorm(8*15),nrow=8,ncol=15);
}});
#  user  system elapsed 
# 0.165   0.006   0.171 
system.time({for (i in NROW(x):1) {
    m <- matrix(rnorm(8*15),nrow=8,ncol=15);
    as.list(t(m[1:8,]));
}});
#   user  system elapsed 
#  0.245   0.001   0.249
system.time({for (i in NROW(x):1) {
    m <- matrix(rnorm(8*15),nrow=8,ncol=15);
    x[i,] <- as.list(t(m[1:8,]));
}});
#   user  system elapsed 
# 36.227   0.682  37.529

# Obtain input data.table
inputdt <- fread('filename');

# Preallocate summary statistics aggregate
sumstatsdt <- data.table(matrix(double(),nrow=10000,ncol=120));

# Loop over input data.table (the *apply suite not suitable for mypkg::calcstats())
for (i in NROW(inputdt):1) {
    # Produce a matrix of summary statistics for the row (of type double)
    sumstat_matrix <- mypkg::calcstats(inputdt,...);

    # Aggregate the summary statistics (where "a","b","c",... are matrix row names of ordered statistics)
    # >>>> This is the operation that leads to lengthy execution time
    sumstatsdt[i,] <- as.list(t(sumstat_matrix[c("a","b","c",...),]));
};

输入data.table包含具有8个属性的10,000个观测值,总共要存储120万个摘要统计信息(每个统计信息均为“ double”类型)。注释掉执行聚合的循环的最后一行时,总处理时间约为 24秒。使用聚合运行时,总处理时间增加到 34分钟

我尝试将类似的代码与data.framecbind()结合使用,从而获得大致相似的性能结果(没有机会尝试tidyverse套件)。认识到深度复制操作会稍微慢一些,尽管在给定相对较小的数据集的情况下执行时间差的大小似乎表明存在另一个问题。

在最近的Fedora安装中运行R v3.4.4,data.table v1.11.4。内存使用量可以忽略不计(不到R脚本执行期间使用的系统RAM的3%)。与R会话具有亲和力的2.1GHz CPU处理器之一在脚本执行期间的运行速度接近100%。没有与该核心相关联的其他进程,其余核心在很大程度上处于空闲状态。 ( NB :说明性代码在另一台计算机上的KVM guest虚拟机中运行)

旁注:还好奇为什么CPU瓶颈会在内存问题中显现出来。

感谢您的时间,并乐意提供有用的其他信息。

编辑[2018.10.31]

  • 包括42要求的说明性代码

1 个答案:

答案 0 :(得分:0)

您的机器似乎是我的机器的速度的两倍,但是通过使用data.table运算符:=而不是{ {1}}。我不确定,但是怀疑使用<-会导致您依赖于创建中间临时副本的常规R步骤,因此<-方法也可能会提高内存效率:< / p>

:=

常规R是单线程进程,除非您安装MRAN之类的“售后” mod之一。