【问题标题】:How Can I Avoid This For Loop? (R)我怎样才能避免这个for循环? (右)
【发布时间】:2016-02-09 22:37:59
【问题描述】:

我目前有一个如下的 for 循环,但它的运行速度没有我想要的那么快。

library(dplyr)

DF<-data.frame(Name=c('Bob','Joe','Sally')) #etc

PrimaryResult <- Function1(DF)
ResultsDF<-Function2(PrimaryResult)

for(i in 1:9) 
{
  Filtered<-filter(DF,Name!=PrimaryResult[i,2])
  NextResult <- Function1(Filtered)
  ResultsDF<-rbind(ResultsDF,Function2(NextResult))
   }

代码获取 Function1 的初始结果(名称列表)并再次尝试,初始结果中的每个名称都被单独排除以提供替代结果。这些通过 Function2 作为单行数据框返回并附加到结果数据框。

我怎样才能加快速度?

【问题讨论】:

  • for 循环几乎肯定不是慢的部分——可能是你的 Function2 慢。您应该首先profile your code 找出真正慢的地方并加以改进。

标签: r for-loop apply


【解决方案1】:

您的主要问题似乎是函数 2 每次迭代都使用rbind 附加结果。这通常很慢,因为您告诉R 在每个时间步重写一堆信息,而R 并不真正知道您最终会得到多大的向量。

试着将你的结果变成一个列表向量。我真的不知道你的功能是做什么的,所以我无法真正协助这部分。

results_list <- vector("list", 10)
results_list[[1]] <- Function2(PrimaryResult)

for(i in 1:9){
  Filtered<-filter(DF,Name!=PrimaryResult[i,2])
  NextResult <- Function1(Filtered)
  results_list[[i+1]]<-rbind(results_list[[i]],Function2(NextResult))
   }

这并不完美,但它应该会加快速度。

【讨论】:

  • OP 的例子是for(i in 1:9)。虽然使用 rbind 增长数据帧是不好的做法,但对 rbind 的 9 次调用不会产生明显的性能差异。即使这样,这个解决方案也不会在每一步都仍然 rbinds,所以唯一的区别是你保存了每个增量结果。要消除rbind,您应该从循环内部删除它,并在循环结束后使用results = do.call(rbind, results_list)` 或results = dplyr::bind_rows(results_list)
猜你喜欢
  • 2010-10-28
  • 2012-08-09
  • 2014-06-18
  • 1970-01-01
  • 2022-08-13
  • 2021-07-14
  • 2020-01-05
  • 1970-01-01
  • 2016-01-21
相关资源
最近更新 更多