Преобразование массива в матрицу в R

#r #arrays

Вопрос:

У меня есть массив, включающий две переменные квалификации (theta0, theta1) над элементом (Да, нет) под названием «comp». Это должно быть преобразовано в одну матрицу. Есть ли какой-нибудь способ преобразовать матрицу, подобную той, что внизу?

Мой массив выглядит так:

 >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"
 

Прошу прощения, я не смог создать что-то, с чем вы могли бы поиграть. Я ищу что-то вроде:

 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     ..         ..
 

С уважением…

Комментарии:

1. tidyr::spread(as.data.frame.table(priCPT.i6), Var3, Freq)

Ответ №1:

Вы можете легко получить столбцы значений, сгладив матрицу на 3-м поле:

 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]]))
 

Все, что вам нужно для остального, — это добавить столбцы «имена» :

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

Теперь вы можете объединить их в фрейм данных (вам определенно нужен фрейм данных, а не матрица, потому что столбцы z1 числовые, а столбцы z2 символьные) с помощью:

 data.frame(z2, z1)
 

Воспроизводимый пример

 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
 

Комментарии:

1. Спасибо за ваш быстрый и точный ответ. Это полностью ответило на мой вопрос. Я действительно был вам очень признателен. Хорошего вам дня.!

2. а, понятно. Сначала я думал использовать as.data.frame.table(x) : но я не мог найти хорошего способа применить его соответствующим образом, только dcast(as.data.frame.table(x), Var1 Var2 ~ Var3, value.var="Freq") это будет не быстро

3. ftable(x) было бы лучше, если бы он вернул что-то полезное. или dd <- data.frame(as.table(x)); reshape(dd, dir = 'w', idvar = names(dd)[1:2], timevar = names(dd)[3])

4. ах, извините, не видел вашего комментария re: подход dcast

5. Нет, я принял ваш ответ. Не знаю, что случилось. Проверьте еще раз

Ответ №2:

Альтернативой использованию reshape2 было бы

 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
 

Комментарии:

1. Спасибо за вашу полезную запись.