2

Here's my question. It's really appreciated if you can help. I have a list containing several data.frames with different length but the same structure. Now I want to save the data.frames in the list respectively. Note: not combine them using do.call(rbind,...) into one single data.frame. And Also I want to name each of the data.frame in a array.

a=c(1,2,3,4,5,6)

b=c(4,5,6,5,5,5)

c=c(3,4,5,6,7,8)

A=data.frame(a=a,b=b,c=c)

B=data.frame(a=c,b=b,c=a)

C=data.frame(a=b,b=c,c=a)

l <- list(A, B, C)

names.list <- c("NewYear_Data", "Thanks_giving", "Christmas")

Now I want to save the A B C in the list using the name in names.list

To be specific, Here I have a list l, in which have several data.frames. Now I want to save each data.frames in the list l using the name in the names.list.

I tried unlist, and get, and apply...

It would be great if anyone can solve this using plyr, reshape, or data.table methods.

Thanks a lot!

eddi
  • 49,088
  • 6
  • 104
  • 155
Bigchao
  • 1,746
  • 3
  • 15
  • 31
  • What is not perfect in the code you presented? I miss what is it what you did not achieve. – Andrey Shabalin Dec 28 '13 at 07:28
  • Hey Andrey, I edited a little bit:) Any suggestions are welcome! – Bigchao Dec 28 '13 at 07:33
  • 1
    It's really not clear where you want to end up. Perhaps `list2env` might be of use to you? (Or, maybe it's as easy as `names`, as Andrey suggests in his answer.) – A5C1D2H2I1M1N2O1R2T1 Dec 28 '13 at 07:43
  • 1
    What do you mean by "respectively"? I get the feeling that the word doesn't have the same meaning for you that it does for most of us reading your question. Do you mean in alphabetical order or some other kind of specified order? – SlowLearner Dec 28 '13 at 09:27
  • 1
    I just want to get rid of the list.. – Bigchao Dec 29 '13 at 08:12

4 Answers4

4

Here is the solution

l <- list(A, B, C)
nms <- c("NewYear_Data", "Thanks_giving", "Christmas")
names(l) = nms

Now you can use names like this:

l$Christmas

If you want to get rid of the list, do this:

attach(l)
Christmas

To save them in a binary file:

save(list=nms,file='file.Rdata')

Or in a text files:

for( i in 1:length(l))
  write.csv(l[i],paste0(nms[i],'.txt'))

Note to avoid calling your variable names.

Andrey Shabalin
  • 4,389
  • 1
  • 19
  • 18
  • Thanks Andery, you are so helpful. Maybe I didn't explain it clearly. Here I want to same the data.frame **respectively**. That is I want Christmas, I want Thanks_giving, and I want NewYear_Data. Could you offer some suggestion? Thanks! – Bigchao Dec 28 '13 at 07:47
  • I've updated my answer with the `attach` option. Is this what you wanted? – Andrey Shabalin Dec 28 '13 at 07:52
  • 1
    Thanks Andrey! Sorry for that I don't have enough reputation to vote up...Here we are closer to what I want. Now I want to save the data.frame respectively for each data.frame attached. – Bigchao Dec 28 '13 at 08:12
  • What do you mean by save? (Updated the answer) – Andrey Shabalin Dec 28 '13 at 08:27
  • Thanks again for your help! I want to use the data.frame in the list in the following analysis. So I want to get rid of the list...Actually I read the rdata file containing the list and want to extract the data.frame. Is that clearer now? – Bigchao Dec 28 '13 at 16:55
  • Oddly, I want to apply the same function to a list of dataframes and it does not work `for(i in seq_along(l)){save(l[i], paste0(names(l[i]), '.RData'))}`. Any suggestion? – goclem Oct 07 '15 at 10:54
2

If the question is, "How do I save a list of data frames as separate files in a folder?", you may try using saveRDS rather than save (see here).

names(l) <- names.list

lapply(names(l), function(df) 
  saveRDS(l[[df]], file = paste0(df, ".rds")))

list.files(pattern = ".rds")
[1] "Christmas.rds"     "NewYear_Data.rds"  "Thanks_giving.rds"

# To load an individual dataframe later 
df <- readRDS(file = "NewYear_Data.rds")

If you want to use save, the following should work (see here; noting that save preserves variable names, hence the with statement and use of list =).

with(l, 
     lapply(names(l), function(df) 
       save(list = df, file = paste0(df, ".rda"))))

list.files(pattern = ".rda")
[1] "Christmas.rda"     "NewYear_Data.rda"  "Thanks_giving.rda"

Otherwise, you can save the entire list as a single file

save(l, file = "Holidays.Rda")
Community
  • 1
  • 1
JWilliman
  • 3,558
  • 32
  • 36
1

Working with a single list with named elements is almost always preferable to working with lots of objects in your workspace. However, two functions that may be of convenience to acheive your aims are setNames() and list2env(). The following line will create named data.frame objects in your global environment using the names in names.list...

list2env( setNames( l , names.list ) , .GlobalEnv )

setNames() is a convenience function that sets the names on an object and returns the object. list2env() assigns each element from a named list into the specified environment so you end up with 3 data.frame objects.

Simon O'Hanlon
  • 58,647
  • 14
  • 142
  • 184
0

After running your code, we have:

> ls()
[1] "a"          "A"          "b"          "B"          "c"          "C"         
[7] "l"          "names.list"

You can then assign the data.frames to the names in names.list:

> invisible(mapply(function(x, y) assign(x, y, envir=globalenv()), names.list, l))
> ls()
[1] "a"             "A"             "b"             "B"             "c"            
[6] "C"             "Christmas"     "l"             "names.list"    "NewYear_Data" 
[11] "Thanks_giving"
> Christmas
a b c
1 4 3 1
2 5 4 2
3 6 5 3
4 5 6 4
5 5 7 5
6 5 8 6
> NewYear_Data
a b c
1 1 4 3
2 2 5 4
3 3 6 5
4 4 5 6
5 5 5 7
6 6 5 8

Then, if you want to clean up your workspace and remove what you used to create the data, you can run the following (careful, this will remove EVERYTHING in your workspace, except the data frames we just created):

> rm(list=ls()[!(ls() %in% names.list)])
> ls()
[1] "Christmas"     "NewYear_Data"  "Thanks_giving"

Frankly, I would recommend @Andrey's answer with attach, but if you're really looking to get the data frames to be in your workspace and get rid of the stuff you used to create it, this is an option.

BrodieG
  • 51,669
  • 9
  • 93
  • 146