我有一个df,YearHT,6.5M x 55列。有特定的信息,我想提取和添加,但只基于聚合值。我使用for循环对大型df进行子集,然后执行计算。
我听说过应该避免for循环,我想知道是否有一种方法可以避免使用for循环,因为当我运行这个查询时,它需要3小时。
这是我的代码:
srt=NULL
for(i in doubletCounts$Var1){
s=subset(YearHT,YearHT$berthlet==i)
e=unlist(c(strsplit(i,'\\|'),median(s$berthtime)))
srt=rbind(srt,e)
}
srt=data.frame(srt)
s2=data.frame(srt$X2,srt$X1,srt$X3)
colnames(s2)=colnames(srt)
s=rbind(srt,s2)doubletCounts为700x3df,每个值都在大df中找到。
我很高兴听到任何关于优化/加快这一进程的想法。
发布于 2016-05-06 12:52:06
这里有一个使用data.table的快速解决方案,尽管从您的问题中还不完全清楚您想要得到的output是什么。
# load library
library(datat.table)
# convert your dataset into data.table
setDT(YearHT)
# subset YearHT keeping values that are present in doubletCounts$Var1
YearHT_df <- YearHT[ berthlet %in% doubletCounts$Var1]
# aggregate values
output <- YearHT_df[ , .( median= median(berthtime)) ]发布于 2016-05-06 12:43:53
for循环并不一定要避免,但是有一些使用for循环的方法是应该避免的。您已经在这里提交了经典的for循环错误。
srt = NULL
for (i in index)
{
[stuff]
srt = rbind(srt, [stuff])
}肯定比您想要的要慢,因为每次您访问srt = rbind(...)时,您都要求R做各种各样的事情来确定srt需要的对象类型以及分配给它的内存。当您知道输出的长度需要提前时,最好是这样做
srt <- vector("list", length = doubletCounts$Var1)
for(i in doubletCounts$Var1){
s=subset(YearHT,YearHT$berthlet==i)
srt[[i]] = unlist(c(strsplit(i,'\\|'),median(s$berthtime)))
}
srt=data.frame(srt)的apply替代方案。
srt = lapply(doubletCounts$Var1,
function(i)
{
s=subset(YearHT,YearHT$berthlet==i)
unlist(c(strsplit(i,'\\|'),median(s$berthtime)))
}
)它们应该以相同的速度运行。
(注:由于缺乏数据,这两者都是未经测试的,因此它们可能有一点小问题)
您可以尝试的其他可能会产生较小效果的方法是放弃subset调用并使用索引。您的for循环的内容可以归结为
unlist(c(strsplit(i, '\\|'),
median(YearHT[YearHT$berthlet == i, "berthtime"])))但我不确定这能节省多少时间。
https://stackoverflow.com/questions/37072479
复制相似问题