Я провожу относительно простой анализ, который я ввел в функцию, для всех файлов в определенной папке. Мне было интересно, есть ли у кого-нибудь советы, которые помогут мне автоматизировать процесс для ряда разных папок.
- Во-первых, мне было интересно, есть ли способ прочитать все файлы в определенной папке прямо в R. Я считаю, что следующая команда выведет список всех файлов:
files <- (Sys.glob("*.csv"))
... который я нашел из Использование R для вывода списка всех файлов с указанным расширением
А затем следующий код считывает все эти файлы в R.
listOfFiles <- lapply(files, function(x) read.table(x, header = FALSE))
… Из " Управление несколькими файлами в R"
Но кажется, что файлы читаются как один непрерывный список, а не как отдельные файлы ... как я могу изменить сценарий, чтобы открыть все файлы csv в определенной папке как отдельные фреймы данных?
Во-вторых, если предположить, что я могу читать все файлы по отдельности, как мне выполнить функцию на всех этих фреймах данных за один раз. Например, я создал четыре небольших фрейма данных, чтобы проиллюстрировать то, что я хочу:
Df.1 <- data.frame(A = c(5,4,7,6,8,4),B = (c(1,5,2,4,9,1))) Df.2 <- data.frame(A = c(1:6),B = (c(2,3,4,5,1,1))) Df.3 <- data.frame(A = c(4,6,8,0,1,11),B = (c(7,6,5,9,1,15))) Df.4 <- data.frame(A = c(4,2,6,8,1,0),B = (c(3,1,9,11,2,16)))
Я также составил пример функции:
Summary<-function(dfile){
SumA<-sum(dfile$A)
MinA<-min(dfile$A)
MeanA<-mean(dfile$A)
MedianA<-median(dfile$A)
MaxA<-max(dfile$A)
sumB<-sum(dfile$B)
MinB<-min(dfile$B)
MeanB<-mean(dfile$B)
MedianB<-median(dfile$B)
MaxB<-max(dfile$B)
Sum<-c(sumA,sumB)
Min<-c(MinA,MinB)
Mean<-c(MeanA,MeanB)
Median<-c(MedianA,MedianB)
Max<-c(MaxA,MaxB)
rm(sumA,sumB,MinA,MinB,MeanA,MeanB,MedianA,MedianB,MaxA,MaxB)
Label<-c("A","B")
dfile_summary<-data.frame(Label,Sum,Min,Mean,Median,Max)
return(dfile_summary)}
Обычно я бы использовал следующую команду для применения функции к каждому индивидуальному фрейму данных.
Df1.summary <-Summary (dfile)
Есть ли способ вместо применения функции ко всем фреймам данных и использования заголовков фреймов данных в сводных таблицах (например, Df1.summary).
Большое спасибо,
Кэти
plyr::llply
(илиldply
) вместо того,lapply
чтобы сохранить имена повсюду, и определить свою собственную итоговую функцию, напримерplyr::each(min, max, mean, sd, median)
plyr
предложение.summary
любую свою функцию, при условии, что она принимает data.frame в качестве аргумента (и / или необязательные параметры, которые постоянны в разных DF). Например,lapply(ldf, function(x) apply(x, 2, function(x) c(mean(x), sd(x))))
вернет среднее значение и стандартное отклонение, вычисленное по очереди.обычно я не использую цикл for в R, но вот мое решение, использующее циклы for и два пакета: plyr и dostats
plyr находится на кране, и вы можете загрузить dostats на https://github.com/halpo/dostats (может использоваться install_github из пакета Hadley devtools )
Предполагая, что у меня есть ваши первые два data.frame (Df.1 и Df.2) в файлах csv, вы можете сделать что-то вроде этого.
require(plyr) require(dostats) files <- list.files(pattern = ".csv") for (i in seq_along(files)) { assign(paste("Df", i, sep = "."), read.csv(files[i])) assign(paste(paste("Df", i, sep = ""), "summary", sep = "."), ldply(get(paste("Df", i, sep = ".")), dostats, sum, min, mean, median, max)) }
Вот результат
R> Df1.summary .id sum min mean median max 1 A 34 4 5.6667 5.5 8 2 B 22 1 3.6667 3.0 9 R> Df2.summary .id sum min mean median max 1 A 21 1 3.5000 3.5 6 2 B 16 1 2.6667 2.5 5
источник
plyr
решение очень хорошее!Вот
tidyverse
вариант, который может быть не самым элегантным, но предлагает некоторую гибкость с точки зрения того, что включено в резюме:library(tidyverse) dir_path <- '~/path/to/data/directory/' file_pattern <- 'Df\\.[0-9]\\.csv' # regex pattern to match the file name format read_dir <- function(dir_path, file_name){ read_csv(paste0(dir_path, file_name)) %>% mutate(file_name = file_name) %>% # add the file name as a column gather(variable, value, A:B) %>% # convert the data from wide to long group_by(file_name, variable) %>% summarize(sum = sum(value, na.rm = TRUE), min = min(value, na.rm = TRUE), mean = mean(value, na.rm = TRUE), median = median(value, na.rm = TRUE), max = max(value, na.rm = TRUE)) } df_summary <- list.files(dir_path, pattern = file_pattern) %>% map_df(~ read_dir(dir_path, .)) df_summary # A tibble: 8 x 7 # Groups: file_name [?] file_name variable sum min mean median max <chr> <chr> <int> <dbl> <dbl> <dbl> <dbl> 1 Df.1.csv A 34 4 5.67 5.5 8 2 Df.1.csv B 22 1 3.67 3 9 3 Df.2.csv A 21 1 3.5 3.5 6 4 Df.2.csv B 16 1 2.67 2.5 5 5 Df.3.csv A 30 0 5 5 11 6 Df.3.csv B 43 1 7.17 6.5 15 7 Df.4.csv A 21 0 3.5 3 8 8 Df.4.csv B 42 1 7 6 16
источник
read_csv()
не работал должным образом, я заменил его наdata.table::fread()
.