我有一个数据框,我想转换为三维数组。数据帧中的一列应作为分组变量,用于将帧拆分为可以组合到阵列中的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可能提供所需的工具,也许是大胆的?
答案 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