将3D数组转换为数据框列表

时间:2019-10-26 08:33:17

标签: r arrays dataframe dplyr data.table

基本上,我想按其列对3D数组进行分组,将其转换为数据框,然后将其绑定到一个新列,该列的值等于所有现有列的总和。

例如,考虑以下3D阵列

> (src <- array(1:8, c(2, 2, 2), dimnames=list(c('X1', 'X2'), c('Y1', 'Y2'), 1:2)))
, , 1

   Y1 Y2
X1  1  3
X2  2  4

, , 2

   Y1 Y2
X1  5  7
X2  6  8

我想将其转换为

> (dest <- list(Y1=data.frame(X1=c(1, 5), X2=c(2, 6), Y1=c(1, 5)+c(2, 6)),
                Y2=data.frame(X1=c(3, 7), X2=c(4, 8), Y2=c(3, 7)+c(4, 8))))
$Y1
  X1 X2 Y1
1  1  2  3
2  5  6 11

$Y2
  X1 X2 Y2
1  3  4  7
2  7  8 15

我知道如何对原始数组中的每个列进行转换,但是不知道如何同时处理多个列。

> library(dplyr)
> as.data.frame(t(src[, 'Y1', ])) %>% mutate(Y1=X1+X2)
  X1 X2 Y1
1  1  2  3
2  5  6 11

随时使用基数R,dplyrdata.table或您喜欢的任何包,只要它足够快即可。在实际应用中,dim(src)往往类似于c(hundreds, tens, tens of thousands)

1 个答案:

答案 0 :(得分:2)

我们可以首先在转置数组的边距apply上进行data.frame 2转换,在这里我们用aperm()进行数组转置。然后,我们以类似的方式处理colSums。为了获得正确的名称"Y1", "Y2",我们进行了一个临时步骤,将列作为数据框列出。最后,Map逐个元素评估两个列表(X*Y*的求和)。

dest <- Map(cbind, apply(aperm(src, c(3, 2, 1)), 2, data.frame), 
    {tmp <- data.frame(apply(src, 2, colSums));list(tmp[1], tmp[2])})
dest
# $Y1
#   X1 X2 Y1
# 1  1  2  3
# 2  5  6 11
# 
# $Y2
#   X1 X2 Y2
# 1  3  4  7
# 2  7  8 15