R语言:按分组统计两列合并后的唯一/去重值数量
解决按ID分组统计两列合并后唯一值数量的问题
你遇到的核心问题是没有把两列的所有值合并成一个整体去统计唯一值,而是分别处理了两列或者统计了列组合的唯一性。下面是针对需求的解决方案:
用dplyr实现(推荐,符合你已有的代码风格)
我们可以按ID分组后,将Party和Party2013两列的所有值合并成一个向量,忽略NA后统计唯一值的数量,再将这个计数添加到每一行:
library(dplyr) # 假设你的数据框名为data result <- data %>% group_by(ID) %>% mutate(Count = n_distinct(c(Party, Party2013), na.rm = TRUE)) %>% ungroup()
代码解释:
group_by(ID):按ID分组,确保每个ID的计算独立进行c(Party, Party2013):把当前分组下两列的所有值拼接成一个单一向量n_distinct(..., na.rm = TRUE):统计向量中的唯一值数量,na.rm = TRUE会自动忽略NA值,避免把NA算作一个"政党"mutate:将计算出的计数作为新列Count添加到每一行
用你的示例数据测试,第一个ID的合并后非NA值是A,A,B,B,A,去重后是A和B,所以Count=2;第二个ID合并后非NA值是A,B,B,B,C,去重后是A,B,C,所以Count=3,完全符合你的期望输出。
为什么你之前的方法不对?
- 第一个命令:
distinct(Party, Party2013, .keep_all = TRUE)是保留Party和Party2013的唯一组合,然后计数,所以得到的是不同列组合的数量(比如你的示例里有(A,A)、(A,NA)、(B,NA)三个组合,所以n()返回3),这和你要的合并后唯一值数量不是一回事。 - 第二个命令:
length(unique(Party, Party2013))的问题在于,unique()的多参数用法是返回每个参数的唯一值组成的列表,length()统计的是列表的长度(这里是2),而不是合并后向量的唯一值数量,所以结果不符合预期。
可选:用data.table实现(大数据量更高效)
如果你的数据集很大,data.table的方法会更高效:
library(data.table) setDT(data) # 将数据框转换为data.table data[, Count := uniqueN(c(Party, Party2013), na.rm = TRUE), by = ID]
uniqueN()是data.table中的去重计数函数,逻辑和n_distinct()一致,只是语法更简洁。
内容的提问来源于stack exchange,提问作者Martin Ondráček
相关产品推荐
相关产品推荐

