【问题标题】:dplyr: grouping and conditionally filteringdplyr:分组和条件过滤
【发布时间】:2021-10-25 09:08:45
【问题描述】:

我的数据由人组成。 他们按职业和性别标记。 我想过滤掉至少有 5 个女性和 5 个男性的职业。 这看起来很简单,但我还没有设法在 StackOverflow 上找到类似的示例。

这是我的尝试:

group_cols <- c("professions", "sex")

df %>%
  group_by(across(all_of(group_cols))) %>% 
  mutate(n = n()) %>%
  filter(n > 4) %>%
  summarize(n())

但是,这给了我至少有 5 名女性或 5 名男性的职业。 我需要创建一个条件规则,考虑每个职业的女性和男性,而不是单独考虑。

谢谢!

【问题讨论】:

    标签: r dplyr filtering


    【解决方案1】:

    要保留profession 在您可以使用的数据中至少有 5 位男性和 5 位女性 -

    library(dplyr)
    
    df %>%
      group_by(profession) %>%
      filter(sum(sex == 'male', na.rm = TRUE) > 4 && 
             sum(sex == 'female', na.rm = TRUE) > 4) %>%
      ungroup
    

    【讨论】:

    • 非常优雅,先生!谢谢!
    【解决方案2】:

    假设有 2 名女工、2 名男工、2 名男学生、1 名女学生和 3 名男开发人员。我了解到您想放弃“学生”职业和“开发人员”职业,因为这些职业中并没有至少 2 名男性和 2 名女性。

    您可以分两步进行:
    (1) 对于每个职业,计算最少的男性和女性工人。
    (2) 合并基于此最小值的数据框和过滤器。

    这是一个可重现的例子:

    library(dplyr)
    
    data <- as_tibble(
      data.frame(
        id=1:9,
        sex=c("F", "F", "F", "H", "H", "H", "H", "H", "H"),
        profession=c("worker","worker","student", "worker", "worker", "student", "developer", "developer", "developer")
        )
    )
    
    gb_cols <- c("profession", "sex")
    
    agg <- data %>% group_by(across(all_of(gb_cols))) %>%
      summarise(n=n()) %>%
      pivot_wider(
        id_cols=profession,
        names_from=sex,
        values_from=n,
        values_fill=0
      ) %>%
      mutate(min=min(H,F)) %>%
      select(profession, min)
    
    data %>% inner_join(y=agg, by="profession") %>%
      filter(min>=2)
    

    【讨论】:

    • 谢谢,这很聪明。但是,我将它应用于我的数据,并且有一些职业,例如。没有女性,但过滤后仍然出现。所以我的目标只是让女性和男性都以最低数量从事职业。我猜脚本失败是因为该职业不存在该级别。
    • 你说得对,我编辑了我的答案以考虑到这种情况。
    • 谢谢,我接受了另一个答案,因为它更简洁。我也很感激你。
    • 然而,我的回答更笼统,因为您不需要对性别变量的级别进行硬编码:)。
    猜你喜欢
    • 2017-05-06
    • 1970-01-01
    • 2016-02-16
    • 2018-06-02
    • 2019-10-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多