5

I have a list of data frame, for each list, I have a name for it, which is the USERID, the following is a sample of the list:

$'AAAAAA'
AA  BB  CC
a   b   1
c   d   2
e   f   3
S'BBBBBB'
AA  BB  CC
g   h   1
i   j   2
k   l   3

My question is how to convert this list into a data frame which has a new column showing the USERID, like the below sample:

AA  BB  CC  USERID
a   b   1   AAAAAA
c   d   2   AAAAAA
e   f   3   AAAAAA
g   h   1   BBBBBB
i   j   2   BBBBBB
k   l   3   BBBBBB

Any Idea how it could be done. Thank you so much in advance

A5C1D2H2I1M1N2O1R2T1
  • 190,393
  • 28
  • 405
  • 485
rabbit_jx
  • 55
  • 5
  • Try `df <- do.call(rbind, l) ; df$USERID <- gsub("[.]\\d", "", row.names(df))` if `l` is your list – David Arenburg Sep 30 '14 at 07:28
  • 1
    This has been answered several times before, e.g. [**here**](http://stackoverflow.com/questions/15162197/append-data-sets-create-new-column-identifying-which-data-set-it-came-from), [**here**](http://stackoverflow.com/questions/15162197/append-data-sets-create-new-column-identifying-which-data-set-it-came-from), [**here**](http://stackoverflow.com/questions/15214472/use-object-names-within-a-list-in-lapply-ldply), [**here**](http://stackoverflow.com/questions/25759336/how-to-create-a-new-column-with-names-in-a-list/25759940#25759940). – Henrik Sep 30 '14 at 07:37

3 Answers3

6

Since cbind recycles its arguments to the length of the longest vector, you could try

Reduce(rbind, Map(cbind, x, USERID = names(x)))
#   AA BB CC USERID
# 1  a  b  1  AAAAA
# 2  c  d  2  AAAAA
# 3  e  f  3  AAAAA
# 4  g  h  1  BBBBB
# 5  i  j  2  BBBBB
# 6  k  l  3  BBBBB

where x is

structure(list(AAAAA = structure(list(AA = c("a", "c", "e"), 
    BB = c("b", "d", "f"), CC = 1:3), .Names = c("AA", "BB", 
"CC"), class = "data.frame", row.names = c(NA, -3L)), BBBBB = structure(list(
    AA = c("g", "i", "k"), BB = c("h", "j", "l"), CC = 1:3), .Names = c("AA", 
"BB", "CC"), class = "data.frame", row.names = c(NA, -3L))), .Names = c("AAAAA", 
"BBBBB"))
Rich Scriven
  • 97,041
  • 11
  • 181
  • 245
6

Another way, using the development version of tidyr:

# install.packages("devtools")
devtools::install_github("hadley/tidyr")
library(tidyr)

unnest(mylist, USERID)
#   USERID AA BB CC
# 1  AAAAA  a  b  1
# 2  AAAAA  c  d  2
# 3  AAAAA  e  f  3
# 4  BBBBB  g  h  1
# 5  BBBBB  i  j  2
# 6  BBBBB  k  l  3
Henrik
  • 65,555
  • 14
  • 143
  • 159
jazzurro
  • 23,179
  • 35
  • 66
  • 76
  • How come I don't have `unnest` in my 0.1 version of `tidyr`? – Rich Scriven Sep 30 '14 at 07:47
  • I did not know this new function till I saw it the other day. You need to get the github version. `unnest()` is not officially released yet. https://github.com/hadley/tidyr/blob/master/man/unnest.Rd – jazzurro Sep 30 '14 at 07:49
  • 2
    @jazzurro +1, It is better to show that in the post to make it clear. `library('devtools');install_github('hadley/tidyr'); library(tidyr)` – akrun Sep 30 '14 at 09:16
  • @akrun Thanks for that. I will do that from next time. – jazzurro Sep 30 '14 at 10:03
4

Or (if l is your list)

library(data.table)
rbindlist(Map(cbind, l, USERID = names(l)))
#    AA BB CC USERID
# 1:  a  b  1 AAAAAA
# 2:  c  d  2 AAAAAA
# 3:  e  f  3 AAAAAA
# 4:  g  h  1 BBBBBB
# 5:  i  j  2 BBBBBB
# 6:  k  l  3 BBBBBB
David Arenburg
  • 91,361
  • 17
  • 137
  • 196