[R] Can a matrix have 'list' as rows/columns?

William Dunlap wdunlap at tibco.com
Thu Apr 19 02:35:20 CEST 2012


> -----Original Message-----
> From: Worik R [mailto:worikr at gmail.com]
> Sent: Wednesday, April 18, 2012 5:05 PM
> To: William Dunlap
> Cc: r-help
> Subject: Re: [R] Can a matrix have 'list' as rows/columns?
> 
> [snip]
> >
> > sapply.  In this case I would expect M to be a list.  I am gobsmacked that
> > > a list can be considered a vector.    Is that a bug?  It must be bad design?
> > >
> > > I have been using R for a number of years (5?) and heavilly for two years.
> > > I am still getting bitten by these "features" in R.  To my mind there are
> > > many places that R violates the *principle of least surprise.  But it may
> > > be my mind that is at fault!  What are other people's experience?*
> >
> > Since a matrix may contain logical, integer, numeric (double precision),
> > complex, and character data, I would be surprised if it didn't also handle
> > list data.  I am surprised that a matrix cannot contain factor data.
> 
> 
> logical, integer, double, complex and character are all atomic.
> Usually, where I have been (have I been in the wrong places?) a vector
> is a one dimensional ordered collection of homogeneously typed atomic
> things.  A matrix an ordered  collection of  vectors, all the same
> type and length.

It will be more fruitful in R to think of a vector as a thing that can
be subscripted by one subscript and a matrix as something that
can be subscripted by two.  (This is not exactly how a matrix is defined,
but I find it is good way to think about them.)  A matrix should definitely
not be thought of as "an ordered collection of vectors, all the same type
and length".  It is just a vector with an attribute called "dims" that
lets you subscript with 2 indices.

I have used a matrix(list(...),...) to conveniently contain remote
sensing observations binned by latitude and longitude.  Each bin
may contain any number of observations.

> A list is R's hold all type.  It has a count of things in it, but each
> thing is an arbitrary thing in itself.  It could be another list, or
> whatever.  Elsewhere on this thread there are some helpful examples of
> how lists must be changed to be forced into a matrix or to be a
> vector.
> 
> That is the violation of  the "Least Astonishment Principle".
> 
> Here is an example I just made up...
> 
> > L <- list()
> > L[[1]] <- list()
> > L[[1]][[1]] <- TRUE
> > L[[1]][["ABC"]] <- pi
> > L
> [[1]]
> [[1]][[1]]
> [1] TRUE
> 
> [[1]]$ABC
> [1] 3.141593
> 
> 
> > V <- as.vector(L)
> > V
> [[1]]
> [[1]][[1]]
> [1] TRUE
> 
> [[1]]$ABC
> [1] 3.141593

Note that as.vector just strips the attributes (except for the names)
from the input list.  Bare lists are vectors.  Hence V and L are identical.

>  M <- matrix(L, ncol=2, nrow=3)
>  M
>      [,1]   [,2]
> [1,] List,2 List,2
> [2,] List,2 List,2
> [3,] List,2 List,2
> 
> > V[2] <- list()
> Error in V[2] <- list() : replacement has length zero

Compare this to an atomic vector - there is no difference in behavior:
    > a <- 1 # a length 1 atomic vector
    > a[2] <- numeric()
    Error in a[2] <- numeric() : replacement has length zero
You cannot replace a 1-long part of a vector with a 0-long vector.
(If you could, I suppose it would be a no-op.)

With a list you can do
   V[[2]] <- list()
because V[[2]] refers to the 2nd element of the list, not the
sublist of length 1 that contains the 2nd element that V[2]
means.


Bill Dunlap
Spotfire, TIBCO Software
wdunlap tibco.com



   
> 
> > L2 <- list()
> > L2[[1]] <- "asd"
> > V[2] <- L2
> > class(V)
> [1] "list"
> 
> > V2 <- as.vector(V)
> > length(V2)
> [1] 2
> > V2[1]
> [[1]]
> [[1]][[1]]
> [1] TRUE
> 
> [[1]]$ABC
> [1] 3.141593
> 
> 
> > V2[2]
> [[1]]
> [1] "asd"
> 
> 
> That is astonishing to me!  I had no way to predict what would happen.
>  5 days ago I would have expected the statement "as.vector(L)" to
> produce an error.  "V[2] <- list()" did.
> 
> cheers
> Worik



More information about the R-help mailing list