Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Read multiple CSV files into separate data frames

Tags:

file

r

csv

lapply

Suppose we have files file1.csv, file2.csv, ... , and file100.csv in directory C:\R\Data and we want to read them all into separate data frames (e.g. file1, file2, ... , and file100).

The reason for this is that, despite having similar names they have different file structures, so it is not that useful to have them in a list.

I could use lapply but that returns a single list containing 100 data frames. Instead I want these data frames in the Global Environment.

How do I read multiple files directly into the global environment? Or, alternatively, How do I unpack the contents of a list of data frames into it?

like image 792
Fred Avatar asked Mar 16 '11 00:03

Fred


People also ask

How do I read a csv file in a different separator?

Adding "sep=;" or "sep=," to the CSV file Here are the steps you should follow: Open your CSV using a text editor. Skip a line at the top, and add sep=; if the separator used in the CSV is a semicolon (;), or sep=, if the separator is a comma (,). Save, and re-open the file.


4 Answers

Thank you all for replying.

For completeness here is my final answer for loading any number of (tab) delimited files, in this case with 6 columns of data each where column 1 is characters, 2 is factor, and remainder numeric:

##Read files named xyz1111.csv, xyz2222.csv, etc.
filenames <- list.files(path="../Data/original_data",
    pattern="xyz+.*csv")

##Create list of data frame names without the ".csv" part 
names <-substr(filenames,1,7)

###Load all files
for(i in names){
    filepath <- file.path("../Data/original_data/",paste(i,".csv",sep=""))
    assign(i, read.delim(filepath,
    colClasses=c("character","factor",rep("numeric",4)),
    sep = "\t"))
}
like image 125
5 revs, 2 users 98% Avatar answered Oct 26 '22 04:10

5 revs, 2 users 98%


Quick draft, untested:

  1. Use list.files() aka dir() to dynamically generate your list of files.

  2. This returns a vector, just run along the vector in a for loop.

  3. Read the i-th file, then use assign() to place the content into a new variable file_i

That should do the trick for you.

like image 25
Dirk Eddelbuettel Avatar answered Oct 26 '22 05:10

Dirk Eddelbuettel


Use assign with a character variable containing the desired name of your data frame.

for(i in 1:100)
{
   oname = paste("file", i, sep="")
   assign(oname, read.csv(paste(oname, ".txt", sep="")))
}
like image 17
Hong Ooi Avatar answered Oct 26 '22 05:10

Hong Ooi


This answer is intended as a more useful complement to Hadley's answer.

While the OP specifically wanted each file read into their R workspace as a separate object, many other people naively landing on this question may think that that's what they want to do, when in fact they'd be better off reading the files into a single list of data frames.

So for the record, here's how you might do that.

#If the path is different than your working directory
# you'll need to set full.names = TRUE to get the full
# paths.
my_files <- list.files("path/to/files")

#Further arguments to read.csv can be passed in ...
all_csv <- lapply(my_files,read.csv,...)

#Set the name of each list element to its
# respective file name. Note full.names = FALSE to
# get only the file names, not the full path.
names(all_csv) <- gsub(".csv","",
                       list.files("path/to/files",full.names = FALSE),
                       fixed = TRUE)

Now any of the files can be referred to by my_files[["filename"]], which really isn't much worse that just having separate filename variables in your workspace, and often it is much more convenient.

like image 11
joran Avatar answered Oct 26 '22 04:10

joran