我有以下有点大的数据集:
> dim(dset)
[1] 422105 25
> class(dset)
[1] "data.frame"
>
没有做任何事情,R进程似乎需要大约1GB的RAM。
我正在尝试运行以下代码:
dset <- ddply(dset, .(tic), transform,
date.min <- min(date),
date.max <- max(date),
daterange <- max(date) - min(date),
.parallel = TRUE)
运行该代码,RAM使用量猛增。它完全饱和了60GB的RAM,运行在32核机器上。我做错了什么?
答案 0 :(得分:12)
如果性能有问题,最好切换到使用同名包中的data.table
s。他们快。你会做一些大致相同的事情:
library(data.table)
dat <- data.frame(x = runif(100),
dt = seq.Date(as.Date('2010-01-01'),as.Date('2011-01-01'),length.out = 100),
grp = rep(letters[1:4],each = 25))
dt <- as.data.table(dat)
key(dt) <- "grp"
dt[,mutate(.SD,date.min = min(dt),
date.max = max(dt),
daterange = max(dt) - min(dt)), by = grp]
答案 1 :(得分:10)
这是data.table
对问题的另一种应用,说明它是多么快速。 (注意:这使用dset
,由Brian Diggs在他的答案中构建的data.frame
,除了30000而不是10 tic
级别。
(这比@joran解决方案要快得多的原因是它避免使用.SD
,而是直接使用列。样式与plyr
略有不同,但它通常会购买另一个例子,请参阅data.table
Wiki,其中:(a)包含此建议#1;以及(b)显示放弃.SD
的代码的50倍加速。
library(data.table)
system.time({
dt <- data.table(dset, key="tic")
# Summarize by groups and store results in a summary data.table
sumdt <- dt[ ,list(min.date=min(date), max.date=max(date)), by="tic"]
sumdt[, daterange:= max.date-min.date]
# Merge the summary data.table back into dt, based on key
dt <- dt[sumdt]
})
# ELAPSED TIME IN SECONDS
# user system elapsed
# 1.45 0.25 1.77
答案 2 :(得分:4)
有些事情会浮现在脑海中。
首先,我会把它写成:
dset <- ddply(dset, .(tic), summarise,
date.min = min(date),
date.max = max(date),
daterange = max(date) - min(date),
.parallel = TRUE)
嗯,实际上,我可能会避免重复计算最小/最大日期并写入
dset <- ddply(dset, .(tic), function(DF) {
mutate(summarise(DF, date.min = min(date),
date.max = max(date)),
daterange = date.max - date.min)},
.parallel = TRUE)
但这不是你要问的主要观点。
使用维度的虚拟数据集
n <- 422105
dset <- data.frame(date=as.Date("2000-01-01")+sample(3650, n, replace=TRUE),
tic = factor(sample(10, n, replace=TRUE)))
for (i in 3:25) {
dset[i] <- rnorm(n)
}
这在我的笔记本电脑上舒适地(低于1分钟)。事实上,plyr
步骤比创建虚拟数据集花费的时间更少。所以它不可能交换到你看到的大小。
第二种可能性是tic
的大量唯一值。这可能会增加所需的尺寸。但是,当我尝试将可能的唯一tic
值的数量增加到1000时,它并没有真正放慢速度。
最后,它可能是并行化中的一些东西。我没有为foreach
注册的并行后端,所以它只是采用串行方法。也许这会导致你的记忆爆炸。
答案 3 :(得分:1)
数据框中有多少个因子级别?我发现这种类型的过多内存使用在adply和可能的其他plyr函数中很常见,但可以通过删除不必要的因素和级别来解决。如果将大数据帧读入R,请确保在导入中将stringsAsFactors设置为FALSE:
dat = read.csv(header=TRUE, sep="\t", file="dat.tsv", stringsAsFactors=FALSE)
然后分配您实际需要的因素。
我还没有关注哈德利的来源,也没有发现原因。