首页 > 解决方案 > 提高 R 中循环的效率

问题描述

我一直在研究 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 中运行它?任何帮助将不胜感激!

标签: rperformancefor-loopcoding-efficiency

解决方案


如所写, SDCalculate 不返回任何结果,最后一行应该是dataor sd_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)
}

推荐阅读