【问题标题】:Optimize R loop优化 R 循环
【发布时间】:2017-06-01 22:24:34
【问题描述】:

我在 R 中编写了一个循环,我想让它运行得更快。任务是计算数据框(tibble)中time 列的增量值。问题是每个增量应该取自level 列的值(范围1-9)更大的前一行大于或等于当前行。我需要运行大约 10 亿行,而当前的性能远低于每秒 100 万行。所以我正在寻找至少一个数量级的加速。

代码如下:

ref <- as.numeric(rep(NA, 9)) # separate reference timestamp per level
timedelta <- function(level, time) {
  delta <- time - ref[level]
  ref[1:level] <<- time
  delta
}
mapply(timedelta, tl$level, tl$time)

我怎样才能让它跑得快?

(我在How to add flexible delta columns using dplyr? 上就 dplyr 提出了同样的问题,但我没有设法通过 dplyr 获得所需的性能,所以我在这里再次询问。)

【问题讨论】:

  • 我不完全明白你需要做什么,但在迭代取决于前一次迭代的结果的情况下,我会尝试 Rcpp
  • 您是否尝试过分析代码以查看瓶颈在哪里?
  • 对于大型数据集,您可以尝试结合使用 data.table(比 dplyr 快)和 foreach(允许您并行运行循环)。如果您发布可重现的示例,您将在这里获得更好的结果:stackoverflow.com/questions/5963269/…

标签: r


【解决方案1】:

我不确定我是否完全理解您对给出的代码所做的事情,但最好的办法是删除显式循环。像这样的:

tl$delta <- tl$time - ref[tl$level]
ref[1:tl$level] <- tl$time

然后总结您的增量或您需要的任何操作。 R 不能很好地处理循环。它喜欢像数据框这样的大矩阵。我再举一个例子。假设我想计算我的数据框中的哪些客户每天都住在我的酒店,考虑到他们的到达和离开。我可以这样写一个循环:

days<-seq(as.Date("2016-01-01"), as.Date("2016-12-31"), by="days")
num_guests<-rep(0, length(days))
for(d in c(1:length(num_guests))){
   for(i in c(1:nrow(guests.df))){
      if(guests.df$Arrive_Date[i]<=days[d] &  guests.df$Leave_Date[i]>=days[d] ){
  num_guests[d]=num_guests[d]+1
 }
 }
}

这个循环策略需要 13 分钟才能在我的数据框中有 6700 个客人的 i7 处理器上运行。或者我可以把它改成这样:

for(d in c(1:length(num_guests))){
  guests.df$in_period<-guests.df$Arrive_Date<=days[d] & guests.df$Leave_Date>=days[d] 
  num_guests[d]<-sum(guests.df$in_period)
}

第二个循环运行一秒钟。

【讨论】:

    猜你喜欢
    • 2016-12-07
    • 2012-07-02
    • 2021-07-28
    • 2017-09-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-09
    • 1970-01-01
    相关资源
    最近更新 更多