Quelque chose comme ce qui suit devrait se traduire par chaque bloc de données comme un élément distinct dans une seule liste:
temp = list.files(pattern="*.csv")
myfiles = lapply(temp, read.delim)
Cela suppose que vous avez ces CSV dans un seul répertoire - votre répertoire de travail actuel - et que tous ont l'extension en minuscule .csv
.
Si vous souhaitez ensuite combiner ces trames de données en une seule trame de données, voir les solutions dans d'autres réponses en utilisant des choses comme do.call(rbind,...)
, dplyr::bind_rows()
ou data.table::rbindlist()
.
Si vous voulez vraiment chaque bloc de données dans un objet séparé, même si cela est souvent déconseillé, vous pouvez effectuer les opérations suivantes avec assign
:
temp = list.files(pattern="*.csv")
for (i in 1:length(temp)) assign(temp[i], read.csv(temp[i]))
Ou, sans assign
, et pour montrer (1) comment nettoyer le nom du fichier et (2) montrer comment l'utiliser list2env
, vous pouvez essayer ce qui suit:
temp = list.files(pattern="*.csv")
list2env(
lapply(setNames(temp, make.names(gsub("*.csv$", "", temp))),
read.csv), envir = .GlobalEnv)
Mais encore une fois, il est souvent préférable de les laisser dans une seule liste.
A5C1D2H2I1M1N2O1R2T1
la source
assign
... Si vous souhaitez que les valeurs attribuées résident dans l'environnement global, assurez-vous de les définirinherits=T
.Une
tidyverse
solution rapide et succincte : (plus de deux fois plus rapide que les Base Rread.csv
)et data.table « s
fread()
peuvent même réduire les temps de chargement de moitié à nouveau. (pour 1/4 des temps Base R )L'
stringsAsFactors = FALSE
argument maintient le facteur de trame de données libre (et comme le souligne Marbel, est le paramètre par défaut pourfread
)Si le transtypage est effronté, vous pouvez forcer toutes les colonnes à être en tant que caractères avec l'
col_types
argument.Si vous souhaitez vous plonger dans des sous-répertoires pour construire votre liste de fichiers à lier, assurez-vous d'inclure le nom du chemin et d'enregistrer les fichiers avec leurs noms complets dans votre liste. Cela permettra au travail de liaison de se poursuivre en dehors du répertoire actuel. (En pensant aux chemins d'accès complets comme fonctionnant comme des passeports pour permettre le retour à travers les «frontières» du répertoire.)
Comme Hadley le décrit ici (à mi-chemin environ):
Bonus - ajout de noms de fichiers aux enregistrements par demande de fonctionnalité Niks dans les commentaires ci-dessous:
* Ajouter l'original
filename
à chaque enregistrement.Explication du code: créer une fonction pour ajouter le nom de fichier à chaque enregistrement lors de la lecture initiale des tableaux. Utilisez ensuite cette fonction au lieu de la
read_csv()
fonction simple .(Les approches de transtypage et de gestion des sous-répertoires peuvent également être gérées à l'intérieur de la
read_plus()
fonction de la même manière que celle illustrée dans les deuxième et troisième variantes suggérées ci-dessus.)Cas d'utilisation de Middling
Cas d'utilisation plus grand
Variété de cas d'utilisation
Lignes: nombre de fichiers (1000, 100, 10)
Colonnes: taille finale de la trame de données (5 Mo, 50 Mo, 500 Mo)
(cliquez sur l'image pour voir la taille d'origine)
Les résultats R de base sont meilleurs pour les cas d'utilisation les plus petits où la surcharge liée à l'utilisation des bibliothèques C de purrr et dplyr l'emporte sur les gains de performances observés lors de l'exécution de tâches de traitement à plus grande échelle.
si vous souhaitez exécuter vos propres tests, ce script bash peut vous être utile.
bash what_you_name_this_script.sh "fileName_you_want_copied" 100
créera 100 copies de votre fichier numérotées séquentiellement (après les 8 premiers caractères du nom de fichier et un trait de soulignement).Attributions et appréciations
Un merci spécial à:
map_df()
ici .fread()
. (J'ai besoin d'étudierdata.table
.)la source
readAddFilename <- function(flnm) { read_csv(flnm) %>% mutate(filename = flnm) }
Alors, déposez-le simplement aumap_df
lieu de la lecture seuleread_csv()
qui est là maintenant. Je peux mettre à jour l'entrée ci-dessus pour montrer la fonction et comment elle s'intégrerait dans le tuyau si vous avez encore des questions ou si vous pensez que cela sera utile.read_csv
c'est beaucoup plus lent quefread
. J'inclurais un point de référence si vous voulez dire que quelque chose est plus rapide. Une idée est de créer 30 fichiers de 1 Go et de les lire, ce serait un cas où les performances sont importantes.fread()
et dplyr » sread_csv()
: 14,2 vs 19,9 secondes. TBH, je n'avais comparé que la base R à dplyr et commeread_csv()
c'est environ 2 à 4 fois plus rapide que leread.csv()
, l'analyse comparative ne semblait pas nécessaire. Il a cependant été intéressant de fairefread()
un tourbillon et de faire une pause pour consulter des résultats de référence plus complets. Merci encore!Voici quelques options pour convertir les fichiers .csv en un data.frame en utilisant la base R et certains des packages disponibles pour lire les fichiers en R.
C'est plus lent que les options ci-dessous.
Modifier: - Quelques choix supplémentaires en utilisant
data.table
etreadr
Une
fread()
version, qui est une fonction dudata.table
package. Ceci est de loin l'option la plus rapide en R .Utilisation de readr , qui est un autre package pour lire les fichiers csv. Il est plus lent que
fread
, plus rapide que la base R mais a des fonctionnalités différentes.la source
data.table
version qui devrait améliorer les performances.do.call
En plus d'utiliser
lapply
ou d'une autre construction en boucle dans R, vous pouvez fusionner vos fichiers CSV en un seul fichier.Sous Unix, si les fichiers n'ont pas d'en-tête, c'est aussi simple que:
ou s'il y a des en-têtes et que vous pouvez trouver une chaîne qui correspond aux en-têtes et uniquement aux en-têtes (par exemple, supposons que les lignes d'en-tête commencent toutes par "Age"), vous feriez:
Je pense que dans Windows, vous pouvez le faire avec
COPY
etSEARCH
(ouFIND
quelque chose) à partir de la boîte de commande DOS, mais pourquoi ne pas installercygwin
et obtenir la puissance du shell de commande Unix?la source
Git
installation?Ceci est le code que j'ai développé pour lire tous les fichiers csv dans R. Il créera un cadre de données pour chaque fichier csv individuellement et titre ce cadre de données le nom d'origine du fichier (en supprimant les espaces et le .csv) J'espère que vous le trouverez utile!
la source
Les trois premières réponses de @ A5C1D2H2I1M1N2O1R2T1, @leerssej et @marbel et sont toutes essentiellement les mêmes: appliquez une frayeur à chaque fichier, puis rbind / rbindlist les données.tables résultantes. J'utilise habituellement le
rbindlist(lapply(list.files("*.csv"),fread))
formulaire.C'est mieux que les autres alternatives internes à R, et c'est bien pour un petit nombre de grands csv, mais pas le meilleur pour un grand nombre de petits csv lorsque la vitesse compte. Dans ce cas, la première utilisation peut être beaucoup plus rapide
cat
, comme le suggère @Spacedman dans la réponse au 4e rang. Je vais ajouter quelques détails sur la façon de procéder à partir de R:Cependant, que se passe-t-il si chaque csv a un en-tête?
Et si vous avez tellement de fichiers que le
*.csv
glob de shell échoue?Et si tous les fichiers ont un en-tête ET qu'il y a trop de fichiers?
Et si le csv concaténé résultant est trop grand pour la mémoire système?
Avec des en-têtes?
Enfin, que se passe-t-il si vous ne voulez pas tous les .csv dans un répertoire, mais plutôt un ensemble spécifique de fichiers? (En outre, ils ont tous des en-têtes.) (Ceci est mon cas d'utilisation.)
et ceci est à peu près la même vitesse que le chat xargs à effroi :)
Remarque: pour data.table pré-v1.11.6 (19 septembre 2018), omettez le
cmd=
fromfread(cmd=
.Addendum: l'utilisation de mclapply de la bibliothèque parallèle à la place de lapply série, par exemple,
rbindlist(lapply(list.files("*.csv"),fread))
est également beaucoup plus rapide que rbindlist lapply fread.Temps de lecture des csvs 121401 dans une seule table de données. Chaque csv comporte 3 colonnes, une ligne d'en-tête et, en moyenne, 4 510 lignes. La machine est une machine virtuelle GCP avec 96 cœurs:
Pour résumer, si vous êtes intéressé par la vitesse et que vous avez beaucoup de fichiers et de cœurs, fread xargs cat est environ 50 fois plus rapide que la solution la plus rapide dans les 3 meilleures réponses.
la source
À mon avis, la plupart des autres réponses sont obsolètes
rio::import_list
, ce qui est une ligne succincte:Tous les arguments supplémentaires sont passés à
rio::import
.rio
peut traiter presque tous les formats fichier R peut lire, et il utilisedata.table
est lafread
mesure du possible, il devrait donc être rapide aussi.la source
Son utilisation
plyr::ldply
augmente d'environ 50% la vitesse en activant l'.parallel
option lors de la lecture de 400 fichiers csv d'environ 30 à 40 Mo chacun. L'exemple comprend une barre de progression du texte.la source
fread
ouuser-defined functions
? Merci!?ldply
montre d'...
autres arguments transmis à.fun
. Utiliser soitfread, skip = 100
oufunction(x) fread(x, skip = 100)
fonctionneraitfunction(x) fread(x, skip = 100)
n'a pas fonctionné pour moi mais fournir des arguments supplémentaires après le nom de la fonction a fait l'affaire. Merci encore!En s'appuyant sur le commentaire de dnlbrk, l'attribution peut être considérablement plus rapide que list2env pour les gros fichiers.
En définissant l'argument full.names sur true, vous obtiendrez le chemin d'accès complet à chaque fichier sous la forme d'une chaîne de caractères distincte dans votre liste de fichiers, par exemple, List_of_file_paths [1] sera quelque chose comme "C: / Users / Anon / Documents / Folder_with_csv_files / file1.csv "
Vous pouvez utiliser fread ou base R read.csv du package data.table au lieu de read_csv. L'étape nom_fichier vous permet de ranger le nom afin que chaque trame de données ne reste pas avec le chemin d'accès complet au fichier tel qu'il est nom. Vous pouvez étendre votre boucle pour faire d'autres choses dans la table de données avant de la transférer dans l'environnement global, par exemple:
la source
Voici mon exemple spécifique pour lire plusieurs fichiers et les combiner en 1 bloc de données:
la source
rbindlist()
partir dedata.table
Les codes suivants devraient vous donner la vitesse la plus rapide pour les mégadonnées tant que vous avez plusieurs cœurs sur votre ordinateur:
Mis à jour en 2020/04/16: Comme je trouve un nouveau package disponible pour le calcul parallèle, une solution alternative est fournie en utilisant les codes suivants.
la source
J'aime l'approche utilisant
list.files()
,lapply()
etlist2env()
(oufs::dir_ls()
,purrr::map()
etlist2env()
). Cela semble simple et flexible.Vous pouvez également essayer le petit package { tor } ( to-R ): par défaut, il importe des fichiers du répertoire de travail dans une liste (
list_*()
variantes) ou dans l'environnement global (load_*()
variantes).Par exemple, ici, je lis tous les fichiers .csv de mon répertoire de travail dans une liste en utilisant
tor::list_csv()
:Et maintenant, je charge ces fichiers dans mon environnement mondial avec
tor::load_csv()
:Si vous avez besoin de lire des fichiers spécifiques, vous pouvez faire correspondre leur chemin de fichier avec
regexp
,ignore.case
etinvert
.Pour encore plus de flexibilité, utilisez
list_any()
. Il vous permet de fournir la fonction lecteur via l'argument.f
.Passez des arguments supplémentaires via ... ou à l'intérieur de la fonction lambda.
la source
Il m'a été demandé d'ajouter cette fonctionnalité au package stackoverflow R. Étant donné qu'il s'agit d'un petit paquet inverse (et ne peut pas dépendre de paquets tiers), voici ce que j'ai trouvé:
En paramétrant la fonction de lecture et de réduction, les utilisateurs peuvent utiliser data.table ou dplyr s'ils le souhaitent, ou simplement utiliser les fonctions de base R qui conviennent aux petits ensembles de données.
la source