0

I would like to write a loop to create multiple data frames from a set of already existsing matrices. I've imported and created these using the code:

temp<-list.files(pattern="*.csv")
ddives <- lapply(temp, read.csv)

so 'ddives' is my set of set of csv files. I now want to create a data frame out of each of these using a looped version of the code:

d.dives1<- data.frame(ddives[1])
Jojo
  • 4,951
  • 7
  • 23
  • 27
  • 1
    ... Doesn't read.csv already return a data.frame? – Dason Jul 11 '12 at 15:55
  • No unfortunately using this code it has just returned 165 (number of files I have) lists which I need to convert to data frames – Jojo Jul 11 '12 at 16:02
  • 1
    I highly doubt it returns 165 lists. More likely it's returning 1 list with 165 data frames as elements. ddives[[1]] will give you the first data.frame, ddives[[2]] will give you the second... – Dason Jul 11 '12 at 16:03
  • It's not clear what you want to do: do you want to combine all these data.frames one at the end of each other to form a bigger data.frame ? If yes, below answer will work (if all your files have the same number of columns). Based on your example, it seems like you want to put each data.frame in a separate variable ... – nassimhddd Jul 11 '12 at 16:12
  • 1
    And if you just want to put them in separate variables then it's probably just smarter and more efficient to keep it as a list... – Dason Jul 11 '12 at 16:13
  • 1
    Are the data related? Are you going to be doing similar operations on all `data.frames`? If you are, it may be better (more efficient, as @Dason points out) for you to keep them as a list and get familiar with the `apply` family of functions. – A5C1D2H2I1M1N2O1R2T1 Jul 11 '12 at 16:24

3 Answers3

7

A quick primer on terminology before I answer your question:

  1. The result of read.csv() is a data.frame.
  2. The result of lapply() is a list.

Thus you now have a list of data frames.

If you can safely assume that the data frames in the list have the same structure (i.e. the same number of columns and the same classes), then you can use rbind() to combine your list of data frames into a single data.frame.

To make this easier, you can use do.call() as follows:

do.call(rbind, ddives)

do.call constructs a call from the function using the list elements as arguments. If they are named, they are passed as named arguments, otherwise in order (as always in R). In this case you apply rbind to all of the elements in your list, thus creating a single data.frame.


This is clearly untested, since I don't have your data. But, in general, do.call is a useful function for this type of operation.

Andrie
  • 176,377
  • 47
  • 447
  • 496
  • I would be careful in saying that `do.call` 'applies a function to a list'. It's using the elements of the list as parameters for the given function. I would think `lapply` would more adequately be described by 'applies a function to a list'. – Dason Jul 11 '12 at 16:12
  • Good answer (and upvoted). This is nitpicky, but since we are on details... `do.call` constructs a call from the function using the list elements as _arguments_. If they are named, they are passed as named arguments, otherwise in order, as always in `R`. So for the default method of the `mean` function: `function (x, trim = 0, na.rm = FALSE, ...)` these produce different results: `do.call("mean", list(x = c(1:10, NA), na.rm = TRUE))`, `do.call("mean", list(x = c(1:10, NA), TRUE))`, `do.call("mean", list(c(1:10, NA), na.rm = TRUE))`. – Joshua Jul 11 '12 at 17:00
  • @Joshua Thank you. Answer edited again (by copying and pasting your text). Please feel free to edit and improve, as necessary. – Andrie Jul 11 '12 at 17:19
1

As this is a follow up to the earlier question you posted, try this:

for (i in 1:length(ddives)) assign(temp[i], ddives[[i]])
A5C1D2H2I1M1N2O1R2T1
  • 190,393
  • 28
  • 405
  • 485
  • 2
    Then again you could just use ddives[[i]] - there is no need for all that other nonsense since each element in the list should be a dataframe already. – Dason Jul 11 '12 at 16:22
  • @Dason, I fully agree with you. That's why I had answered [the original question](http://stackoverflow.com/questions/11433432/importing-multiple-csv-files-into-r) the way I did. Now I'm just providing an answer to *this* question. **I** wouldn't want to have my workspace filled with 165 files when I can just use the list indexing features. – A5C1D2H2I1M1N2O1R2T1 Jul 11 '12 at 16:26
  • I was actually talking about in the assign statement. Why are you using data.frame(unlist(stuff)) when you could just use ddives[[i]]? It should do the same thing shouldn't it? – Dason Jul 11 '12 at 16:29
  • 1
    @Dason, (slapping forehead). It's bedtime in India. I've edited my answer. Thanks! – A5C1D2H2I1M1N2O1R2T1 Jul 11 '12 at 16:33
0

If you really want a looped version of your code, this would be:

for (i in 1:length(ddives)){
  assign(paste("d.dives", i, sep =""), ddives[i])
}
nassimhddd
  • 8,340
  • 1
  • 29
  • 44