group_by 和有条件地变异 + 计数

Posted

技术标签:

【中文标题】group_by 和有条件地变异 + 计数【英文标题】:group_by and conditionally mutate + count 【发布时间】:2022-01-04 15:04:30 【问题描述】:

我有以下示例数据框(原来有超过 200,000 行:

df <- tribble(~ id, ~ birth_year,
                 1,         2015,
                 1,         2015,
                 1,         2016,
                 2,         2008,
                 2,         2010,
                 3,         2010,
                 3,         2014,
                 3,         2014,
                 3,         2014,
                 4,         2010,
                 4,         2011,
                 4,         2012,
                 4,         2013)

我想按 id 分组并计算出生年份与 id 重复的次数。理想情况下获得这个:

df_wanted <- tribble(~ id, ~ birth_year, ~ n,
                        1,         2015,   2,
                        1,         2015,   2,
                        1,         2016,   2,
                        2,         2008,   0,
                        2,         2010,   0,
                        3,         2010,   3,  
                        3,         2014,   3,
                        3,         2014,   3,
                        3,         2014,   3,
                        4,         2010,   0,
                        4,         2011,   0,
                        4,         2012,   0,
                        4,         2013,   0)

有什么建议吗?我遇到了有条件地计算特定值,但没有像我的示例那样重复的情况。

【问题讨论】:

嗨@Paula,我认为您的输出中有一个错误(n 列):两个和三个应该分别是一个和两个,或者零应该是一个。这有意义吗? 【参考方案1】:

使用dplyr,您可以尝试以下操作。如果没有重复,则将n 设置为零。如果有,则使用table获取birth_year的频率,然后使用mutate存储max的数字。

library(dplyr)

df %>%
  group_by(id) %>%
  mutate(n = ifelse(anyDuplicated(birth_year), max(table(birth_year)), 0))

输出

      id birth_year     n
   <dbl>      <dbl> <dbl>
 1     1       2015     2
 2     1       2015     2
 3     1       2016     2
 4     2       2008     0
 5     2       2010     0
 6     3       2010     3
 7     3       2014     3
 8     3       2014     3
 9     3       2014     3
10     4       2010     0
11     4       2011     0
12     4       2012     0
13     4       2013     0

data.table 的替代方案可能更快:

library(data.table)

setDT(df)[, n := ifelse(anyDuplicated(birth_year), max(table(birth_year)), 0), id]

或基础R:

within(df,  n <- ave(birth_year, id, FUN = function(x) ifelse(anyDuplicated(x), max(table(x)), 0)) )

【讨论】:

【参考方案2】:

当您说“按 id 和计数分组”时,您的意思是聚合吗? 如果是这样,我相信这会成功:

df %>% 
  count(id, birth_year)

如果您的意思是要添加一个包含 id 和出生年份计数的列(如您的 df_wanted 所示),那么您正在寻找 add_count 函数:

df %>% 
  add_count(id, birth_year)

您可以从 R for data science book 或 dplyr 文档中学到很多。

【讨论】:

以上是关于group_by 和有条件地变异 + 计数的主要内容,如果未能解决你的问题,请参考以下文章

group_by 跨多个列的唯一计数

如何根据过滤条件添加计数列而不是在dplyr中进行分组?

在 R 中使用 aggregate/group_by 对数据进行分组并对每个因子变量进行计数?

Dplyr唯一计数和同一数据帧中的一般计数

在 SQL Server 查询中有条件地应用多个计数

dplyr:为什么个人计数摘要和索引摘要有所不同