16

我有一个要转换为三维数组的数据框。数据框中的一列应用作分组变量,用于将帧拆分为可组合成数组的二维矩阵。在下面的最小工作示例中,数据帧应由变量“i”拆分为矩阵,然后组合成一个 4x4x2 数组。该解决方案对于大型数据集应该是实用的,理想情况下可以推广到将数据帧转换为维度数组。

# Make reproducible 
set.seed(123)

df <- {
  data.frame(i=rep(1:2, each=4),
             x=rep(rep(0:1, each=2), 2),
             y=rep(rep(0:1, 2), 2),
             l=rnorm(8))
}

df
#   i x y           l
# 1 1 0 0 -0.56047565
# 2 1 0 1 -0.23017749
# 3 1 1 0  1.55870831
# 4 1 1 1  0.07050839
# 5 2 0 0  0.12928774
# 6 2 0 1  1.71506499
# 7 2 1 0  0.46091621
# 8 2 1 1 -1.26506123

注意:我怀疑 Hadley Wickham 的 plyr 可能会提供所需的工具,也许是 daply?

4

3 回答 3

11

这是我可能会做的事情:

library(abind)
abind(split(df, df$i), along=3)
# , , 1
# 
#   i x y           l
# 5 1 0 0 -0.56047565
# 6 1 0 1 -0.23017749
# 7 1 1 0  1.55870831
# 8 1 1 1  0.07050839
# 
# , , 2
# 
#   i x y          l
# 5 2 0 0  0.1292877
# 6 2 0 1  1.7150650
# 7 2 1 0  0.4609162
# 8 2 1 1 -1.2650612
于 2013-10-23T05:52:16.780 回答
10

听起来您正在寻找split

> split(df, df$i)
$`1`
  i x y           l
1 1 0 0 -0.56047565
2 1 0 1 -0.23017749
3 1 1 0  1.55870831
4 1 1 1  0.07050839

$`2`
  i x y          l
5 2 0 0  0.1292877
6 2 0 1  1.7150650
7 2 1 0  0.4609162
8 2 1 1 -1.2650612

这会导致由您的“i”列分隔list的两个s。data.frame


要得到一个array,你已经得到了 Josh 的答案,或者你可以simplify2array从 base R 中使用:

> simplify2array(by(df, df$i, as.matrix))
, , 1

  i x y           l
1 1 0 0 -0.56047565
2 1 0 1 -0.23017749
3 1 1 0  1.55870831
4 1 1 1  0.07050839

, , 2

  i x y          l
1 2 0 0  0.1292877
2 2 0 1  1.7150650
3 2 1 0  0.4609162
4 2 1 1 -1.2650612
于 2013-10-23T05:34:38.183 回答
5

也许我读错了问题,但 MWE 描述了一个 2x2x2 数组(x,y,i(又名 z))。当前的答案似乎提供了提供 data.frames 数组而不是 2D 矩阵数组(每个 OP)的解决方案。array()将 a 转换data.frame为 n 维矩阵数组:

dfa <- array(data = df$l, 
             dim=c(length(unique(df$x)), 
                   length(unique(df$y)), 
                   length(unique(df$i))), 
             dimnames=list(unique(df$x), unique(df$y), unique(df$i))
            )
dfa
> dfa
, , 1

           0          1
0 -0.5604756 1.55870831
1 -0.2301775 0.07050839

, , 2

          0          1
0 0.1292877  0.4609162
1 1.7150650 -1.2650612
于 2018-09-21T02:38:02.787 回答