[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