【问题标题】:R for-loop iterating from central value out to extremesR for循环从中心值迭代到极端值
【发布时间】:2016-08-01 11:46:13
【问题描述】:

我正在尝试提高我的代码的速度,它正在尝试使用 3 个具有大范围的变量来优化一个值。最可能的输出使用范围中间的值,因此从每个变量的最低可能值开始是在浪费时间。我想从中间值开始迭代出来!实际问题有数千行,数字从 150 到 650。 C、H 和 O 限制将在一定程度上基于起始数字来定义,但总是更有可能在定义范围内的中心值处。有没有办法定义 for 循环像我想要的那样向外工作?我能想到的唯一非常简陋的方法是简单地从向量重新定义循环内的值(例如 1=20、2=21、3=19 等)。请参阅下面的当前代码:

set_error<-2.5
ct<-c(325.00214,325.00952,325.02004,325.02762,325.03535,325.03831,325.04588, 325.05641,325.06402,325.06766,325.07167,325.07454,325.10396)


FormFun<-function(x){
    for(C in 1:40){
      for(H in 1:80){
        for(O in 1:40){
        test_mass=C*12+H*1.007825+O*15.9949146-1.0072765

        error<-1000000*abs(test_mass-x)/x

        if(error<set_error){
          result<-paste("C",C,"H",H,"O",O,sep ="")
          return(result)
          break;break;break;break
        }
        }
        }
        }
}

old_t <- Sys.time()
ct2<-lapply(ct,FormFun)
new_t <- Sys.time() - old_t # calculate difference
print(new_t)

【问题讨论】:

    标签: r performance for-loop


    【解决方案1】:

    使用矢量化并创建closure

    FormFun1_fac <- function(gr) {
      gr <<- gr
      function(x, set_error){
      test_mass <- with(gr, C*12+H*1.007825+O*15.9949146-1.0072765)
      error <- 1000000 * abs(test_mass - x) / x
      ind <- which(error < set_error)[1]
      if (is.na(ind))  return(NULL)
      paste0("C", gr[ind, "C"],"H", gr[ind, "H"],"O", gr[ind, "O"])
      }
    }
    FormFun1 <- FormFun1_fac(expand.grid(C = 1:40, H = 1:80, O = 1:40))
    
    ct21 <- lapply(ct, FormFun1, set_error = set_error)
    all.equal(ct2, ct21)
    #[1] TRUE
    

    这会在函数环境中保存 C、H、O 的所有组合的网格,并计算所有组合的误差(这在矢量化代码中很快)。返回第一个通过测试的组合。

    【讨论】:

    • Roland,我遇到过 gr 网格中不止一行出现错误的情况
    • 改为ind &lt;- which(error &lt; set_error),即省略[1]
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-12-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-23
    • 1970-01-01
    • 2020-02-20
    相关资源
    最近更新 更多