Нужна помощь в преобразовании цикла в lapply или sapply - PullRequest
0 голосов
/ 05 октября 2019

Я работаю над R и учусь кодировать. Я написал фрагмент кода, используя цикл for, и я нахожу его очень медленным. Мне было интересно, смогу ли я получить некоторую помощь, чтобы преобразовать его в функцию sapply или lapply. Вот мой рабочий код R:

library(dplyr)
pollutantmean <- function(directory, pollutant, id = 1:332)   {
      files_list <- list.files(directory, full.names=TRUE)   #creates a list of files
      dat <- data.frame()                             #creates an empty data frame
      for (i in seq_along(files_list)) {
            #loops through the files, rbinding them together
            dat <- rbind(dat, read.csv(files_list[i]))
      }
      dat_subset <- filter(dat, dat$ID %in% id) #subsets the rows that match the 'ID' argument
      mean(dat_subset[, pollutant], na.rm=TRUE)      #identifies the Mean of a Pollutant
}

pollutantmean("specdata", "sulfate", 1:10)

Этот код возвращает почти 20 секунд, что недопустимо для 332 записей. Представьте себе, если у меня есть набор данных с 10K-записями и я хочу получить среднее значение этих переменных?

Ответы [ 2 ]

1 голос
/ 05 октября 2019

Вы можете rbind всех элементов в списке, используя do.call, и вы можете прочитать все файлы в этом списке, используя lapply:

mean(
  filter( # here's the filter that will be applied to the rbind-ed data
    do.call("rbind", # call "rbind" on all elements of a list 
            lapply( # create a list by reading in the files from list.files()
              # add any necessary args to read.csv:
              list.files("[::DIR_PATH::]"), function(x) read.csv(file=x, ...)
            ) 
    )
  ), ID %in% id)$pollutant, # make sure id is replaced with what you want
na.rm = TRUE
)
0 голосов
/ 05 октября 2019

Причина, по которой ваш код работает медленно, потому что вы постепенно увеличиваете свой фрейм данных в цикле. Один из способов сделать это с помощью dplyr и map_df из purrr может быть

library(dplyr)
pollutantmean <- function(directory, pollutant, id = 1:332)   {

    files_list <- list.files(directory, full.names=TRUE)  
    purrr::map_df(files_list, read.csv) %>%
                  filter(ID %in% id) %>%
                  summarise_at(pollutant, mean, na.rm = TRUE)

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...