Reputation: 509
I would like to convert a 2D data frame into a 3D matrix, while preserving row and column order.
I have some data like so:
dat<- data.frame(obs = rep(1:3,2),
LET=c('A','A','A','B','B','B'),
x1=c('a','b','c','d','e','f'),
x2=c('g','h','i','j','k','l'))
obs LET x1 x2
1 1 A a g
2 2 A b h
3 3 A c i
4 1 B d j
5 2 B e k
6 3 B f l
And I'd like to create a 3D matrix, where the output looks like this:
, , 1
[,1] [,2] [,3] [,4]
[1,] "1" "A" "a" "g"
[2,] "1" "B" "d" "j"
, , 2
[,1] [,2] [,3] [,4]
[1,] "2" "A" "b" "h"
[2,] "2" "B" "e" "k"
, , 3
[,1] [,2] [,3] [,4]
[1,] "3" "A" "c" "i"
[2,] "3" "B" "f" "l"
Where each "layer" is a different obs
of two LET
s and their x values.
When I do dim(dat) <- c(2,4,3)
the order isn't preserved the way I'd like it to be, I'm not sure how to shape it in order to get the right format.
Upvotes: 3
Views: 212
Reputation: 887223
One option is split
the data into a list
, create an array
of specified dim
ensions and assign the values of the list
to it
lst1 <- split(dat, dat$obs)
ar1 <- array(dim = c(dim(lst1[[1]]), length(lst1)))
for(i in seq_along(lst1)) ar1[,,i] <- as.matrix(lst1[[i]])
ar1
#, , 1
# [,1] [,2] [,3] [,4]
#[1,] "1" "A" "a" "g"
#[2,] "1" "B" "d" "j"
#, , 2
# [,1] [,2] [,3] [,4]
#[1,] "2" "A" "b" "h"
#[2,] "2" "B" "e" "k"
#, , 3
# [,1] [,2] [,3] [,4]
#[1,] "3" "A" "c" "i"
#[2,] "3" "B" "f" "l"
Or convert to character
class for all the columns, do the split
, unlist
the list
and create the array
dat[] <- lapply(dat, as.character)
lst1 <- split(dat, dat$obs)
array(unlist(lst1), c(dim(lst1[[1]]), length(lst1)))
Upvotes: 2