我想基于两列分割数据帧,但我希望输出是数据帧的二维矩阵,而不是数据帧的平面列表。我可以使用by()
和subset
来实现我想要的但我被告知(我认为Ripley)应该避免在包开发中使用subset
。是否有一个优雅的替代方案(可能使用split
)来保留dimnames?
# sample data
df <- data.frame(x=rnorm(20), y=rnorm(20), v1=rep(letters[1:5],each=4), v2=rep(LETTERS[6:9]))
# what I did previously
submat <- by(df, list(df$v1,df$v2), subset)
dim(submat) # 5 x 4
dimnames(submat) # "a" "b" "c" "d" "e" ; "F" "G" "H" "I"
答案 0 :(得分:2)
要获得您要求的数据帧矩阵,请使用tapply
函数返回特定数据帧子集,但行名称与因子级别相匹配。
> dfmat <- with(df, tapply(1:NROW(df), list(v1,v2), function(idx) df[idx,] ) )
> dfmat[1,1] # items that are in a single dataframe accessed via matrix indexing
[[1]]
x y v1 v2
1 -0.5604756 -1.067824 a F
> dfmat
F G H I
a List,4 List,4 List,4 List,4
b List,4 List,4 List,4 List,4
c List,4 List,4 List,4 List,4
d List,4 List,4 List,4 List,4
e List,4 List,4 List,4 List,4
将列表作为条目的矩阵为print
- 仅显示对象类型和条目数(在本例中为列)。请注意,每个条目都是一个包含一个项目的列表,以便维护dataframe属性,但需要“向下钻取”以获取宝藏:
编辑:添加了dfmat的属性:
> attributes(dfmat)
$dim
[1] 5 4
$dimnames
$dimnames[[1]]
[1] "a" "b" "c" "d" "e"
$dimnames[[2]]
[1] "F" "G" "H" "I"
#------------
> attributes( dfmat[1,1])
NULL
#------------
> attributes( dfmat[1,1][[1]])
$names
[1] "x" "y" "v1" "v2"
$row.names
[1] 1
$class
[1] "data.frame"