R语言中基于指定列去重并正确处理NA值的实现方案
解决方法:保留分组内非NA值,区分全NA与真实0
我完全懂你的困扰——你需要按country和year去除重复行,同时保留每个分组里的非NA值,还要避免把全NA的分组错误转换成0(这会和真实的0值混淆)。之前用sum(.x, na.rm = TRUE)的思路确实会踩这个坑,下面给你两种简洁且准确的解决方案:
方案1:使用coalesce(最简洁)
你的数据集里,每个country+year分组的同一列中,最多只有一个非NA值(另一行是NA),所以可以利用coalesce函数直接提取非NA值,全NA时自动返回NA:
library(dplyr) df_cleaned <- df %>% select(-iso2c) %>% # 移除不需要的iso2c列 group_by(country, year) %>% summarise( across(everything(), ~ do.call(coalesce, .x)), # 提取分组内第一个非NA值,全NA则返回NA .groups = "drop" # 取消分组,返回常规数据框 )
方案2:显式判断全NA情况
如果你需要更清晰的逻辑展示,可以显式检查分组内是否全为NA,再决定返回值:
library(dplyr) df_cleaned <- df %>% select(-iso2c) %>% group_by(country, year) %>% summarise( across(everything(), ~ if(all(is.na(.x))) NA else na.omit(.x)[1]), .groups = "drop" )
验证效果
拿你提供的数据集测试:
- 1991年的分组所有列都是NA,处理后会保留NA,不会变成0
- 1985年的分组,各列会正确保留对应的非NA值(比如
DT.ODA.ODAT.GN.ZS保留1.3528,DT.ODA.ODAT.GD.ZS保留1.3299) - 全NA的列(比如
DT.ODA.ODAT.XP.ZS)在所有分组中都会保留NA,不会被转换
这样就完美解决了数据混淆的问题,同时满足去重和NA值保留的需求。
内容的提问来源于stack exchange,提问作者Macosso
相关产品推荐
相关产品推荐

