[R] list to matrix?

William Dunlap wdunlap at tibco.com
Wed Dec 5 00:28:49 CET 2012


> No need for all this (see solutions including mine already given) --
> but even without those, this is silly. An identity map is a real waste
> if you just want the simplification bit of sapply() -- you'd be much
> better just using simplify2array()

You are right that simplify2array(p) does everything that sapply(p,function(x)x)
does and does it more quickly and that matrix(unlist(p),nrow=2,byrow=TRUE)
is much faster than either:

  > p <- lapply(1:1e6, function(i)c(i, log2(i)))
  > system.time(z1 <- t(sapply(p,function(x)x)))
     user  system elapsed 
      1.2     0.0     1.2 
  > system.time(z2 <- t(simplify2array(p)))
     user  system elapsed 
      0.91    0.00    0.90 
  > system.time(z3 <- matrix(unlist(p), ncol=2, byrow=TRUE))
     user  system elapsed 
     0.04    0.00    0.04

You can also use vapply instead of sapply - it requires that you supply
the expect shape and type of FUN's output so it is doesn't have to figure
this out from looking at all the outputs of FUN: 
  > system.time(z4 <- t(vapply(p,FUN=function(x)x,FUN.VALUE=numeric(2))))
     user  system elapsed 
     0.56    0.00    0.56 

An advantage of vapply is that it stops in its tracks if FUN returns
an unexpected value.  sapply() and simplify2array() will silently give
you an unexpected result (a single column matrix of mode list 
instead of a vector of numbers)  and matrix(unlist()...) gives you a
warning if you are lucky.
  > pBad <- p ; pBad[[length(pBad)/2]] <- 666
  > system.time(zBad1 <- t(sapply(pBad,function(x)x)))
     user  system elapsed 
     1.75    0.00    1.75 
  > zBad1[,499999:500001] # not what we wanted
  [[1]]
  [1] 499999.00000     18.93157

  [[2]]
  [1] 666
  
  [[3]]
  [1] 500001.00000     18.93157
  > system.time(zBad2 <- t(simplify2array(pBad)))
     user  system elapsed 
      0.5     0.0     0.5 
  > system.time(zBad3 <- matrix(unlist(pBad), ncol=2, byrow=TRUE))
     user  system elapsed 
     0.03    0.00    0.03 
  Warning message:
  In matrix(unlist(pBad), ncol = 2, byrow = TRUE) :
    data length [1999999] is not a sub-multiple or multiple of the number of rows [1000000]
  > # no warning if length(unlist(p)) were even
  > system.time(zBad4 <- t(vapply(pBad,function(x)x,numeric(2))))
  Error in vapply(pBad, function(x) x, numeric(2)) : 
    values must be length 2,
   but FUN(X[[500000]]) result is length 1
  Timing stopped at: 0.29 0 0.28

Which of the latter two methods you choose depends on how likely errors
in the data are.

Bill Dunlap
Spotfire, TIBCO Software
wdunlap tibco.com


> -----Original Message-----
> From: r-help-bounces at r-project.org [mailto:r-help-bounces at r-project.org] On Behalf
> Of R. Michael Weylandt
> Sent: Tuesday, December 04, 2012 2:59 PM
> To: arun
> Cc: R help; sds at gnu.org
> Subject: Re: [R] list to matrix?
> 
> On Tue, Dec 4, 2012 at 8:17 PM, arun <smartpink111 at yahoo.com> wrote:
> > Hi,
> > Try this:
> > list1<-list(c(50000, 101), c(1e+05, 46), c(150000, 31), c(2e+05, 17),
> >     c(250000, 19), c(3e+05, 11), c(350000, 12), c(4e+05, 25),
> >     c(450000, 19), c(5e+05, 16))
> >
> >
> > res<-t(sapply(list1,function(x) x))
> 
> Bah Humbug! (In Christmas cheer)
> 
> No need for all this (see solutions including mine already given) --
> but even without those, this is silly. An identity map is a real waste
> if you just want the simplification bit of sapply() -- you'd be much
> better just using simplify2array()
> 
> Michael
> 
> ______________________________________________
> R-help at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-help
> PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
> and provide commented, minimal, self-contained, reproducible code.




More information about the R-help mailing list