首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何加快R循环的速度?

如何加快R循环的速度?
EN

Stack Overflow用户
提问于 2015-08-22 14:53:00
回答 2查看 408关注 0票数 4

我正在为R中的gwr.basic包中的GWmodel函数运行下面的for循环,我需要做的是收集任何给定带宽的估计参数的平均值。

代码看起来像:

代码语言:javascript
复制
library(GWmodel)
data("DubVoter")
#Dub.voter


LARentMean = list()
for (i in 20:21)
{
gwr.res <- gwr.basic(GenEl2004 ~ DiffAdd + LARent + SC1 + Unempl + LowEduc + Age18_24 + Age25_44 + Age45_64, data = Dub.voter, bw = i,  kernel = "bisquare", adaptive = TRUE, F123.test = TRUE)
a <- mean(gwr.res$SDF$LARent)
LARentMean[i] <- a
}
outcome = unlist(LARentMean)

> outcome
[1] -0.1117668 -0.1099969

然而,返回结果的速度非常慢。我需要一个更宽的范围,如20:200。有没有办法加快这一进程?如果不是,如何有一个步骤范围--比如说20到200步--5步来减少操作的数量?

我是一个刚接触R的python用户,所以我读到了R,因为R在for循环中速度慢,并且有更有效的替代方案。在这一点上更加明确是值得欢迎的。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-08-22 15:02:40

我有着和@musically_ut一样的印象。for循环和传统的for-vs.apply辩论在这里不太可能对您有所帮助。如果你有一个以上的核心,试着去并行化。有几个包,如parallelsnowfall。哪个包最终是最好的,最快的取决于您的机器和操作系统。

在这里,最好的东西并不总是最快的。一种跨平台工作的代码,它比额外的性能更有价值。此外,透明度和易用性可以超过最大速度。尽管如此,我非常喜欢标准解决方案,并建议使用parallel,它随R一起发布,并在Windows、OSX和Linux上工作。

编辑:下面是使用OP示例的完全可复制的示例。

代码语言:javascript
复制
library(GWmodel)
data("DubVoter")

library(parallel)

bwlist <- list(bw1 = 20, bw2 = 21)


cl <- makeCluster(detectCores())

# load 'GWmodel' for each node
clusterEvalQ(cl, library(GWmodel))

# export data to each node
clusterExport(cl, varlist = c("bwlist","Dub.voter"))

out <- parLapply(cl, bwlist, function(e){
 try(gwr.basic(GenEl2004 ~ DiffAdd + LARent + SC1 +
 Unempl + LowEduc + Age18_24 + Age25_44 +
 Age45_64, data = Dub.voter,
 bw = e,  kernel = "bisquare",
 adaptive = TRUE, F123.test = TRUE  ))

} )


LArent_l <- lapply(lapply(out,"[[","SDF"),"[[","LARent")
unlist(lapply(LArent_l,"mean"))

# finally, stop the cluster
stopCluster(cl)
票数 4
EN

Stack Overflow用户

发布于 2015-08-22 15:32:44

除了使用Matt建议的并行化之外,还应该预先分配向量LARentMean。通常,慢的并不是for循环本身,而是for诱使您做一些缓慢的事情,比如创建增长的向量。

考虑下面的示例,可以看到与预先分配内存相比,正在增长的向量的影响:

代码语言:javascript
复制
library(microbenchmark)

growing <- function(x) {
  mylist <- list()
  for (i in 1:x) {
    mylist[[i]] <- i
  }
}

allocate <- function(x) {
  mylist <- vector(mode = "list", length = x)
  for (i in 1:x) {
    mylist[[i]] <- i
  }
}

microbenchmark(growing(1000), allocate(1000), times = 1000)
# Unit: microseconds
#          expr      min       lq      mean   median       uq       max neval
# growing(1000) 3055.134 4284.202 4743.4874 4433.024 4655.616 47977.236  1000
# allocate(1000)  867.703  917.738  998.0719  956.441  995.143  2564.192  1000

增长列表比分配内存的版本慢5倍。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32157474

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档