J'ai écrit la fonction suivante pour combiner 300 fichiers .csv. Le nom de mon répertoire est "specdata". J'ai fait les étapes suivantes pour l'exécution,
x <- function(directory) {
dir <- directory
data_dir <- paste(getwd(),dir,sep = "/")
files <- list.files(data_dir,pattern = '\\.csv')
tables <- lapply(paste(data_dir,files,sep = "/"), read.csv, header = TRUE)
pollutantmean <- do.call(rbind , tables)
}
# Step 2: call the function
x("specdata")
# Step 3: inspect results
head(pollutantmean)
Error in head(pollutantmean) : object 'pollutantmean' not found
Quelle est mon erreur? Quelqu'un peut-il expliquer?
Il y a beaucoup de code inutile dans votre fonction. Vous pouvez le simplifier pour:
load_data <- function(path) {
files <- dir(path, pattern = '\\.csv', full.names = TRUE)
tables <- lapply(files, read.csv)
do.call(rbind, tables)
}
pollutantmean <- load_data("specdata")
Soit conscient que do.call
+ rbind
est relativement lent. Vous pourriez trouver dplyr::bind_rows
ou data.table::rbindlist
pour être sensiblement plus rapide.
Pour mettre à jour la réponse du professeur Wickham ci-dessus avec le code de la bibliothèque la plus récente purrr
qu'il a co-écrit avec Lionel Henry:
Tbl <-
list.files(pattern="*.csv") %>%
map_df(~read_csv(.))
Si le transtypage est effronté, vous pouvez forcer toutes les colonnes à être des caractères avec cela.
Tbl <-
list.files(pattern="*.csv") %>%
map_df(~read_csv(., col_types = cols(.default = "c")))
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.)
Tbl <-
list.files(path = "./subdirectory/",
pattern="*.csv",
full.names = T) %>%
map_df(~read_csv(., col_types = cols(.default = "c")))
Comme le décrit le professeur Wickham ici (à mi-chemin environ):
map_df(x, f)
est effectivement la même chose quedo.call("rbind", lapply(x, f))
mais sous le capot est beaucoup plus efficace.
et un merci à Jake Kaupp pour m'avoir présenté map_df () ici .
Cela peut être fait de manière très succincte avec du dplyr et du ronronnement du tidyverse. Où x est une liste des noms de vos fichiers csv que vous pouvez simplement utiliser:
bind_rows(map(x, read.csv))
Le mappage de read.csv en x produit une liste de fichiers DFS que bind_rows combine ensuite parfaitement!
```{r echo = FALSE, warning = FALSE, message = FALSE}
setwd("~/Data/R/BacklogReporting/data/PastDue/global/") ## where file are located
path = "~/Data/R/BacklogReporting/data/PastDue/global/"
out.file <- ""
file.names <- dir(path, pattern = ".csv")
for(i in 1:length(file.names)){
file <- read.csv(file.names[i], header = TRUE, stringsAsFactors = FALSE)
out.file <- rbind(out.file, file)
}
write.csv(out.file, file = "~/Data/R/BacklogReporting/data/PastDue/global/global_stacked/past_due_global_stacked.csv", row.names = FALSE) ## directory to write stacked file to
past_due_global_stacked <- read.csv("C:/Users/E550143/Documents/Data/R/BacklogReporting/data/PastDue/global/global_stacked/past_due_global_stacked.csv", stringsAsFactors = FALSE)
files <- list.files(pattern = "\\.csv$") %>% t() %>% paste(collapse = ", ")
```
Si vos fichiers csv se trouvent dans un autre répertoire, vous pouvez utiliser quelque chose comme ceci:
readFilesInDirectory <- function(directory, pattern){
files <- list.files(path = directory,pattern = pattern)
for (f in files){
file <- paste(directory,files, sep ="")
temp <- lapply(file, fread, sep=",")
data <- rbindlist( temp )
}
return(data)
}