在dplyr summarize或aggregate中使用c()函数聚合字符串

5

我希望使用dplyr中的c()函数来聚合一些字符串。我首先尝试了以下方法:

> InsectSprays$spray = as.character(InsectSprays$spray)
> dt = tbl_df(InsectSprays)
> dt %>% group_by(count) %>% summarize(c(spray))
Error: expecting a single value

但是在aggregate()中使用c()函数可以工作:

> da = aggregate(spray ~ count, InsectSprays, c)
> head(da)
  count                  spray
1     0                   C, C
2     1       C, C, C, C, E, E
3     2             C, C, D, E>

在stackoverflow中搜索提示说,使用paste()和collapse代替c()函数可以解决问题:

dt %>% group_by(count) %>% summarize(s=paste(spray, collapse=","))

或者

dt %>% group_by(count) %>% summarize(paste( c(spray), collapse=","))

我的问题是:为什么在aggregate()中c()函数能够工作,但在dplyr的summarize()中却不能?


1
你也可以使用 toString(),它与 paste(.. , collapse = ", ") 相同。 - talat
2
我认为一个区别是c()返回一个向量,而paste(.. , collapse = ", ")toString返回一个单独的字符串。(这并不真正回答你的问题,我知道)。要看到这一点,请比较str(aggregate(cyl ~ hp, mtcars, toString))str(aggregate(cyl ~ hp, mtcars, c))之间的差异。 - talat
1
如果您想要使用list列,处理更大的数据集,可以使用data.table。例如:DT1 <- data.table(InsectSprays);DT1[, list(spray=list(spray)), keyby=count] - akrun
1
你真的想在聚合列中有列表项吗?还是只是因为你没有注意到(因为从aggregate的输出中看不出来)? - talat
@beginneR:其实,我没有注意到这一点。谢谢你明确指出这个微小的差别。 - Mert Nuhoglu
1个回答

5
如果您仔细看,会发现在使用do()c()实际上确实可以工作(在一定程度上)。但据我所知,dplyr目前不允许这种列表的输出方式。
> InsectSprays$spray = as.character(InsectSprays$spray)
> dt = tbl_df(InsectSprays)
> doC <- dt %>% group_by(count) %>% do(s = c(.$spray))
> head(doC)
Source: local data frame [6 x 2]

  count        s
1     0 <chr[2]>
2     1 <chr[6]>
3     2 <chr[4]>
4     3 <chr[8]>
5     4 <chr[4]>
6     5 <chr[7]>

> head(doC)[[2]]
[[1]]
[1] "C" "C"

[[2]]
[1] "C" "C" "C" "C" "E" "E"

[[3]]
[1] "C" "C" "D" "E"

[[4]]
[1] "C" "C" "D" "D" "E" "E" "E" "E"

[[5]]
[1] "C" "D" "D" "E"

[[6]]
[1] "D" "D" "D" "D" "D" "E" "E"

2
我认为你也可以使用summarise来完成这个任务,请参考https://github.com/hadley/dplyr/issues/832 - hadley
@hadley 请将此作为单独的答案发布,我认为这应该是首选方式。 - mihagazvoda

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接