Algo como lo siguiente debería dar como resultado que cada marco de datos sea un elemento separado en una sola lista:
temp = list.files(pattern="*.csv")
myfiles = lapply(temp, read.delim)
Esto supone que tiene esos CSV en un solo directorio, su directorio de trabajo actual, y que todos tienen la extensión en minúsculas .csv
.
Si luego desea combinar esos marcos de datos en un solo marco de datos, vea las soluciones en otras respuestas usando cosas como do.call(rbind,...)
, dplyr::bind_rows()
o data.table::rbindlist()
.
Si realmente desea que cada marco de datos esté en un objeto separado, aunque eso a menudo no es aconsejable, puede hacer lo siguiente con assign
:
temp = list.files(pattern="*.csv")
for (i in 1:length(temp)) assign(temp[i], read.csv(temp[i]))
O, sin assign
, y para demostrar (1) cómo se puede limpiar el nombre del archivo y (2) mostrar cómo usarlo list2env
, puede intentar lo siguiente:
temp = list.files(pattern="*.csv")
list2env(
lapply(setNames(temp, make.names(gsub("*.csv$", "", temp))),
read.csv), envir = .GlobalEnv)
Pero, de nuevo, a menudo es mejor dejarlos en una sola lista.
A5C1D2H2I1M1N2O1R2T1
fuente
assign
... Si desea que los valores asignados residan en el entorno global, asegúrese de configurarloinherits=T
.Una
tidyverse
solución rápida y sucinta : (más del doble de rápido que la Base Rread.csv
)y data.table 's
fread()
incluso pueden cortar los tiempos de carga por medio nuevo. (por 1/4 de la base R veces)El
stringsAsFactors = FALSE
argumento mantiene el factor de trama de datos libre (y como señala marbel, es la configuración predeterminada parafread
)Si la conversión de texto es descarada, puede forzar que todas las columnas sean caracteres con el
col_types
argumento.Si desea sumergirse en subdirectorios para construir su lista de archivos para eventualmente enlazar, entonces asegúrese de incluir el nombre de la ruta, así como registrar los archivos con sus nombres completos en su lista. Esto permitirá que el trabajo de enlace continúe fuera del directorio actual. (Pensando en los nombres de ruta completos como operando como pasaportes para permitir el movimiento de regreso a través de 'fronteras' del directorio)
Como Hadley describe aquí (aproximadamente a la mitad):
Función de bonificación : agregar nombres de archivo a los registros por solicitud de función de Niks en los comentarios a continuación:
* Agregar original
filename
a cada registro.Código explicado: realice una función para agregar el nombre de archivo a cada registro durante la lectura inicial de las tablas. Luego use esa función en lugar de la
read_csv()
función simple .(Los enfoques de conversión de tipos y manejo de subdirectorios también se pueden manejar dentro de la
read_plus()
función de la misma manera que se ilustra en la segunda y tercera variantes sugeridas anteriormente).Caso de uso medio
Caso de uso más grande
Variedad de casos de uso
Filas: recuentos de archivos (1000, 100, 10)
Columnas: tamaño final de trama de datos (5 MB, 50 MB, 500 MB)
(haga clic en la imagen para ver el tamaño original)
Los resultados básicos de R son mejores para los casos de uso más pequeños en los que la sobrecarga de llevar las bibliotecas C de purrr y dplyr supera las ganancias de rendimiento que se observan al realizar tareas de procesamiento a mayor escala.
Si desea ejecutar sus propias pruebas, puede encontrar útil este script bash.
bash what_you_name_this_script.sh "fileName_you_want_copied" 100
creará 100 copias de su archivo numeradas secuencialmente (después de los 8 caracteres iniciales del nombre de archivo y un guión bajo).Atribuciones y apreciaciones
Con especial agradecimiento a:
map_df()
aquí .fread()
. (Necesito estudiar másdata.table
).fuente
readAddFilename <- function(flnm) { read_csv(flnm) %>% mutate(filename = flnm) }
entonces, simplemente colóquelo en elmap_df
lugar de la lectura simpleread_csv()
que está allí ahora. Puedo actualizar la entrada anterior para mostrar la función y cómo encajaría en la tubería si todavía tiene preguntas o cree que será útil.read_csv
es mucho más lento quefread
. Incluiría un punto de referencia si va a decir que algo es más rápido. Una idea es crear 30 archivos de 1GB y leerlos, ese sería un caso en el que el rendimiento es importante.fread()
y dplyr ' sread_csv()
: 14,2 vs 19,9 segundos. TBH, solo había estado comparando la base R con dplyr y, comoread_csv()
es alrededor de 2-4 veces más rápido que elread.csv()
, el benchmarking no parecía necesario. Sin embargo, ha sido interesante darfread()
una vuelta y pausar para ver resultados de referencia más completos. ¡Gracias de nuevo!Estas son algunas opciones para convertir los archivos .csv en un marco de datos utilizando R base y algunos de los paquetes disponibles para leer archivos en R.
Esto es más lento que las opciones a continuación.
Editar: - Algunas opciones adicionales más usando
data.table
yreadr
Una
fread()
versión, que es una función deldata.table
paquete. Esto es, con mucho, la opción más rápida en I .Usando readr , que es otro paquete para leer archivos csv. Es más lento que
fread
, más rápido que la base R pero tiene diferentes funcionalidades.fuente
data.table
versión, que debería mejorar el rendimiento.do.call
Además de usar
lapply
o alguna otra construcción de bucle en R, podría fusionar sus archivos CSV en un solo archivo.En Unix, si los archivos no tienen encabezados, entonces es tan fácil como:
o si hay encabezados y puede encontrar una cadena que coincida con encabezados y solo encabezados (es decir, suponga que todas las líneas de encabezado comienzan con "Edad"), haría lo siguiente:
Creo que en Windows podría hacer esto con
COPY
ySEARCH
(oFIND
algo) desde el cuadro de comandos de DOS, pero ¿por qué no instalarcygwin
y obtener el poder del shell de comandos de Unix?fuente
Git
instalación?Este es el código que desarrollé para leer todos los archivos csv en R. Creará un marco de datos para cada archivo csv individualmente y titulará ese marco de datos con el nombre original del archivo (eliminando espacios y el .csv) ¡Espero que lo encuentre útil!
fuente
Las tres respuestas principales de @ A5C1D2H2I1M1N2O1R2T1, @leerssej y @marbel son esencialmente las mismas: aplique fread a cada archivo, luego rbind / rbindlist las tablas de datos resultantes. Usualmente uso el
rbindlist(lapply(list.files("*.csv"),fread))
formulario.Esto es mejor que otras alternativas internas R, y está bien para un pequeño número de csvs grandes, pero no es el mejor para un gran número de csvs pequeños cuando la velocidad es importante. En ese caso, puede ser mucho más rápido usarlo por primera vez
cat
, como sugiere @Spacedman en la respuesta del cuarto puesto. Agregaré algunos detalles sobre cómo hacer esto desde R:Sin embargo, ¿qué pasa si cada csv tiene un encabezado?
¿Y qué pasa si tienes tantos archivos que
*.csv
falla el shell glob?¿Y si todos los archivos tienen un encabezado Y hay demasiados archivos?
¿Y qué pasa si el csv concatenado resultante es demasiado grande para la memoria del sistema?
Con encabezados?
Finalmente, ¿qué sucede si no quiere todos los archivos .csv en un directorio, sino un conjunto específico de archivos? (Además, todos tienen encabezados). (Este es mi caso de uso).
y esto es más o menos la misma velocidad que fread xargs cat :)
Nota: para data.table anterior a v1.11.6 (19 de septiembre de 2018), omita el
cmd=
defread(cmd=
.Anexo: el uso de mclapply de la biblioteca paralela en lugar de lapply en serie, por ejemplo,
rbindlist(lapply(list.files("*.csv"),fread))
también es mucho más rápido que rbindlist lapply fread.Tiempo para leer 121401 csvs en una sola tabla de datos. Cada csv tiene 3 columnas, una fila de encabezado y, en promedio, 4.510 filas. La máquina es una VM GCP con 96 núcleos:
En resumen, si está interesado en la velocidad y tiene muchos archivos y muchos núcleos, fread xargs cat es aproximadamente 50 veces más rápido que la solución más rápida en las 3 respuestas principales.
fuente
En mi opinión, la mayoría de las otras respuestas están obsoletas
rio::import_list
, lo cual es un resumen breve:Cualquier argumento adicional se pasa a
rio::import
.rio
puede lidiar con casi cualquier formato de archivo que R pueda leer, y usadata.table
'sfread
donde sea posible, por lo que también debería ser rápido.fuente
El uso
plyr::ldply
allí es aproximadamente un aumento del 50% de velocidad al habilitar la.parallel
opción mientras se leen 400 archivos csv de aproximadamente 30-40 MB cada uno. El ejemplo incluye una barra de progreso de texto.fuente
fread
ouser-defined functions
? ¡Gracias!?ldply
muestra...
otros argumentos pasados a.fun
. Usar cualquierafread, skip = 100
ofunction(x) fread(x, skip = 100)
funcionaríafunction(x) fread(x, skip = 100)
no funcionó para mí, pero proporcionar argumentos adicionales después del nombre de la función descubierta hizo el truco. ¡Gracias de nuevo!Basándose en el comentario de dnlbrk, asignar puede ser considerablemente más rápido que list2env para archivos grandes.
Al establecer el argumento full.names en verdadero, obtendrá la ruta completa a cada archivo como una cadena de caracteres separada en su lista de archivos, por ejemplo, List_of_file_paths [1] será algo así como "C: / Users / Anon / Documents / Carpeta_con_archivos_csv / archivo1.csv "
Puede usar el paquete data.table fread o base R read.csv en lugar de read_csv. El paso nombre_archivo le permite ordenar el nombre para que cada marco de datos no permanezca con la ruta completa del archivo como su nombre. Puede extender su ciclo para hacer más cosas en la tabla de datos antes de transferirlo al entorno global, por ejemplo:
fuente
Este es mi ejemplo específico para leer varios archivos y combinarlos en 1 marco de datos:
fuente
rbindlist()
desdedata.table
Los siguientes códigos deberían darle la velocidad más rápida para big data siempre que tenga muchos núcleos en su computadora:
Actualizado en 16/04 2020: a medida que encuentro un nuevo paquete disponible para cómputo paralelo, se proporciona una solución alternativa utilizando los siguientes códigos.
fuente
Me gusta el enfoque usando
list.files()
,lapply()
ylist2env()
(ofs::dir_ls()
,purrr::map()
ylist2env()
). Eso parece simple y flexible.Alternativamente, puede probar el paquete pequeño { tor } ( to-R ): por defecto importa archivos del directorio de trabajo a una lista (
list_*()
variantes) o al entorno global (load_*()
variantes).Por ejemplo, aquí leo todos los archivos .csv de mi directorio de trabajo en una lista usando
tor::list_csv()
:Y ahora cargo esos archivos en mi entorno global con
tor::load_csv()
:En caso de que tenga que leer archivos específicos, puede hacer coincidir su file-path con
regexp
,ignore.case
yinvert
.Para un uso aún más flexible
list_any()
. Le permite proporcionar la función de lector a través del argumento.f
.Pase argumentos adicionales a través de ... o dentro de la función lambda.
fuente
Se solicitó que agregue esta funcionalidad al paquete stackoverflow R. Dado que es un paquete tinyverse (y no puede depender de paquetes de terceros), esto es lo que se me ocurrió:
Al parametrizar la función de lector y reductor, las personas pueden usar data.table o dplyr si así lo desean, o simplemente usar las funciones base R que están bien para conjuntos de datos más pequeños.
fuente