如何在R中将数据帧转换为3d数组

时间:2013-10-23 05:30:59

标签: arrays r

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

# 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可能提供所需的工具,也许是大胆的?

3 个答案:

答案 0 :(得分:9)

听起来你正在寻找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

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


要获得array,你得到了乔希的答案,或者你可以使用基础R的simplify2array

> 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

答案 1 :(得分:8)

以下是我可能会做的事情:

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

答案 2 :(得分:2)

也许我读错了问题,但是MWE描述了一个2x2x2数组(x,y,i(也称为z))。当前的答案似乎提供了提供data.frame数组而不是2D矩阵数组(按OP)的解决方案。 array()会将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