当我坐在这里等待一些R脚本运行...我想知道...有没有办法在R中并行化rbind?
当我处理大量数据时,我坐着等待这个电话频繁完成.
do.call("rbind", LIST)
Run Code Online (Sandbox Code Playgroud) 我知道在这里有很多关于使用do.call或ldply将data.frames列表转换为单个data.frame的方法,但这个问题是关于理解两种方法的内部工作方式并试图找出原因我无法将两个相同结构,相同字段名称等近100万个df的列表连接到一个data.frame中.每个data.frame都是一行和21列.
数据以JSON文件开头,我使用fromJSON转换为列表,然后运行另一个lapply来提取列表的一部分并转换为data.frame,最后得到一个data.frames列表.
我试过了:
df <- do.call("rbind", list)
df <- ldply(list)
Run Code Online (Sandbox Code Playgroud)
但我不得不在让它运行3个小时并且没有得到任何回报之后终止这个过程.
有更有效的方法吗?我怎样才能解决正在发生的事情以及为什么需要这么长时间?
仅供参考 - 我在使用RHEL的72GB四核服务器上使用RStudio服务器,所以我认为内存不是问题所在.sessionInfo如下:
> sessionInfo()
R version 2.14.1 (2011-12-22)
Platform: x86_64-redhat-linux-gnu (64-bit)
locale:
[1] LC_CTYPE=en_US.UTF-8 LC_NUMERIC=C
[3] LC_TIME=en_US.UTF-8 LC_COLLATE=en_US.UTF-8
[5] LC_MONETARY=en_US.UTF-8 LC_MESSAGES=en_US.UTF-8
[7] LC_PAPER=C LC_NAME=C
[9] LC_ADDRESS=C LC_TELEPHONE=C
[11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C
attached base packages:
[1] stats graphics grDevices utils datasets methods base
other attached packages:
[1] multicore_0.1-7 plyr_1.7.1 rjson_0.2.6
loaded via a namespace (and not attached):
[1] tools_2.14.1
>
Run Code Online (Sandbox Code Playgroud) 我期望cbind.xts并do.call(cbind.xts)以相似的经过时间执行.R2.11,R2.14也是如此.
对于R2.15.2和xts 0.8-8,do.call(cbind.xts,...)变体执行速度非常慢,这有效地破坏了我以前的代码.
正如Josh Ulrich在下面的评论中指出的那样,xts软件包维护者已经意识到了这个问题.与此同时,有一个方便的工作吗?
可重复的例子:
library(xts)
secs <- function (rows, from = as.character(Sys.time()), cols = 1, by = 1)
{
deltas <- seq(from = 0, by = by, length.out = rows)
nacol <- matrix(data = NA, ncol = cols, nrow = rows)
xts(x = nacol, order.by = strptime(from, format = "%Y-%m-%d %X") +
deltas)
}
n <- 20
d1 <- secs(rows=n*100,cols=n)
d2 <- secs(rows=n*100,cols=n)
system.time(cbind.xts(d1,d2))
Run Code Online (Sandbox Code Playgroud)
与
system.time(do.call(cbind.xts, list(d1,d2)))
Run Code Online (Sandbox Code Playgroud) 我很高兴使用这段代码:
z=lapply(filename_list, function(fname){
read.zoo(file=fname,header=TRUE,sep = ",",tz = "")
})
xts( do.call(rbind,z) )
Run Code Online (Sandbox Code Playgroud)
直到Dirty Data在一个文件的末尾出现:
Open High Low Close Volume
2011-09-20 21:00:00 1.370105 1.370105 1.370105 1.370105 1
Run Code Online (Sandbox Code Playgroud)
这是在下一个文件的开头:
Open High Low Close Volume
2011-09-20 21:00:00 1.370105 1.371045 1.369685 1.3702 2230
Run Code Online (Sandbox Code Playgroud)
所以rbind.zoo抱怨重复.
我不能使用像:
y <- x[ ! duplicated( index(x) ), ]
Run Code Online (Sandbox Code Playgroud)
因为它们在不同的动物园对象中,在列表中.我不能aggregate像这里建议的那样使用,因为它们是动物园对象的列表,而不是一个大的动物园对象.而且我无法得到一个重要的对象.第二十二条军规.
所以,当事情变得艰难时,强硬的黑客攻击一些for循环(原谅印刷品和停止,因为这还不是工作代码):
indexes <- do.call("c", unname(lapply(z, index)))
dups=duplicated(indexes)
if(any(dups)){
duplicate_timestamps=indexes[dups]
for(tix in 1:length(duplicate_timestamps)){
t=duplicate_timestamps[tix]
print("We have a duplicate:");print(t)
for(zix in 1:length(z)){
if(t %in% …Run Code Online (Sandbox Code Playgroud) 有没有更好的方法来实现以下代码:
slice.periods <- function (x, periods, ...)
{
if (!require("xts")) {
stop("Need 'xts'")
}
Reduce(rbind.xts, lapply(periods, function(t) x[t], ...))
}
Run Code Online (Sandbox Code Playgroud)
其中 x 是一个 xts 对象,periods 是一个可通过 xts 子集识别的可迭代宪章列表。示例用法:
j <- xts(rnorm(10e6),Sys.time()-(10e6:1))
v <- c("T10:00/T11:00", "T13:00/T15:00", "T20:30/T22:00")
system.time(slice.periods(j, v))
## result on my MacBook Air (1.8 GHz Intel Core i7; 4 GB 1333 MHz DDR3)
## user system elapsed
## 14.956 0.876 15.837
Run Code Online (Sandbox Code Playgroud)
有几个顾虑:
我看到一些帖子说,如果时间是 UTC,直接访问会有一些惊人的加速,请参阅以下帖子: data.table 时间子集 vs xts 时间子集
但是,我的应用程序需要使用夏令时的本地时区。这使得夏季和冬季之间的 UTC 小时转换不同,上述方法将不起作用。
我还考虑使用 data.table,因为我使用“rbindlist”替换 do.Call(rbind, …