서영빈
서영빈

Reputation: 106

How to 'read.csv' many files in a folder using R?

How can I read many CSV files and make each of them into data tables?

I have files of 'A1.csv' 'A2.csv' 'A3.csv'...... in Folder 'A'

So I tried this.

link <- c("C:/A")
filename<-list.files(link)
listA <- c()

for(x in filename) {
 temp <- read.csv(paste0(link , x), header=FALSE)
 listA <- list(unlist(listA, recursive=FALSE), temp)
 }

And it doesn't work well. How can I do this job?

Upvotes: 0

Views: 622

Answers (3)

r2evans
r2evans

Reputation: 160407

Unless each file is a completely different structure (i.e., different columns ... the number of rows does not matter), you can consider a more efficient approach of reading the files in using lapply and storing them in a list. One of the benefits is that whatever you do to one frame can be immediately done to all of them very easily using lapply.

files <- list.files(link, full.names = TRUE, pattern = "csv$")
list_of_frames <- lapply(files, read.csv)
# optional
names(list_of_frames) <- files # or basename(files), if filenames are unique

Something like sapply(list_of_frames, nrow) will tell you how many rows are in each frame. If you have something more complex,

new_list_of_frames <- lapply(list_of_frames, function(x) {
  # do something with 'x', a single frame
})

Upvotes: 2

Marcus
Marcus

Reputation: 3636

The most immediate problem is that when pasting your file path together, you need a path separator. When composing file paths, it's best to use the function file.path as it will attempt to determine what the path separator is for operating system the code is running on. So you want to use:

read.csv(files.path(link , x), header=FALSE)

Better yet, just have the full path returned when listing out the files (and can filter for .csv):

filename <- list.files(link, full.names = TRUE, pattern = "csv$")

Combining with the idea to use assign to dynamically create the variables:

link <- c("C:/A")
files <-list.files(link, full.names = TRUE, pattern = "csv$")

for(file in files){
  assign(paste0(basename(file), "_df"), read.csv(file))
}

Upvotes: 1

Juan Sebastian Lozano
Juan Sebastian Lozano

Reputation: 473

Write a regex to match the filenames

reg_expression <- "A[0-9]+"
files <- grep(reg_expression, list.files(directory), value = TRUE)

and then run the same loop but use assign to dynamically name the dataframes if you want

for(file in files){
    assign(paste0(file, "_df"),read.csv(file))
}

But in general introducing unknown variables into the scope is bad practice so it might be best to do a loop like

dfs <- list()
for(index in 1:length(files)){
    file <- files[index]
    dfs[index] <- read.csv(file)
}

Upvotes: 2

Related Questions