> From: Liaw, Andy [mailto:andy_liaw at merck.com]
>
> Dear R-help,
>
> Is it a violation of the S language to have a matrix of
> factors? What I would like to have is just a factor object
> that has dim attribute, and can be printed (and subsetted)
> like a matrix; i.e., all columns/rows have the identical
> levels. However, I can't get it to work:
>
> > x <- factor(sample(2, 10, replace=TRUE))
> > dim(x)<- c(5,2)
> > x
> [1] 1 2 2 1 2 1 1 1 2 1
> Levels: 1 2
> > str(x)
> int [1:5, 1:2] 1 2 2 1 ...
> - attr(*, "levels")= chr [1:2] "1" "2"
> - attr(*, "class")= chr "factor"
> > x[1,]
> factor(0)
> Levels: 1 2
>
> (This is R 1.7.1 on WinXPPro.)
This is wierder than I thought! Try:
> x[,1]
[1] 1 2 2 1 2
Levels: 1 2> x[2,]
factor(0)
Levels: 1 2
I.e., column extraction "works", but not row extraction.
> y <- factor(1:12)
> dim(y) <- c(3,4)
> y[,1]
[1] 1 2 3
Levels: 1 2 3> y[1,1]
[1] 1
Levels: 1> y[1,]
factor(0)
Levels: 1 2 3 4 5 6 7 8 9 10 11 12> y[1, 1:ncol(y)]
[1] 1 4 7 10
Levels: 1 4 7 10
Warning message:
the condition has length > 1 and only the first element will be used in: if
(drop) factor(y) else y
Column extraction and element extraction "work", but notice the unused
levels mysteriously disappeared! The last warning also seems strange.
> is.matrix(y)
[1] TRUE> class(y)
[1] "factor"
This also baffles me: Given a numeric vector, (say y <- 1:12, dim(y) <-
3:4
will give y the "matrix" class. Yet if I do this with a factor, it
doesn't!
Apparently that's not what is.matrix tests for.
> The alternative is to have a list instead, where each
> "column" makes up a component of the list. But it would be
> nice to have the matrix...
Short of as.list(as.data.frame(matrix))), does anyone know of an efficient
way to turn a matrix into a list with each component containing a column?
Best,
Andy