R 按+拆分vs;子集

R 按+拆分vs;子集,r,split,names,R,Split,Names,我希望基于两列分割数据帧,但我希望输出是数据帧的二维矩阵,而不是数据帧的平面列表。使用by()和subset我可以实现我想要的,但是我被告知(我认为是Ripley)在包开发中应该避免使用subset。是否有一种优雅的替代方法(可能使用拆分)来保留DIMNAME # sample data df <- data.frame(x=rnorm(20), y=rnorm(20), v1=rep(letters[1:5],each=4), v2=rep(LETTERS[6:9])) # what

我希望基于两列分割数据帧,但我希望输出是数据帧的二维矩阵,而不是数据帧的平面列表。使用
by()
subset
我可以实现我想要的,但是我被告知(我认为是Ripley)在包开发中应该避免使用
subset
。是否有一种优雅的替代方法(可能使用
拆分
)来保留DIMNAME

# 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"
#示例数据

df要获得所需的数据帧矩阵,请将
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

如果您检查
str(submat)
的结果,您将看到它实际上是一个20个的平面列表,其中包含一些由
调用
提供的附加属性。在这种情况下,使用
identity
函数代替subset似乎可以得到相同的结果。我很好奇为什么你需要保留矩阵的维数。以下是我所谈论的
identity
by(df,list(df$v1,df$v2),identity)
已接受(按我的要求执行)。尽管根据Chase上面的评论,我现在意识到我真正想知道的是如何获得
split
,根据传递给它的
列表创建
dim
dimnames
属性,以及(后续)如何获取
lappy
以在此处未显示的后续步骤中保留这些维度。我不确定是否理解。返回的矩阵确实具有从因子级别构造的DIMNAME。也许有一个新问题要问?我希望我没有通过显示项目的属性而不是dfmat的所有不同属性来迷惑您。没错,您的解决方案满足了我的要求(创建DIM和DIMNAME)。接下来的问题可能会出现一个新问题(获取
lappy
或类似内容以保留这些属性)。
>  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"