[R] Question: concatenating lists

John Fox jfox at mcmaster.ca
Tue Oct 15 04:35:49 CEST 2002


Dear Hein,

On Mon Oct 14 2002 - 17:03:40 CEST, you wrote:


>I have the following problem. I have a number of lists with identical
>structure. Each component is a vector, matrix or array, but components of
>different lists may be of different size. How do I combine the lists to get
>a new list such that each component of this list contains the components of
>the individual lists?
>
>An example may explain most clearly what I need.
>
>Suppose I have three lists:
>list1 <- list(a=1:2,b=matrix(1,2,2))
>list2 <- list(a=3:5,b=matrix(-1,3,3))
>list3 <- list(a=6:9,b=matrix(5,4,4))
>
>The result should give me something like:
>
>$a:
>      [,1] [,2] [,3]
>[1,] 1 3 6
>[2,] 2 4 7
>[3,] NA 5 8
>[4,] NA NA 9
>
>$b:
>, , 1
>      [,1] [,2] [,3] [,4]
>[1,] 1 1 NA NA
>[2,] 1 1 NA NA
>[3,] NA NA NA NA
>[4,] NA NA NA NA
>
>, , 2
>      [,1] [,2] [,3] [,4]
>[1,] -1 -1 -1 NA
>[2,] -1 -1 -1 NA
>[3,] -1 -1 -1 NA
>[4,] NA NA NA NA
>
>, , 3
>      [,1] [,2] [,3] [,4]
>[1,] 5 5 5 5
>[2,] 5 5 5 5
>[3,] 5 5 5 5
>[4,] 5 5 5 5
>
>Any ideas would be much appreciated.

Here's a solution to your problem. I haven't tested it extensively, and 
it's a bit awkward, but it seems to work. I expect that, as is usually the 
case, you'll have several better suggestions shortly.

     combine <- function(...){
         NApad <- function(x, dim){
             result <- array(NA, dim)
             subscript <- as.matrix(do.call("expand.grid", lapply(dim(x), 
function(x) 1:x)))
             result[subscript] <- x
             result
             }
         paste.arrays <- function(...) {
             arrays <- list(...)
             n <- length(arrays)
             d <- dim(arrays[[1]])
             array(unlist(arrays), c(d, n))
             }
         lists <- list(...)
         result <- lists[[1]]
         components <- names(result)
         for (component in components){
             list.components <- lapply(lapply(lists, function(x) 
x[[component]]), as.array)
             d <- do.call("pmax", lapply(list.components, dim))
             result[[component]] <- do.call("paste.arrays",
                 lapply(list.components, function(x) NApad(x, d)))
             }
         result
         }

This assumes that the lists passed as arguments to combine have the same 
elements, and that corresponding elements are vectors or arrays of the same 
dimension (though not necessarily of the same order). Applying the function 
to your example:

     > combine(list1, list2, list3)
     $a
         [,1] [,2] [,3]
     [1,]    1    3    6
     [2,]    2    4    7
     [3,]   NA    5    8
     [4,]   NA   NA    9

     $b
     , , 1

         [,1] [,2] [,3] [,4]
     [1,]    1    1   NA   NA
     [2,]    1    1   NA   NA
     [3,]   NA   NA   NA   NA
     [4,]   NA   NA   NA   NA

     , , 2

         [,1] [,2] [,3] [,4]
     [1,]   -1   -1   -1   NA
     [2,]   -1   -1   -1   NA
     [3,]   -1   -1   -1   NA
     [4,]   NA   NA   NA   NA

     , , 3

         [,1] [,2] [,3] [,4]
     [1,]    5    5    5    5
     [2,]    5    5    5    5
     [3,]    5    5    5    5
     [4,]    5    5    5    5


I hope that this helps,
  John
-----------------------------------------------------
John Fox
Department of Sociology
McMaster University
Hamilton, Ontario, Canada L8S 4M4
email: jfox at mcmaster.ca
phone: 905-525-9140x23604
web: www.socsci.mcmaster.ca/jfox
-----------------------------------------------------

-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-
r-help mailing list -- Read http://www.ci.tuwien.ac.at/~hornik/R/R-FAQ.html
Send "info", "help", or "[un]subscribe"
(in the "body", not the subject !)  To: r-help-request at stat.math.ethz.ch
_._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._



More information about the R-help mailing list