Повышение эффективности l oop в R - PullRequest
0 голосов
/ 11 июля 2020

Я работал над кодом в R, который вычисляет стандартное отклонение (SD) по моим данным. Я сделал это как al oop, где он смотрит на 1-ю и 2-ю строки, вычисляет SD для каждого столбца в этой строке, а затем суммирует SD. Затем он повторяет следующий просмотр строк 1, 2 и 3, затем строк с 1 по 4 и т. Д. c.

Он отлично работает с моим тестовым набором данных, который содержит 19 строк и 128 столбцов, однако мой фактический набор данных насчитывает около 340000 строк и 128 столбцов. Когда я запускаю этот код, он не может достичь конца, замедляясь примерно на отметке 100000, я думаю, с тех пор, как я добавил функцию печати, чтобы показать мне, какой l oop он включен.

Вот код:

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? Любая помощь будет принята с благодарностью!

1 Ответ

0 голосов
/ 11 июля 2020

Как написано, SDCalculate не возвращает никакого результата, последняя строка должна быть data или sd_totals. Если у вас 340000 строк и 128 столбцов, внутренний l oop будет выполнен более 43 миллионов раз. Первый l oop выбирает матрицу данных, добавляя следующую строку, затем для новой матрицы вы вычисляете sd по столбцу, а затем biuld матрицу из одного столбца с помощью rbind, но затем вы получаете сумму sd. Так почему бы просто не суммировать SD в пределах l oop.

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)
}

Другой вариант, я не пробовал производительность, без внутреннего l oop для

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)
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...