-3

I'm trying to manipulate an R list of lists which themselves contain matrices. What I want to do is similar to this question where a list of matrices, l, is combined into a single matrix using either do.call(rbind, l) or the rbind.fill.matrix(l) function from plyr. However, I want to combine the matrices from across the different elements of the top level list while retaining groupings at the lower level to end up with a list of matrices with the separate elements corresponding to the groupings of the lower level lists.

As an example consider the top level list toplist constructed from three lower level lists:

lowerlist1 = list(matrix1_1, matrix1_2, matrix1_3, matrix1_4)
lowerlist2 = list(matrix2_1, matrix2_2, matrix2_3, matrix2_4)
lowerlist3 = list(matrix3_1, matrix3_2, matrix3_3, matrix3_4)
toplist = list(lowerlist1, lowerlist2, lowerlist3)

where the matrices all have the same number of columns but may have different number of rows. In the end I would like a new list newtoplist with the following structure

newmatrix1 = rbind(matrix1_1, matrix2_1, matrix3_1)
newmatrix2 = rbind(matrix1_2, matrix2_2, matrix3_2)
newmatrix3 = rbind(matrix1_3, matrix2_3, matrix3_3)
newmatrix4 = rbind(matrix1_4, matrix2_4, matrix3_4)
newtoplist = list(newmatrix1, newmatrix2, newmatrix3, newmatrix4)

So a complete example would be:

matrix1_1 = matrix(1.1, 4, 5)
matrix1_2 = matrix(1.2, 3, 5)
matrix1_3 = matrix(1.3, 2, 5)
matrix1_4 = matrix(1.4, 3, 5)
matrix2_1 = matrix(2.1, 2, 5)
matrix2_2 = matrix(2.2, 4, 5)
matrix2_3 = matrix(2.3, 5, 5)
matrix2_4 = matrix(2.4, 2, 5)
matrix3_1 = matrix(3.1, 2, 5)
matrix3_2 = matrix(3.2, 4, 5)
matrix3_3 = matrix(3.3, 5, 5)
matrix3_4 = matrix(3.4, 2, 5)

lowerlist1 = list(matrix1_1, matrix1_2, matrix1_3, matrix1_4)
lowerlist2 = list(matrix2_1, matrix2_2, matrix2_3, matrix2_4)
lowerlist3 = list(matrix3_1, matrix3_2, matrix3_3, matrix3_4)
toplist = list(lowerlist1, lowerlist2, lowerlist3)

newmatrix1 = rbind(matrix1_1, matrix2_1, matrix3_1)
newmatrix2 = rbind(matrix1_2, matrix2_2, matrix3_2)
newmatrix3 = rbind(matrix1_3, matrix2_3, matrix3_3)
newmatrix4 = rbind(matrix1_4, matrix2_4, matrix3_4)
newtoplist = list(newmatrix1, newmatrix2, newmatrix3, newmatrix4)

Can this be done generally?

Community
  • 1
  • 1
NWPhy
  • 19
  • 2

2 Answers2

0
newtoplist<-mapply(rbind,lowerlist1,lowerlist2,lowerlist3)
Metrics
  • 15,172
  • 7
  • 54
  • 83
  • This works here although in my real application I have a varying number of toplist entries which can't be hardcoded. – NWPhy Mar 01 '15 at 19:25
  • You mean number of lowerlist is large. – Metrics Mar 01 '15 at 19:30
  • Well not necessarily large - it actually corresponds to the number of processor cores I'm running a function on using the `parallel` package. – NWPhy Mar 01 '15 at 19:35
  • http://stackoverflow.com/questions/8827437/is-there-an-efficient-way-to-parallelize-mapply may work – Metrics Mar 01 '15 at 19:42
  • Consider adding an explanation of why this is a good solution. One line of code looks like a poor quality answer, and made it to the review queue for "low quality posts". – Benjamin Mar 02 '15 at 00:43
  • @Benjamin : the solution speaks itself to your question. – Metrics Mar 02 '15 at 00:53
  • @Metrics I don't see what you mean? Should I re-flag as low-quality, and remove my comment to you? – Benjamin Mar 02 '15 at 00:56
  • @Benjamin: I wonder what makes you think one line of code looks like a poor quality if it solves the OP's given problem. Please feel free to exercise your right. – Metrics Mar 02 '15 at 00:59
  • @Metrics: Just trying to hear from you before I agreed with the low quality flag. Since you disagree, I will leave it as is, others can decide. – Benjamin Mar 02 '15 at 01:01
0

If you can't use mapply from @Metrics' answer (when you have too many lowerlist items to write out), something like this might work. I've used magrittr pipe for readability.

n <- length(toplist)
k <- sapply(toplist, length)[1] #assuming that each sublist contains the same number of matrices
num <- seq(1, n*k, by = n)
unlist(toplist, recursive = F) %>% 
    split(., num) %>% 
    lapply(., function(x) do.call(rbind,x))
Khashaa
  • 7,293
  • 2
  • 21
  • 37
  • This seems to do the trick. For my application the number of list entries in toplist can vary rather than the fixed number I have above. Thanks for this. – NWPhy Mar 01 '15 at 19:24