【问题标题】:Optimizing for loop in R在 R 中优化 for 循环
【发布时间】:2016-06-10 00:04:18
【问题描述】:

我一直在做很多研究,但我认为在 R 中的嵌套 for 循环方面我遗漏了一些东西。我有两个数据框 - 一个包含观察结果和我想要编写输出的位置,另一个包含我正在循环的变量名。现在循环可以工作,但循环 200 行需要 14 多个小时,这似乎有点过分。当然,我在每行执行 12 次单独的排列(100 次),但理想情况下我希望进行 >1000 次以上的排列。有没有更有效的方法来执行这个 for 循环?当我进行一次观察时,它只需要很少的时间(不到 2 秒)就可以完成,这让我不禁要问,应该有更好的方法来完成这项任务。非常感谢您在优化此代码方面提供的任何帮助!谢谢!

附加了主数据集(fbfm.xlsx),称为 fm.std https://www.dropbox.com/s/vmd8d05yxds93j6/fbfm.xlsx?dl=0

library(rothermel)
u.val<-c(5,10,15,25,35,45,55,65,75,85,95,100)
unames <- data.frame(u=u.val,ros.nam=paste("u",u.val,"_ROS",sep=""), stringsAsFactors = FALSE)
ros.out<-data.frame(fm.std)
for (i in 1:dim(unames)[1]){
     ros.out[,unames[i,'ros.nam']]<-999
          }
ros.out <- as.vector(ros.out)
fm.std <- as.vector(fm.std)
for (i in 1:dim(ros.out)[1]){
   ros.out[i,1:32]
     for (u in 1:dim(unames)[1]){
         ros.out[i,unames[u,'ros.nam']]<-mean(rosunc(modeltype=fm.std[i,'Fuel_Model_Type'], #Dyanmic or static model
                                            w=fm.std[i,4:8], # fuel loads (1, 10, 100, herb, and shrub)
                                            s=fm.std[i,9:13], # SAV measurements
                                            delta=fm.std[i,14], #fuel bed depth
                                            mx.dead=fm.std[i,15], # dead fuel mositure of extinction
                                            h=fm.std[i,16:20], # heat content for fuel classes
                                            m=fm.std[i,c(25,24,23,26,30)], #percent moisture of fuel classes
                                            u = unames[u,'u'],
                                            slope=0,
                                            sdm=0.3,
                                            nsim=100) ) #wind and slope of 0 }}

【问题讨论】:

  • 如果您有想要改进的工作代码,那么您应该在 Code Review 而不是 StackOverflow 上发布问题codereview.stackexchange.com
  • 嗨,Hack-R,谢谢,我会在那里发帖

标签: r loops nested


【解决方案1】:

考虑一个更矢量化的sapply() 方法,传入两个向量u.val1:nrow(fm.std)。这将构建一个 200 行 12 列的矩阵,您可以将其转换为数据帧,然后将 cbind 转换为原始数据帧。

ucols <- sapply(u.val, 
                function(x, y){
                   mean(rosunc(modeltype=fm.std[y,'Fuel_Model_Type'],  # Dyanmic or static model
                               w=fm.std[y,4:8],       # fuel loads (1, 10, 100, herb, and shrub)
                               s=fm.std[y,9:13],      # SAV measurements
                               delta=fm.std[y,14],    # fuel bed depth
                               mx.dead=fm.std[y,15],  # dead fuel mositure of extinction
                               h=fm.std[y,16:20],     # heat content for fuel classes
                               m=fm.std[y,c(25,24,23,26,30)],     # percent moisture of fuel classes
                               u=x,
                               slope=0,
                               sdm=0.3,
                               nsim=100))
                }, 1:nrow(fm.std))

# CONVERT MATRIX TO DATA FRAME
ucols <- data.frame(ucols)
# RENAME COLUMNS
names(test) <- paste("u",u.val,"_ROS",sep="")

# BIND COLUMNS TO ORIGINAL DATA FRAME
ros.out <- cbind(fm.std, ucols)

或者,考虑使用带有转置的outer() t() 来实现 200 行和 12 列的矩阵。

ucols <- t(outer(u.val, 1:nrow(fm.std), 
                    function(x, y){
                         mean(rosunc(...))
                    }
           ))
...

【讨论】:

  • 像魅力一样工作!谢谢,这是我过去几天一直在寻找的解决方案。非常感谢!
  • 太棒了!对包裹不太熟悉,但很高兴它有效并且我可以提供帮助。当谈到 R:矢量化你的代码时,你可能已经听说过它或者它会听到它!
猜你喜欢
  • 2017-09-20
  • 1970-01-01
  • 2021-04-23
  • 2017-09-26
  • 2018-04-06
  • 2018-11-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多