如何在R语言数据框中移除重复分组中含NA更多的行
解决方法:移除Year和Country重复组中NA更多的行
没问题,这个数据清理需求很常见,我给你两种实用的解决方案,你可以根据自己的习惯选择:
方法一:用dplyr包(简洁易读)
dplyr是R中处理数据框的常用工具,代码逻辑清晰,适合快速实现需求。
步骤:
- 先计算每行的NA数量(这是核心,用来判断哪行要保留)
- 按
Year和Country分组,筛选出每组中NA数量最少的行 - 清理临时生成的NA计数列
# 先复制你的原始数据框 x <- data.frame("Year" = c(2017,2017,2017,2018,2018), "Country" = c("Sweden", "Sweden", "Norway", "Denmark", "Finland"), "Sales" = c(15, 15, 18, 13, 12), "Campaigns" = c(3, NA, 4, 1, 1), "Employees" = c(15, 15, 12, 8, 9), "Satisfaction" = c(0.8, NA, 0.9, 0.95, 0.87), "Expenses" = c(NA, NA, 9000, 7500, 4300)) # 如果还没装dplyr,先安装 # install.packages("dplyr") library(dplyr) # 1. 计算每行的NA数量 x$na_count <- rowSums(is.na(x)) # 2. 分组筛选+清理临时列 cleaned_x <- x %>% group_by(Year, Country) %>% # 按年份和国家分组 filter(na_count == min(na_count)) %>% # 保留每组中NA最少的行 ungroup() %>% # 取消分组 select(-na_count) # 删除临时的NA计数列 # 查看结果 cleaned_x
运行后,2017年瑞典的两行里,只有NA数量为1的第一行会被保留,其他行都正常保留。
方法二:用Base R(无需额外安装包)
如果你不想安装新包,用Base R也能实现同样的效果:
# 原始数据框同上 x <- data.frame("Year" = c(2017,2017,2017,2018,2018), "Country" = c("Sweden", "Sweden", "Norway", "Denmark", "Finland"), "Sales" = c(15, 15, 18, 13, 12), "Campaigns" = c(3, NA, 4, 1, 1), "Employees" = c(15, 15, 12, 8, 9), "Satisfaction" = c(0.8, NA, 0.9, 0.95, 0.87), "Expenses" = c(NA, NA, 9000, 7500, 4300)) # 1. 计算每行NA数量 x$na_count <- rowSums(is.na(x)) # 2. 找出每个(Year, Country)组的最小NA数量 min_na_per_group <- aggregate(na_count ~ Year + Country, data = x, FUN = min) # 3. 合并数据并筛选符合条件的行 cleaned_x_base <- merge(x, min_na_per_group, by = c("Year", "Country")) %>% subset(na_count.x == na_count.y) %>% select(-na_count.x, -na_count.y) # 查看结果 cleaned_x_base
补充说明:
- 如果某个组里有多行NA数量相同且都是组内最少的(比如两行都只有1个NA),两种方法都会保留这些行。如果你需要进一步去重,可以在筛选后加上
distinct(Year, Country, .keep_all = TRUE)(dplyr方法)或者其他去重逻辑。 rowSums(is.na(x))是计算每行NA数量的高效方式,is.na(x)会把数据框转为布尔值矩阵,rowSums统计每行TRUE(即NA)的数量。
内容的提问来源于stack exchange,提问作者Friedi S.
相关产品推荐
相关产品推荐

