我很难将正确的数据放入我的 4x3x21 数组的矩阵中

I'm having difficulty getting the right data into the matrices of my 4x3x21 array

我遇到的问题是我希望这个矩阵 (mat.a) 的第一行是我数组中矩阵 1 的第一行,然后第二行是矩阵 2 的第一行等。然后 mat.b 的第一行成为我数组中第一个矩阵的第二行,mat 的第二行。 b 是数组第二个矩阵中的第二行,依此类推。这种趋势持续 mat.c。我的矩阵的第四行应该是每列中值的平均值。另外,我不允许使用 for 循环

mat.a <- matrix(c(scores$A1, scores$A2, scores$avgA), ncol = 3, 
byrow = FALSE)
mat.b <- matrix(c(scores$B1, scores$B2, scores$avgB), ncol = 3, 
byrow = FALSE)
mat.c <- matrix(c(scores$C1, scores$C2, scores$avgC), ncol = 3, 
byrow = FALSE)

scores.array<- array(c(mat.a,mat.b, mat.c), dim = c(3,3,21))


> dim(mat.a)
[1] 21  3
> dim(scores)
[1] 21 10
> dim(mat.b)
[1] 21  3
> dim(mat.c)
[1] 21  3

scores scores.updated

试试这个:

library(tidyverse)
# add the averages 
scores <- scores %>%
  rowwise() %>%
  mutate(avg1 = mean(c_across(ends_with("1"))),
         avg2 = mean(c_across(ends_with("2"))),
         avg3 = mean(c_across(starts_with("avg")))) %>% 
  # relocate the columns
  relocate(ini, A1,B1,C1,avg1, A2,B2,C2,avg2, avgA,avgB,avgC, avg3)

# create scores array
scores.array = array(scores %>% pivot_longer(cols = A1:avg3) %>% pull(value), dim=c(4,3,21))

# add dim names
dimnames(scores.array) = list(c("A","B","C","mean"), c("Midterm", "Final", "mean"), scores$ini)

输出(前两个):

> scores.array[,,1:2]
, , ZO

      Midterm    Final     mean
A    28.75775 69.28034 49.01905
B    41.37243 27.43836 34.40540
C    10.28646 89.03502 49.66074
mean 26.80555 61.91791 44.36173

, , UE

      Midterm    Final     mean
A    78.83051 64.05068 71.44060
B    36.88455 81.46400 59.17427
C    43.48927 91.44382 67.46655
mean 53.06811 78.98617 66.02714

输入数据(假数据):

set.seed(123)
scores = data.frame(
  A1 = runif(21)*100,
  A2 = runif(21)*100,
  B1 = runif(21)*100,
  B2 = runif(21)*100,
  C1 = runif(21)*100,
  C2 = runif(21)*100
)

scores <- scores %>% rowwise() %>% 
  mutate(ini = paste0(sample(LETTERS,2), collapse="")) %>% 
  relocate(ini)

scores$avgA = apply(scores[,c("A1","A2")],1,mean)
scores$avgB = apply(scores[,c("B1","B2")],1,mean)
scores$avgC = apply(scores[,c("C1","C2")],1,mean)
  
   ini      A1    A2    B1    B2    C1    C2  avgA  avgB  avgC
   <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
 1 ZO    28.8   69.3 41.4   27.4  10.3 89.0   49.0  34.4  49.7
 2 UE    78.8   64.1 36.9   81.5  43.5 91.4   71.4  59.2  67.5
 3 HS    40.9   99.4 15.2   44.9  98.5 60.9   70.2  30.0  79.7
 4 JR    88.3   65.6 13.9   81.0  89.3 41.1   76.9  47.4  65.2
 5 JL    94.0   70.9 23.3   81.2  88.6 14.7   82.4  52.3  51.7
 6 BJ     4.56  54.4 46.6   79.4  17.5 93.5   29.5  63.0  55.5
 7 VL    52.8   59.4 26.6   44.0  13.1 30.1   56.1  35.3  21.6
 8 TN    89.2   28.9 85.8   75.4  65.3  6.07  59.1  80.6  35.7
 9 QN    55.1   14.7  4.58  62.9  34.4 94.8   34.9  33.8  64.6
10 VC    45.7   96.3 44.2   71.0  65.7 72.1   71.0  57.6  68.9
# ... with 11 more rows

这是解决这个问题的自然(我认为)方法:

  1. 使用 array 构造一个数组,其中 A、B 和 C 位于第三维。
  2. 使用 aperm 转置数组,使 A、B 和 C 位于第一维。
  3. 使用 colMeans 计算第一个维度(“按列”)的均值。
  4. 使用abind将均值附加到转置数组。
nms <- c("A1", "A2", "avgA", "B1", "B2", "avgB", "C1", "C2", "avgC")
z <- array(unlist(scores[nms]), dim = c(21L, 3L, 3L))
zz <- aperm(zz, 3:1)
zzz <- abind::abind(zz, colMeans(zz, dims = 1L), along = 1L)
zzz[, , 1:2]
, , 1

         [,1]     [,2]     [,3]
[1,] 28.75775 69.28034 49.01905
[2,] 41.37243 27.43836 34.40540
[3,] 10.28646 89.03502 49.66074
[4,] 26.80555 61.91791 44.36173

, , 2

         [,1]     [,2]     [,3]
[1,] 78.83051 64.05068 71.44060
[2,] 36.88455 81.46400 59.17427
[3,] 43.48927 91.44382 67.46655
[4,] 53.06811 78.98617 66.02714

我使用了 scores 作为(非常有帮助!)由@langtang 定义。