0

I suppose this is simple, but I just can't seem to figure it out. I need to flatten the second level structure and push the list name/key to a vector on the same level as the other vectors. The current structure of myList is

$ 13454:List of 30
  ..$ subjectId        : num 187
  ..$ procedureId      : num 3
  ..$ procedureSampleId: num 3
  ..$ timestamp        : chr "2017-04-21T17:15:10.911Z"
  ..$ n001             : num -999
  ..$ n002             : num -999
  ..$ gender           : num 1
  ..$ age              : num 18

 $ 13455:List of 30
  ..$ subjectId        : num 188
  ..$ procedureId      : num 3
  ..$ procedureSampleId: num 3
  ..$ timestamp        : chr "2017-04-21T17:15:10.913Z"
  ..$ n001             : num -999
  ..$ n002             : num -999      
  ..$ gender           : num -999
  ..$ age              : num 28

whereas this is the structure I'm looking for

 $ ID               : chr  '13455' '13455'
 $ subjectId        : num 187 188
 $ procedureId:     : num  3 3

and so on

I've tried to achieve this by:

  myList2 <- sapply(names(myList), function(y){
    y <- unlist(c('ID' = y, myList[[y]]), use.names = TRUE)
  })

But I end up with the full transposed result of what I need. I could go t(myList2) but I want to understand how to do this correctly. Thank you!

EDIT: Reproducible data:

myList <- list('13454' = list('subjectId' = 187, 'procedureId' = 3, 'procedureSampleId' = 3, 'timestamp' = "2017-04-21T17:15:10.911Z", 'n001' = -999, 'n002' = -999, 'gender' = 1, 'age' = 18), '13455' = list('subjectId' = 188, 'procedureId' = 3, 'procedureSampleId' = 3, 'timestamp' = "2017-04-21T17:15:10.913Z", 'n001' = -999, 'n002' = -999, 'gender' = -999, 'age' = 28))
Comfort Eagle
  • 2,112
  • 2
  • 22
  • 44
  • 3
    What you say you want and what you show you want are not the same thing. If you want a data.frame, `rbind` it all together, e.g. `dplyr::bind_rows(myList, .id = 'ID')`. Either way, you need [to make your example reproducible](http://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example#5963610) by adding sample data. – alistaire May 05 '17 at 20:47

2 Answers2

3

myList can be turned into a data.frame using lapply() and rbindlist() from the data.table package:

result <- data.table::rbindlist(lapply(myList, as.data.frame), idcol = "ID")
result[["ID"]] <- names(myList)
result
#      ID subjectId procedureId procedureSampleId                timestamp n001 n002 gender age
#1: 13454       187           3                 3 2017-04-21T17:15:10.911Z -999 -999      1  18
#2: 13455       188           3                 3 2017-04-21T17:15:10.913Z -999 -999   -999  28

Edit: This can be even more streamlined:

library(data.table)
rbindlist(myList, idcol = "ID")[, ID := names(myList)][]
Uwe
  • 41,420
  • 11
  • 90
  • 134
0

Edit: To get to the list format you indicate above in base R, use rbind to build the data frame, then unlist the necessary elements with lapply.

With your list above, you can use do.call to call rbind in base R:

example<-data.frame(ID = as.character(names(myList)), do.call("rbind", myList), row.names = NULL)
exAsList <-lapply(example, function(x) x <- unlist(x, use.names = FALSE))
exAsList
Luke C
  • 10,081
  • 1
  • 14
  • 21