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)
Обратите внимание, что, поскольку вы не предоставили пример данных, я не смог проверить это.