【问题标题】:Improve efficiency of loop in R提高 R 中循环的效率
【发布时间】:2020-07-11 14:09:39
【问题描述】:

我一直在编写 R 中的代码,用于计算我的数据的标准偏差 (SD)。我将它作为一个循环来完成,它查看第一行和第二行,计算该行中每一列的 SD,然后总计 SD。然后它重复下一次查看第 1、2 和 3 行,然后是第 1 到 4 行等。

它在包含 19 行和 128 列的测试数据集上运行良好,但我的实际数据集大约有 340,000 行和 128 列。当我运行此代码时,它无法到达终点,在大约 100,000 标记处减速,我想从我添加打印功能来显示它在哪个循环上。

代码如下:

site <- read.csv("data.csv", header = TRUE)

SDCalculate <- function(data){
  
  sd_totals <- data.frame(SD=0)
  
  for(i in 2:nrow(data)){
    
    sd_values <- data.frame()
    
    cat(i,"\n")
    
    for (j in 4:ncol(data)){
      
      list <- c(data[1:i,j])
      
      sd_values <- rbind(sd_values, sd(list))
      
    }
    
    sd_totals <-rbind(sd_totals, sum(sd_values))
    
  }
  
  data <- sd_totals
}


results<- SDCalculate(site)

我想知道是否有任何方法可以提高我的代码的效率以使其正常工作?还是值得在 Python 中运行它?任何帮助将不胜感激!

【问题讨论】:

  • 不要增长向量。预先分配它们然后填写它们。即sd_totals &lt;-rbind(sd_totals, sum(sd_values)) 不好。在循环之外,执行sd_totals &lt;- numeric(sizeOfFinalResults),然后执行sd_totals[currentIteration] &lt;- sum(sd_values)。也与您的其他载体。当您使用rbind 和类似的方式生成向量时,您将在循环的每一轮中复制这些向量。随着矢量大小的增加,这会变得昂贵。
  • 如果i 的打印速度会减慢您的速度,也许每1000 个i 左右打印一次。对于并行化,您可以查看支持for 循环的foreach 包,如并行化。
  • 这有帮助吗? stackoverflow.com/questions/2765374/… 基本上是您计算累积标准偏差,但内存效率非常低。您可以使用链接中的功能,然后发送as.matrix(data[, 4:length(data)]) 以更快地获得结果。
  • @Cole 非常感谢,链接的问题正是我想要的!

标签: r performance for-loop coding-efficiency


【解决方案1】:

正如所写,SDCalculate 不返回任何结果,最后一行应该是datasd_totals。如果您有 340000 行和 128 列,则内部循环将执行超过 43 万次。第一个循环选择一个添加下一行的数据矩阵,然后对于新矩阵,您按列计算sd,然后使用 rbind 构建一个单列矩阵,然后您得到 sd 的总和。那么为什么不在循环中对 sd 求和呢。

SDCalculate2 <- function(data){
  
  SD <- 0 # do not need data.frame(SD=0)
  
  for(i in 2:nrow(data)){
  
    sd_sum <- 0 # do not need a data frame sd_values

    for (j in 4:ncol(data)){
      sd_sum <- sd_sum + sd(data[1:i,j])
    }
    # do not need rbind
    SD[i] <- sd_sum
  }

  # output 
  as.data.frame(SD)
}

另一种选择,我没有尝试性能,没有内循环

SDCalculate3 <- function(data){
  SD <- 0
  for(i in 2:nrow(data)){
    SD[i] <- sum(apply(data[1:i,4:ncol(data)],2,sd))
  }
  data.frame(SD)
}

【讨论】:

    猜你喜欢
    • 2015-10-08
    • 2019-11-06
    • 1970-01-01
    • 2018-04-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-05
    相关资源
    最近更新 更多