说我有这个data.frame
data <- data.frame(foo = c(1, 1, 2, 2 ),
bar = c(10,10,10,20),
baz = c(1, 2, 3, 4 ),
qux = c(5, 6, 7, 8 ))
我想通过 foo
和 bar
列对其进行分组以达到此目的:
expected <- list(
data.frame(foo = c(1, 1),
bar = c(10, 10),
baz = c(1, 2),
qux = c(5, 6)),
data.frame(foo = 2,
bar = 10,
baz = 3,
qux = 7),
data.frame(foo = 2,
bar = 20,
baz = 4,
qux = 8)
)
我可以为每个组生成一个行,但是我找不到 MATCH
函数;给定带有列 foo,bar,baz,qux
的输入框架和带有列 foo,bar
的过滤器框架时返回 foo,bar
单元格内容匹配的行 .
groups <- unique(data[c("foo","bar")])
MATCH(data, groups[1,]) == expected[[1]]
MATCH(data, groups[2,]) == expected[[2]]
MATCH(data, groups[3,]) == expected[[3]]
或更高级别的 GROUP
函数,它只返回一个帧列表,其中给定的列匹配:
GROUP(data, by=c("foo","bar")) == expected
我最接近的是
out <- aggregate(. ~ foo + bar, data, list)
单元格 baz
, qux
是列表:
> out
foo bar baz qux
1 1 10 1, 2 5, 6
2 2 10 3 7
3 2 20 4 8
> class(out[,"baz"])
[1] "list"
所以每个组都是 out
中的一行,但是如何再次展开它,以便 out[1,]
成为一个包含两行的data.frame,如 expected[[1]]
?
3 回答
看起来你只需要
split
.Option 1 :保留"foo"和"bar"组合的所有"levels",即使它导致空
data.frame
.Option 2 :删除"foo"和"bar"组合的空"levels" - 就像在预期输出中一样 .
来自
plyr
的dlply
就是为此目的而设计的:试试这个,就像@Ananda的解决方案,但使用
interaction
: