Converting array to matrix in R

amisos55 picture amisos55 · Dec 1, 2016 · Viewed 9.2k times · Source

I have an array, including two proficiency variables (theta0, theta1) over an item (Yes, No) called "comp". This needs to be converted to one matrix. Is there any way that I could convert a matrix like the one at the bottom?

My array looks like this:

>priCPT.i6

 , , comp = Yes

 theta1
theta0       Low       Med      High
  Low  0.8377206 0.6760511 0.4576021
  Med  0.6760511 0.4576021 0.2543239
  High 0.4576021 0.2543239 0.1211734

, , comp = No

  theta1
theta0       Low       Med      High
  Low  0.1622794 0.3239489 0.5423979
  Med  0.3239489 0.5423979 0.7456761
  High 0.5423979 0.7456761 0.8788266

attr(,"class")
[1] "CPA"   "array"

I apologize, I could not produce something that you could play with. I am looking for something like:

theta0   theta1   Yes        No
Low      Low      0.8377206  0.1622794
Low      Med      ..         ..
Low      High     ..         ..
Med      Low      ..         ..
Med      Med      ..         ..
Med      High     ..         ..
High     Low      ..         ..
High     Med      ..         ..
High     High     ..         ..

Regards...

Answer

李哲源 picture 李哲源 · Dec 1, 2016

You can easily get columns of values by flattening the matrix on the 3rd margin:

z1 <- apply(priCPT.i6, 3L, c)
## we can also simply use `matrix`; but remember to set `dimnames`
## otherwise we lose dimnames
## z1 <- matrix(priCPT.i6, ncol = 2L,
##              dimnames = list(NULL, dimnames(priCPT.i6)[[3]]))

What you need for the rest is to append the "dimnames" columns:

z2 <- expand.grid(dimnames(priCPT.i6)[1:2])

Now you can merge them into a data frame (you definitely need a data frame than a matrix, because columns of z1 are numeric while columns of z2 are character) via:

data.frame(z2, z1)

Reproducible example

x <- array(1:18, dim = c(3L, 3L, 2L), dimnames = list(
           c("Low", "Medium", "High"), c("Low", "Medium", "High"), c("Yes", "No")))

#, , Yes
#
#       Low Medium High
#Low      1      4    7
#Medium   2      5    8
#High     3      6    9
#
#, , No
#
#       Low Medium High
#Low     10     13   16
#Medium  11     14   17
#High    12     15   18

z1 <- apply(x, 3L, c)
## z1 <- matrix(x, ncol = 2L, dimnames = list(NULL, dimnames(x)[[3]]))
z2 <- expand.grid(dimnames(x)[1:2])
data.frame(z2, z1)

#    Var1   Var2 Yes No
#1    Low    Low   1 10
#2 Medium    Low   2 11
#3   High    Low   3 12
#4    Low Medium   4 13
#5 Medium Medium   5 14
#6   High Medium   6 15
#7    Low   High   7 16
#8 Medium   High   8 17
#9   High   High   9 18