You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在R中简洁实现DataFrame组内状态过滤(含全inactive组例外)?

问题描述

假设我有如下DataFrame:

dat <- data.frame(account = c(1, 2, 3, 4, 5, 6, 7, 8, 9),
                  group = c("a", "a", "b", "b", "c", "c", "c", "d", "d"),
                  status = c("active", "inactive", "inactive", "inactive", "active", "open", "inactive", "active", "active"))

我需要对数据做过滤,要求每个组(a、b、c等)至少留一个账户。过滤规则是:只保留状态为active或open的账户,除非这个组的所有账户状态都是inactive,这种情况至少保留一条。

我现在用多步代码实现了需求(如下),但想知道有没有更简洁的单步实现方式?

active_open <- dat %>%
    group_by(group) %>%
    filter(status == "active" | status == "open") %>%
    ungroup()

inactive <- dat %>%
    group_by(group) %>%
    filter(n_distinct(status) == 1 & status == "inactive") %>%
    slice_head(n = 1) %>%
    ungroup()

dat_clean <- bind_rows(active_open, inactive)
简洁实现方案

可以用dplyr的分组过滤逻辑,一次分组操作就能完成所有判断,不用拆分后再合并:

dat_clean <- dat %>%
  group_by(group) %>%
  filter(
    # 保留状态为active或open的记录
    status %in% c("active", "open") |
    # 组内全是inactive的话,只留第一条
    (all(status == "inactive") & row_number() == 1)
  ) %>%
  ungroup()

逻辑说明

  • 按组分组后,先筛出状态是active或open的记录,这些是我们优先要保留的
  • 对于那些组里没有active/open记录的情况(也就是全是inactive),我们只保留组内的第一条记录,保证每个组至少有一条数据

结果验证

运行上面的代码后,得到的dat_clean和你原来多步实现的结果完全一致:

# A tibble: 6 × 3
  account group status  
    <dbl> <chr> <chr>   
1       1 a     active  
2       3 b     inactive
3       5 c     active  
4       6 c     open    
5       8 d     active  
6       9 d     active  

内容的提问来源于stack exchange,提问作者setty

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 04:02:13