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

多分组列含NA时dplyr的group_by+summarise丢失NA行问题

问题:dplyr分组汇总时丢失含NA的行

问题重现

使用dplyr对包含NA的多列分组后汇总,示例代码如下:

df <- data.frame(ID1 = c(1,2,3,4,5), ID2 = c(11, NA, 13, NA, 14), ID3 = c(1,2,3,4,5), value = c(110, 120, 130, 140, 150))
test <- df %>%
  group_by(ID1, ID2, ID3) %>%
  summarise(value=sum(value))

期望输出与实际输出

期望输出

ID1 ID2 ID3 value
1   11  1   110
2   NA  2   120
3   13  3   130
4   NA  4   140
5   14  5   150

实际输出(9个分组ID列时)

ID1 ID2 ID3 value
1   11  1   110
3   13  3   130
5   14  5   150

注:上述示例代码可得到期望输出,但9个分组ID列的代码会排除含NA的行,此前类似场景未出现该问题。

当前临时解决方法

通过将NA替换为字符"NA",汇总后再还原的方式处理:

df <- data.frame(ID1 = c(1,2,3,4,5), ID2 = c(11, NA, 13, NA, 14), ID3 = c(1,2,3,4,5), value = c(110, 120, 130, 140, 150))
test <- df %>%
  mutate(ID2 = ifelse(is.na(ID2), "NA", ID2)) %>%
  group_by(ID1, ID2, ID3) %>%
  summarise(value=sum(value)) %>% 
  mutate(ID2 = ifelse(ID2 == "NA", NA, ID2))

原因分析与最优解决方案

原因分析

  1. dplyr版本差异:最可能的原因是使用的dplyr版本低于1.0.0。在dplyr 1.0.0之前,多列分组场景下group_by()默认会意外排除包含NA的分组;而1.0.0及之后的版本默认保留NA分组(.na.rm = FALSE)。
  2. 列类型问题:如果实际数据中NA所在的分组列为因子类型,因子的NA处理逻辑会导致分组时被排除。

最优解决方案

  • 方案1:升级dplyr版本
    将dplyr升级到1.0.0及以上版本,无需修改现有代码,group_by()会默认保留含NA的分组,直接得到期望输出。

  • 方案2:显式设置分组参数(适配旧版本)
    如果无法升级版本,在group_by()中显式设置参数保留NA分组:

    • 对于dplyr 0.8.x及更早版本,使用keep.na = TRUE:
      test <- df %>%
        group_by(ID1, ID2, ID3, ..., keep.na = TRUE) %>%
        summarise(value=sum(value))
      
    • 对于dplyr 1.0.0及以上版本,可显式指定.na.rm = FALSE(默认值,可省略):
      test <- df %>%
        group_by(ID1, ID2, ID3, ..., .na.rm = FALSE) %>%
        summarise(value=sum(value))
      
  • 方案3:处理因子类型分组列
    如果分组列为因子类型,先将其转换为字符或数值列后再分组:

    test <- df %>%
      mutate(across(c(ID2, ...), as.character)) %>% # 或as.numeric,根据实际类型选择
      group_by(ID1, ID2, ID3, ...) %>%
      summarise(value=sum(value))
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 08:45:08