R версия 3.5.0 Windows For Loop читает CSV не читает файл правильно

У меня есть папка (specdata) с кучей CSV-файлов. Когда я запускаю свою функцию для чтения отдельных файлов, у меня нет проблем. но когда я добавляю цикл For, чтобы функция могла принимать имена файлов функций (1:10), она не распознает, что существует 10 файлов.

pollutantmean <- function(directory = "specdata", pollutant = "sulfate", id = 
"001") {
pollutantcount <- 0
pollutantsum <- 0

filetype <- ".csv"
pathswitch <- "."


file_len <- nchar(id)
if (file_len == 1) {
new_id <- paste("00", id, filetype, sep = "")}
else if (file_len == 2) {
new_id <- paste("0", id, filetype, sep = "")}
else
new_id <- paste(id, filetype, sep = "")
new_path <-  file.path(pathswitch,directory, new_id)
new_data <- read.csv(new_path)
pollutantsum <- pollutantsum + sum(new_data[,pollutant], na.rm=TRUE)
pollutantcount <- pollutantcount + length(na.exclude(new_data[,pollutant])) 
meanofpollutant <- (pollutantsum / pollutantcount) 
print(meanofpollutant)

}

Я должен указать, что код написан выше, чтобы распознать, если идентификатор файла 001.csv введен в arg как 1 или 01, он напишет правильное имя файла для чтения.

Я искал несколько часов, но не могу найти пример, где я понимаю, как цикл For четко читает имена файлов CSV. Если бы кто-то мог предложить редактирование, я был бы благодарен. Спасибо!

1 ответ

Решение

Вот решение с использованием for петля.

files <- list.files(path = "specdata", pattern = ".csv$")
# Since you build this up you first need a starting value
pollutantsum <- 0
pollutantcount <- 0
# Use the files argument as the 'seq' argument
for (file in files) {
  new_data <- read.csv(file)
  pollutantsum <- pollutantsum + sum(new_data[,pollutant], na.rm=TRUE)
  pollutantcount <- pollutantcount + length(na.exclude(new_data[,pollutant])) 
  meanofpollutant <- (pollutantsum / pollutantcount)
}

Это классический пример неэффективного for цикл, хотя вы медленно наращиваете количество загрязнителей и количество загрязнителей, заставляя R перемещаться по данным на каждой итерации цикла.

Более эффективным способом было бы использовать lapply() читать файлы, а затем выполнять операции над объектом списка. Это было бы примерно, как бы вы достигли этого:

files <- list.files(path = "specdata", pattern = ".csv$")
files.list <- lapply(files, read.csv)
pollutantsum <- sum(sapply(files.list, function(x) sum(x[, pollutant], na.rm = TRUE)))
pollutantsum <- sum(sapply(files.list, function(x) length(na.exclude(x[,pollutant]))))
meanofpollutant <- (pollutantsum / pollutantcount)

Обратите внимание, что, поскольку вы не предоставили пример данных, я не смог проверить это.

Другие вопросы по тегам