Estoy intentando merge
varios data.frames
en un data.frame
. Como tengo una lista completa de archivos, bash hacerlo con una estructura de bucle.
Hasta ahora, el enfoque de bucle funciona bien. Sin embargo, parece bastante ineficiente y me pregunto si hay un enfoque más rápido y más fácil.
Aquí está el escenario: Tengo un directorio con varios archivos .csv
. Cada archivo contiene el mismo identificador que puede usarse como la variable de fusión. Como los archivos son de un tamaño bastante grande, pensé leer cada archivo uno a la vez en R en lugar de leer todos los archivos a la vez. Así que obtengo todos los archivos del directorio con list.files
y leo los primeros dos archivos. Luego utilizo merge
para obtener un data.frame
.
FileNames <- list.files(path=".../tempDataFolder/") FirstFile <- read.csv(file=paste(".../tempDataFolder/", FileNames[1], sep=""), header=T, na.strings="NULL") SecondFile <- read.csv(file=paste(".../tempDataFolder/", FileNames[2], sep=""), header=T, na.strings="NULL") dataMerge <- merge(FirstFile, SecondFile, by=c("COUNTRYNAME", "COUNTRYCODE", "Year"), all=T)
Ahora uso un ciclo for
para obtener todos los archivos .csv
restantes y merge
en el data.frame
ya existente:
for(i in 3:length(FileNames)){ ReadInMerge <- read.csv(file=paste(".../tempDataFolder/", FileNames[i], sep=""), header=T, na.strings="NULL") dataMerge <- merge(dataMerge, ReadInMerge, by=c("COUNTRYNAME", "COUNTRYCODE", "Year"), all=T) }
Aunque funciona bien, me preguntaba si existe una forma más elegante de hacer el trabajo.
Es posible que desee ver la pregunta estrechamente relacionada en stackoverflow .
Me acercaría a esto en dos pasos: importar todos los datos (con plyr
), luego plyr
:
filenames <- list.files(path=".../tempDataFolder/", full.names=TRUE) library(plyr) import.list <- llply(filenames, read.csv)
Eso le dará una lista de todos los archivos que ahora necesita fusionar. Hay muchas formas de hacerlo, pero este es un enfoque (con Reduce
):
data <- Reduce(function(x, y) merge(x, y, all=T, by=c("COUNTRYNAME", "COUNTRYCODE", "Year")), import.list, accumulate=F)
Alternativamente, puede hacer esto con el paquete de reshape
si no se siente cómodo con Reduce
:
library(reshape) data <- merge_recurse(import.list)
Si no me equivoco, un cambio bastante simple podría eliminar el 3:length(FileNames)
kludge:
FileNames <- list.files(path=".../tempDataFolder/", full.names=TRUE) dataMerge <- data.frame() for(f in FileNames){ ReadInMerge <- read.csv(file=f, header=T, na.strings="NULL") dataMerge <- merge(dataMerge, ReadInMerge, by=c("COUNTRYNAME", "COUNTRYCODE", "Year"), all=T) }