0

I have a list (lgtdata3) with 300+ elements and each list looks like the following:

lgtdat3[[1]]
 $y
 [1] 3 3 3 

 $X

  1 0 1.178470  7.643059 0.5680831
  0 1 1.220708 10.272480 0.7268355
  0 0 0.000000  0.000000 0.0000000

 $id
 123

and i want to stack the y, x, and id component in each sublist of the total list into a dataframe. My ideal result would be the following:

 y:
 3 3 3 4 6 ...

 x:
 1 0 1.178470  7.643059   0.5680831
 0 1 1.220708  10.27248   0.7268355
 0 0 0.000120  0.000000   0.0000000 
 1 1 1.175660  7.6435459  0.5685431
 0 1 1.228708  10.272480  0.7265355
 0 0 0.001400  0.0156000  0.0055000
 ....

 id
 123 124 ... 

I have tried the following methods but none of them is working:

 mnl = Reduce(merge,lgtdata3)
 mnl = lapply(lgtdata3, function (x) '[',(c('y', 'X','hhid'))) 
Hack-R
  • 22,422
  • 14
  • 75
  • 131
lll
  • 1,049
  • 2
  • 13
  • 39
  • 1
    Please show a small reproducible example, what are those values - vector/matrix/data.frame`? – akrun Jul 26 '16 at 03:44
  • http://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example – shayaa Jul 26 '16 at 03:44
  • I presume the problem is that your list is too long to share in a reproducible way. In that case the best thing would be to either make a new list from built-in data or shorten the list. – Hack-R Jul 26 '16 at 04:07
  • `library(purrr) ; lgtdat3 %>% transpose() %>% map_at('X', reduce, rbind) %>% map_if(is_list, unlist)` – alistaire Jul 26 '16 at 04:16

2 Answers2

1

We can use transpose from purrr and then loop through the list elements with lapply to do the concatenation/rbind.

library(purrr)
res <- lapply(transpose(lgtdat3), function(x) if(all(sapply(x, is.matrix))) 
                 do.call(rbind, x) else unlist(x))
res
#$y
#[1] 3 3 3 4 6 4

#$x
#           [,1]       [,2]       [,3]
#1 0 -0.545880758 -0.5836272  0.4445853
#0 1  0.536585304  0.8474600 -0.4664951
#0 0  0.419623149  0.2660220 -0.8483700
#1 0  0.002311942 -0.7622144 -0.4690607
#0 1 -1.316908124 -1.4290903 -0.3349868
#0 0  0.598269113  0.3322444  1.5362522

#$id
#[1] 123 124

NOTE: Assumption is that the 'x' elements are matrices.

data

set.seed(24) 
lgtdat3 <- list(list(y = c(3, 3, 3), x = `row.names<-`(matrix(rnorm(9), 3, 
            3), c("1 0", "0 1", "0 0")), id = 123), 
               list(y = c(4, 6, 4), x= `row.names<-`(matrix(rnorm(9), 3, 
             3), c("1 0", "0 1", "0 0")), id = 124))
Community
  • 1
  • 1
akrun
  • 874,273
  • 37
  • 540
  • 662
1

Here's a base R solution, demonstrated on akrun's data:

setNames(nm=names(lgtdat3[[1L]]),lapply(seq_along(lgtdat3[[1L]]),function(i)
    do.call(if (is.null(dim(lgtdat3[[1L]][[i]]))) c else rbind,lapply(lgtdat3,`[[`,i))
));
## $y
## [1] 3 3 3 4 6 4
##
## $x
##             [,1]       [,2]       [,3]
## 1 0 -0.545880758 -0.5836272  0.4445853
## 0 1  0.536585304  0.8474600 -0.4664951
## 0 0  0.419623149  0.2660220 -0.8483700
## 1 0  0.002311942 -0.7622144 -0.4690607
## 0 1 -1.316908124 -1.4290903 -0.3349868
## 0 0  0.598269113  0.3322444  1.5362522
##
## $id
## [1] 123 124
##
bgoldst
  • 34,190
  • 6
  • 38
  • 64