1

I have list of array, and needed to reshape it into dataframe.

Sample input :

> box
[[1]]
, , 1
          [,1]      [,2]      [,3]      [,4]
[1,] -88.44636 -84.29698 -84.29698 -88.44636

, , 2
         [,1]     [,2]    [,3]    [,4]
[1,] 32.28459 32.28459 41.7449 41.7449

[[2]]
NULL

[[3]]
, , 1
         [,1]     [,2]     [,3]     [,4]
[1,] 108.3619 108.4818 108.4818 108.3619

, , 2
          [,1]      [,2]      [,3]      [,4]
[1,] -6.537015 -6.537015 -6.439103 -6.439103

[[4]]
, , 1

         [,1]     [,2]     [,3]     [,4]
[1,] 108.5949 114.2009 114.2009 108.5949

, , 2

         [,1]     [,2]    [,3]    [,4]
[1,] -3.03971 -3.03971 2.08105 2.08105

Input structure:

> str(box)
List of 4
 $ : num [1, 1:4, 1:2] -88.4 -84.3 -84.3 -88.4 32.3 ...
 $ : NULL
 $ : num [1, 1:4, 1:2] 108.36 108.48 108.48 108.36 -6.54 ...
 $ : num [1, 1:4, 1:2] 108.59 114.2 114.2 108.59 -3.04 ...

Desired output:

> bound
         X1        X2        X3        X4        X5        X6        X7        X8
1 -88.44636 -84.29698 -84.29698 -88.44636 32.284593 32.284593 41.744901 41.744901
2        NA        NA        NA        NA        NA        NA        NA        NA
3 108.36186 108.48179 108.48179 108.36186 -6.537015 -6.537015 -6.439103 -6.439103
4 108.59490 114.20087 114.20087 108.59490 -3.039710 -3.039710  2.081050  2.081050

I write codes. It works and gives me desired outpur, but perform very slow :(

bound = NULL
for ( i in 1:length(box) ) {
  if ( !is.null(dim(box[i][[1]])) ) {
    bound = rbind(bound, data.frame(matrix(as.vector(box[i][[1]][1,,]),nrow=1))) 
  } else
    bound = rbind(bound,rep(NA,8))

  if ( i == 1) {
    colnames(bound) = paste("X",1:8,sep="")
  }
}

Can someone give me better solution that simple and fast, to handle the problem? From this discussion, apply family look suitable. But I have no idea how to do.

Community
  • 1
  • 1
nurandi
  • 1,588
  • 1
  • 11
  • 20

1 Answers1

2

Looping (lapply) through the list, we replace the NULL elements with NA, concatenate (c) the non-NULL elements, and rbind to get a matrix output.

m1 <- do.call(rbind,lapply(box, function(x) if(is.null(x)) NA else c(x)))

We can convert this to a data.frame

as.data.frame(m1)

data

box <- list(structure(c(-88.44636, -84.29698, -84.29698, -88.44636, 
32.28459, 32.28459, 41.7449, 41.7449), .Dim = c(1L, 4L, 2L)), 
NULL, structure(c(108.3619, 108.4818, 108.4818, 108.3619, 
-6.537015, -6.537015, -6.439103, -6.439103), .Dim = c(1L, 
4L, 2L)), structure(c(108.5949, 114.2009, 114.2009, 108.5949, 
-3.03971, -3.03971, 2.08105, 2.08105), .Dim = c(1L, 4L, 2L)))
akrun
  • 874,273
  • 37
  • 540
  • 662
  • 1
    Fantastic !!! It performs very fast ... Thank you, @akrun. Then, I have to learn concept of how apply function works. – nurandi Sep 16 '15 at 09:01