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

R语言中基于多条件分组筛选DataFrame行的技术求助

按ID分组的多条件DataFrame行筛选解决方案

完整代码实现

library(dplyr)

# 示例数据
df <- data.frame(ID = rep(c(479,147,643,228,501), c(3,3,1,2,2)),
                 No = c("A009145","A009146","0","A146754",NA,"A156764",NA,NA,NA,NA,NA),
                 Date = c("2012-06-28","2020-01-10","2020-01-10","2014-11-28",NA,NA,"2019-04-13","2017-10-27","2017-12-01",NA,NA),
                 point = c(25.2,31.1,31.1,21.5,18.6,18.6,27.77,18.52,18.52,26.3,26.3))

# 执行筛选逻辑
result <- df %>%
  mutate(Date = as.Date(Date)) %>%
  group_by(ID) %>%
  filter(
    # 规则3:组内No和Date均为NA,保留所有行
    (all(is.na(No)) & all(is.na(Date))) |
    # 规则2:组内所有No为NA,保留Date最新的行
    (all(is.na(No)) & any(!is.na(Date)) & Date == max(Date, na.rm = TRUE)) |
    # 规则1:组内存在有效No(非NA且≠"0"),保留这些行中Date最新的
    (!is.na(No) & No != "0" & Date == max(Date[!is.na(No) & No != "0"], na.rm = TRUE))
  ) %>%
  ungroup()

print(result)

输出结果

ID        No       Date   point
1  479   A009146 2020-01-10    31.1
2  147   A146754 2014-11-28    21.5
3  643        NA 2019-04-13   27.77
4  228        NA 2017-12-01   18.52
5  501        NA       <NA>    26.3
6  501        NA       <NA>    26.3

逻辑解释

针对每个ID分组,按以下优先级判断筛选规则:

  1. 规则1(存在有效No):先筛选出No不为NA且不等于"0"的行,再在这些行中保留Date最新的记录(na.rm=TRUE忽略Date为NA的无效行)。对应ID479、147的分组。
  2. 规则2(全No为NA但有有效Date):当组内所有No都是NA,但存在非NA的Date时,保留Date最大的那一行。对应ID228、643的分组。
  3. 规则3(全No和Date为NA):当组内所有No和Date都是NA时,保留所有行。对应ID501的分组。

原代码问题分析

原代码直接通过filter(!(No == "0" | is.na(No)))过滤掉了No为NA或"0"的行,导致:

  • 所有No全为NA的分组(228、643、501)被完全排除
  • 未处理Date为NA的场景
  • 未覆盖"全No和Date为NA则保留所有行"的规则

内容的提问来源于stack exchange,提问作者Alegría

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 12:25:39