0

I am looking into importing multiple csv files in R

temp = list.files(pattern="*.csv")
for (i in 1:length(temp)) assign(temp[i], read.csv(temp[i]))

however

temp[1] returns "something.csv"
.......

is there something wrong with my code?

smci
  • 26,085
  • 16
  • 96
  • 138
xbd
  • 875
  • 1
  • 7
  • 13
  • 1
    See http://stackoverflow.com/questions/19655431/reading-multiple-csv-files-in-r or http://stackoverflow.com/questions/9807945/consolidating-data-frames-in-r or http://stackoverflow.com/questions/23169645/r-3-0-3-rbind-multiple-csv-files/23170007#23170007 for a way – user20650 Apr 26 '14 at 22:21
  • Or perhaps your understanding of `assign`. Try `ls()` and see what is in your workspace... – Simon O'Hanlon Apr 26 '14 at 22:23
  • Thanks, is there a reason that `head(tables[1])` doesn't return the head but the whole list? and `nrow(tables[1]) = null` for the answer http://stackoverflow.com/questions/9807945/consolidating-data-frames-in-r – xbd Apr 26 '14 at 22:28
  • 1
    You are assigning the output of `read.csv` to the variable named by the string contained in `temp[i]`, i.e. you are assigning it to the variable whose name is `something.csv` so look for `something.csv` and that should contain the result of the read. – G. Grothendieck Apr 26 '14 at 22:31
  • @ G. Grothendieck but `"something.csv"` is a string? – xbd Apr 26 '14 at 22:33
  • Following what G.Grothendieck writes: perhaps rename your .csv files prior to assigning the name of the file. See http://r.789695.n4.nabble.com/Reading-a-bunch-of-csv-files-into-R-td4631383.html – user20650 Apr 26 '14 at 22:33
  • @xbd; what 'tables'?. But if it is in alist try head(tables[[1]]) - note the double `[` – user20650 Apr 26 '14 at 22:35
  • Example: `assign( "something.csv" , 1 ); something.csv` – Simon O'Hanlon Apr 26 '14 at 22:38
  • See solution in my answer. You don't want `assign`. – smci Apr 27 '14 at 00:32
  • possible duplicate of [Read multiple CSV files into separate data frames](http://stackoverflow.com/questions/5319839/read-multiple-csv-files-into-separate-data-frames) – Jaap Apr 27 '14 at 08:37

3 Answers3

4

No need for for looping in R when we have sapply (and the other *apply functions).

In this case, with no further arguments sapply returns a named list of data frames, which I will call read.all.

> temp <- list.files(pattern = "*.csv")
> read.all <- sapply(temp, read.csv)

Looking at read.all shows that it is a named list of data frames.

You can then access the individual data frames by file name with

> read.all[["filename.csv"]]  ## or read.all["filename.csv"]

or with the $ operator

> read.all$filename.csv
Rich Scriven
  • 90,041
  • 10
  • 148
  • 213
  • However OP wants to do it, it's useful to know you need `[[i]]` indexing when you access `temp`. – smci Apr 27 '14 at 01:08
  • Unless you enjoy getting failures like *In addition: Warning message: In temp[i] – smci Apr 27 '14 at 01:11
2

SOLUTION:

Fixes: 1) must use double-[[]] to get the individual list element 2) don't use assign()

So either:

for (i in 1:length(temp)) { temp[[i]] <- read.csv(temp[i]) }

or, if you don't want to overwrite the temp variable:

df = c(rep(data.frame(), length(temp))) # list of empty dataframe
for (i in 1:length(temp)) { df[[i]] <- as.list(read.csv(temp[i])) }

There were two separate mistakes in your original code:

  1. using single [] instead of double [[]]. Single [] gives you a list slice containing one element (not what you want to assign to), instead of just that actual element.

  2. assign is not doing what you think it's doing, as @G-Grothendieck said.

You simply want to do temp[[i]] <- read.csv(temp[i])

But what you're actually doing is assigning to the variable whose name is contained in temp[i]. So if temp[i] is 'whosyour.csv', you're actually creating and assigning to a variable with that name, rather than assigning to temp[i] itself:

whosyour.csv <- read.csv('whosyour.csv') # NOT WHAT YOU WANTED!
smci
  • 26,085
  • 16
  • 96
  • 138
1

Try this:

temp <- list.files(pattern = "*.csv")
## for individual files
dataset <- lapply(temp,FUN=function(files){read.table(files,header=TRUE, sep=",")})
dataset[1] ## for specific files of interest, OR
## If your CSV column structure is same across all csv's bind them all into 1 file
dataset <- do.call("rbind",lapply(temp,FUN=function(files){read.table(files,header=TRUE, sep=",")}))
digdeep
  • 594
  • 1
  • 9
  • 20