如何在R中按两列分组

27

我有一个数据框,希望对其进行分组,并根据两列进行求和。这两列是字符型数据,其中一列是月份,另一列是变量。

以下是数据框的样例及结构。

#row.names   month    variable   amount
  1          1-Jan       x        1000
  2          1-Jan       x        3000
  3          2-Feb       z        5000
  4          2-Feb       y        3000 

我试图首先对数据进行分组,然后尝试进行总结,但是我无法让group_by_()函数发挥作用。以下是我尝试的代码。

byVarMonth <- group_by_(df, variable, (as.date(month)))

感谢您的帮助。


(1) 使用 group_by() (2) 这是 as.Date() (3) 你需要在 as.Date() 中指定一个格式 - Rich Scriven
那么 group_by(df, variable, month = months(as.Date(month, "%d-%b"), TRUE)) 应该可以完成,但我真的看不出将该列转换为日期的原因。您可以按原样对其进行分组。 - Rich Scriven
4个回答

34

你似乎不想将你的Character [month]作为日期变量处理。考虑到我的理解是正确的,你可以简单地这样做:

library(dplyr)

tab %>%
  group_by(month, variable) %>%
  summarise(a_sum=sum(amount),
            a_mean=(mean(amount)))

并且听好了:

Source: local data frame [3 x 4]
Groups: month

  month variable a_sum a_mean
1 1-Jan        x  4000   2000
2 2-Feb        y  3000   3000
3 2-Feb        z  5000   5000

3
这是一个有些老式的解决方案,但可以使用内置的R函数aggregate来实现,无需安装dplyr
res <- aggregate(amount ~ variable + month, 
  data=df, 
  function(x) { 
    c(sum=sum(x), avg=mean(x)) 
})

第一个参数是一个公式。在 ~ 左边指定要聚合的列,在右边按+分隔列名以进行分组。第二个参数 data= 指定输入数据框。最后,第三个参数是一个函数,它接受向量 x(每个组选定的值)并返回标量或各种汇总结果的向量(这里我们计算每个组中 amount 的总和和平均数,参见例如此 SO 答案)。

如果您打印 res,它会像这样:

variable month amount.sum amount.avg
1        x 1-Jan       4000       2000
2        y 2-Feb       3000       3000
3        z 2-Feb       5000       5000

然而,你没有看到的是,最后两列实际上是一个由长度为2的向量组成的单独一列(运行dim(res)来验证)。要将该最后一列拆分为两个列,请执行以下操作(灵感来源于这个 SO 帖子):

res <- do.call(data.frame, res)

请注意,aggregate 函数可以使用其他参数调用,请参考 ?aggregate 以获取详细信息。


2

...或者,您可以使用另一种语法:

summarise(group_by(df, variable), sum(amount), mean(amount))

享受。


0

dplyr 1.1.0引入了.by参数,用于一次性分组操作的mutatesummarize函数(请注意,在本文发布时,该参数处于实验生命周期):

df %>% 
  summarize(total = sum(amount),
            .by = c(month, variable))

.by接受整洁选择器助手,以便更简洁地选择列。


.bygroup_by

使用这个参数和group_by函数的区别在于,.bysummarize(或mutate)之后自动取消分组,返回一个数据帧对象。除非您在使用group_by之后取消分组(或使用summarize中的.groups参数),否则您将得到一个分组数据帧对象,这可能会对管道链产生意想不到的影响。summarize在这种情况下会发出警告,因为很容易忽略。只是需要注意的一些事情,因为大多数时候数据需要被取消分组。

df %>% 
  summarize(total = sum(amount),
            .by = c(month, variable)) %>% 
  class()
[1] "data.frame"

df %>% 
  group_by(month, variable) %>% 
  summarize(total = sum(amount)) %>% # pipe to ungroup() or use .groups arg to get a data frame
  class()

`summarise()` has grouped output by 'month'. You can override using the `.groups`
argument.
[1] "grouped_df" "tbl_df"     "tbl"        "data.frame"

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