说我有这个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 ))
Run Code Online (Sandbox Code Playgroud)
我想通过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)
)
Run Code Online (Sandbox Code Playgroud)
我可以为每个组生成一个行,但是我找不到一个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]]
Run Code Online (Sandbox Code Playgroud)
或者更高级别的GROUP函数,它只返回一个框架列表,给定的列匹配:
GROUP(data, by=c("foo","bar")) == expected
Run Code Online (Sandbox Code Playgroud)
我最接近的是
out <- aggregate(. ~ foo + bar, data, list)
Run Code Online (Sandbox Code Playgroud)
当细胞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"
Run Code Online (Sandbox Code Playgroud)
所以每个组都是一行out,但是我如何再次展开它,这样out[1,]就成了一个有两行的data.frame,比如expected[[1]]?
看起来你只需要split.
选项1:保留"foo"和"bar"组合的所有"级别",即使它导致空data.frame.
> split(data, list(data$foo, data$bar))
$`1.10`
foo bar baz qux
1 1 10 1 5
2 1 10 2 6
$`2.10`
foo bar baz qux
3 2 10 3 7
$`1.20`
[1] foo bar baz qux
<0 rows> (or 0-length row.names)
$`2.20`
foo bar baz qux
4 2 20 4 8
Run Code Online (Sandbox Code Playgroud)
选项2:删除"foo"和"bar"组合的空"级别" - 就像您在预期输出中所做的那样.
> split(data, list(data$foo, data$bar), drop=TRUE)
$`1.10`
foo bar baz qux
1 1 10 1 5
2 1 10 2 6
$`2.10`
foo bar baz qux
3 2 10 3 7
$`2.20`
foo bar baz qux
4 2 20 4 8
Run Code Online (Sandbox Code Playgroud)