SamPassmore
SamPassmore

Reputation: 1365

Subsetting a matrix created from a list of lists

I am having some trouble manipulating a matrix that I have created from a list of lists. I don't really understand why the resulting matrix doesn't act like a normal matrix. That is, I expect when I subset a column for it to return a vector, but instead I get a list. Here is a working example:

x = list()
x[[1]] = list(1, 2, 3)
x[[2]] = list(4, 5, 6)
x[[3]] = list(7, 8, 9)

y = do.call(rbind, x)
y
     [,1] [,2] [,3]
[1,] 1    2    3   
[2,] 4    5    6   
[3,] 7    8    9  

y is in the format that I expect. Ultimately I will have a list of these matrices that I want to average, but I keep getting an error which appears to be due to the fact that when you subset this matrix you get lists instead of vectors.

y[,1]
[[1]]
[1] 1

[[2]]
[1] 4

[[3]]
[1] 7

Does anyone know a) why this is happening? and b) How I could avoid / solve this problem?

Thanks in advance

Upvotes: 0

Views: 271

Answers (3)

juliamm2011
juliamm2011

Reputation: 136

do.call passes the argument for each list separately, so you are really just binding your three lists together. This explains why they are in list format when you call the elements.

Unlist x and then use sapply to create your matrix. Since R defaults to filling columns first, you'll need to transpose it to get your desired matrix.

y <- t(sapply(x, unlist))

Upvotes: 0

Sean
Sean

Reputation: 11

It looks like the problem is due to x being a list of lists, rather than a list of vectors. This is not great, but it'll work:

y = do.call(rbind, lapply(x, unlist))

Upvotes: 1

Zheyuan Li
Zheyuan Li

Reputation: 73265

This is just another problem with "matrix of list". You need

do.call(rbind, lapply(x, unlist))

or even simpler:

matrix(unlist(x), nrow = length(x), byrow = TRUE)

If you need some background reading, see: Why a row of my matrix is a list. That is a more complex case than yours.

Upvotes: 1

Related Questions