通过R中的数据子集执行计算

Viv*_*ivi 5 foreach r subset

我想在我的数据框的PERMNO列中对每个公司编号执行计算,其摘要可以在这里看到:

> summary(companydataRETS)
     PERMNO           RET           
 Min.   :10000   Min.   :-0.971698  
 1st Qu.:32716   1st Qu.:-0.011905  
 Median :61735   Median : 0.000000  
 Mean   :56788   Mean   : 0.000799  
 3rd Qu.:80280   3rd Qu.: 0.010989  
 Max.   :93436   Max.   :19.000000  
Run Code Online (Sandbox Code Playgroud)

到目前为止,我的解决方案是创建一个包含所有公司编号的变量

compns <- companydataRETS[!duplicated(companydataRETS[,"PERMNO"]),"PERMNO"]
Run Code Online (Sandbox Code Playgroud)

然后使用并行计算的foreach循环调用我的函数get.rho(),然后执行所需的计算

rhos <- foreach (i=1:length(compns), .combine=rbind) %dopar% 
      get.rho(subset(companydataRETS[,"RET"],companydataRETS$PERMNO == compns[i]))
Run Code Online (Sandbox Code Playgroud)

我测试了它的一部分数据,一切正常.问题是我有7200万观察,即使在电脑一夜之间工作,它仍然没有完成.

我是R的新手,所以我想我的代码结构可以改进,并且有更好的(更快,更少计算密集)的方式来执行同样的任务(也许使用apply或with,我不明白) .有什么建议?

Viv*_*ivi 4

按照乔兰的建议,我走进了图书馆data.table。代码的修改是

library(data.table) 
companydataRETS <- data.table(companydataRETS)
setkey(companydataRETS,PERMNO)

rhos <- foreach (i=1:length(compns), .combine=rbind) %do% 
      get.rho(companydataRETS[J(compns[i])]$RET)
Run Code Online (Sandbox Code Playgroud)

我按照原来的方式(使用subset)运行代码,并且曾经使用data.table,变量compns仅包含数据集中 28659 个公司中的 30 个。system.time()以下是两个版本的输出:

使用subset

用户........系统......经过
43.925 ... 12.413...... 56.337

使用data.table

用户......系统......经过
0.229.....0.047.......0.276

(出于某种原因,使用%do%代替%dopar%for 原始代码使其运行速度更快。system.time()forsubset是使用 的那个%do%,在本例中是两者中更快的一个。)

我让原始代码运行了一整夜,但 5 个小时后它还没有完成,所以我放弃并终止了它。通过这个小小的修改,我在不到 5 分钟的时间内就得到了结果(我想大约 3 分钟)!

编辑

有一种更简单的方法可以使用 来完成此操作data.table,而不使用foreach,其中涉及将上面代码的最后一行替换为

rhos <- companydataRETS[ , get.rho(RET), by=PERMNO]
Run Code Online (Sandbox Code Playgroud)