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

dplyr使用na.rm=TRUE分组筛选最小值时丢失含NA组问题

问题:dplyr分组筛选含NA的日期最小值行时丢失分组

使用dplyr 1.1.2版本,按uid和cat两个变量分组后,筛选每组date最小值对应的行时,当组内存在NA值,即使设置了na.rm=TRUE,也没有忽略NA保留非NA的最小值,反而导致整个组被丢弃。

原始数据框

# Original data frame
my_df <- 
structure(list(uid = c("id100", "id100", "id100", "id100", "id200", 
"id200", "id200", "id200", "id300", "id300", "id300", "id300"
), cat = c("franklin", "franklin", "aretha", "aretha", "franklin", 
"aretha", "aretha", "aretha", "franklin", "franklin", "aretha", 
"franklin"), food = c("fish", "beef", "chicken", "chicken", "beef", 
"pork", "turkey", "fish", "beef", "pork", "chicken", "beef"), 
    date = structure(c(8674, 8703, 8685, 8689, 8675, 8677, 8680, 
    8691, 8701, NA, 8698, 8697), class = "Date")), class = "data.frame", row.names = c(NA, 
-12L))

尝试的筛选代码

# Group by two variables, filter
new_df <- 
  my_df %>%
  group_by(uid, cat) %>%
  filter(date == min(date), na.rm = TRUE)

当前执行结果

uid   cat      food    date      
  <chr> <chr>    <chr>   <date>    
1 id100 franklin fish    1993-10-01
2 id100 aretha   chicken 1993-10-12
3 id200 franklin beef    1993-10-02
4 id200 aretha   pork    1993-10-04
5 id300 aretha   chicken 1993-10-25

期望得到的结果

uid   cat      food    date      
  <chr> <chr>    <chr>   <date>    
1 id100 franklin fish    1993-10-01
2 id100 aretha   chicken 1993-10-12
3 id200 franklin beef    1993-10-02
4 id200 aretha   pork    1993-10-04
5 id300 aretha   chicken 1993-10-25
6 id300 franklin beef    1993-10-24

解决方案

问题根源是参数传递错误:你把na.rm=TRUE传给了filter()函数,但filter()本身并不支持这个参数,该参数被直接忽略。这导致min(date)计算时,因为组内存在NA值,返回结果为NA,进而date == NA的判断结果全是NA,filter()会丢弃所有NA对应的行,最终整个组被排除。

修正方法1:正确传递na.rm给min()

把na.rm=TRUE放到min()函数的参数中,确保计算最小值时忽略NA:

new_df <- 
  my_df %>%
  group_by(uid, cat) %>%
  filter(date == min(date, na.rm = TRUE)) %>%
  ungroup() # 建议分组操作后取消分组,避免后续操作受分组状态影响

修正方法2:使用slice_min()更直观

dplyr提供了专门的slice_min()函数,用于筛选每组的最小值行,默认支持通过na_rm参数处理NA值,代码更简洁易懂:

new_df <- 
  my_df %>%
  group_by(uid, cat) %>%
  slice_min(date, na_rm = TRUE, with_ties = FALSE) %>% 
  # with_ties=FALSE:若组内有多个相同最小值的行,只保留第一行;设为TRUE则保留所有,按需调整
  ungroup()

两种方法都能得到你期望的结果,包含id300的franklin组对应的最小日期行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 17:25:01