Estoy haciendo un análisis relativamente simple que he puesto en una función, en todos los archivos de una carpeta en particular. Me preguntaba si alguien tenía algún consejo que me ayude a automatizar el proceso en varias carpetas diferentes.
- En primer lugar, me preguntaba si había alguna forma de leer todos los archivos de una carpeta en particular directamente en R. Creo que el siguiente comando enumerará todos los archivos:
files <- (Sys.glob("*.csv"))
... que encontré en Usando R para enumerar todos los archivos con una extensión específica
Y luego el siguiente código lee todos esos archivos en R.
listOfFiles <- lapply(files, function(x) read.table(x, header = FALSE))
... de Manipular varios archivos en R
Pero los archivos parecen leerse como una lista continua y no como archivos individuales ... ¿cómo puedo cambiar el script para abrir todos los archivos csv en una carpeta en particular como marcos de datos individuales?
En segundo lugar, suponiendo que pueda leer todos los archivos por separado, ¿cómo puedo completar una función en todos estos marcos de datos de una sola vez? Por ejemplo, he creado cuatro pequeños marcos de datos para poder ilustrar lo que quiero:
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)))
También he creado una función de ejemplo:
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)}
Normalmente, usaría el siguiente comando para aplicar la función a cada marco de datos individual.
Df1.summary <-Summary (archivo df)
¿Hay alguna manera en lugar de aplicar la función a todos los marcos de datos y usar los títulos de los marcos de datos en las tablas de resumen (es decir, Df1.summary)?
Muchas gracias,
Katie
plyr::llply
(oldply
) en lugar delapply
conservar los nombres en todo momento, y definir mi propia función de resumen, por ejemploplyr::each(min, max, mean, sd, median)
plyr
sugerencia.summary
con cualquier función suya, siempre que tome un data.frame como argumento (y / o parámetros opcionales que sean constantes en los DF de diferencia). Por ejemplo,lapply(ldf, function(x) apply(x, 2, function(x) c(mean(x), sd(x))))
devolvería la media y la DE calculadas en sentido contrario.generalmente no uso el bucle for en R, pero aquí está mi solución usando bucles for y dos paquetes: plyr y dostats
plyr está en cran y puede descargar dostats en https://github.com/halpo/dostats (puede estar usando install_github del paquete Hadley devtools )
Suponiendo que tengo sus dos primeros data.frame (Df.1 y Df.2) en archivos csv, puede hacer algo como esto.
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)) }
Aquí está la salida
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
fuente
plyr
solución es bastante buena!Aquí hay una
tidyverse
opción que puede no ser la más elegante, pero ofrece cierta flexibilidad en términos de lo que se incluye en el resumen: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
fuente
read_csv()
no funcionaba correctamente, así que lo reemplacé condata.table::fread()
.