Converting array to matrix in R
11,165
Solution 1
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
Solution 2
An alternative using reshape2 would be
x <- array(1:18, dim = c(3L, 3L, 2L), dimnames = list(
c("Low", "Medium", "High"),
c("Low", "Medium", "High"),
c("Yes", "No")))
library(reshape2)
df <- dcast(melt(x), Var1+Var2~Var3)
df
Var1 Var2 Yes No
1 Low Low 1 10
2 Low Medium 4 13
3 Low High 7 16
4 Medium Low 2 11
5 Medium Medium 5 14
6 Medium High 8 17
7 High Low 3 12
8 High Medium 6 15
9 High High 9 18
Author by
amisos55
Updated on June 21, 2022Comments
-
amisos55 almost 2 years
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...
-
amisos55 over 7 yearsThanks for your fast and accurate reply. This totally answered my question. I really appreciated. Have a great day.!
-
user20650 over 7 yearsah I see. I initially thought of using
as.data.frame.table(x)
: but I couldnt see a nice way to apply appropriately, onlydcast(as.data.frame.table(x), Var1 + Var2 ~ Var3, value.var="Freq")
which will not be fast -
rawr over 7 years
ftable(x)
would be best if it returned something useful. ordd <- data.frame(as.table(x)); reshape(dd, dir = 'w', idvar = names(dd)[1:2], timevar = names(dd)[3])
-
gfgm over 7 yearsah sorry didn't see your comment re: dcast approach
-
amisos55 over 7 yearsThanks for your helpful entry.
-
amisos55 over 7 yearsNo, I accepted your answer. Do not know what happened. Check one more time