R语言合并DataFrame去重:保留同数据集内重复,保留最小dfid行
R语言多数据集合并按规则去重实现
需求说明
- 多个数据集通过
rbind合并为一个数据框,每个数据集新增唯一标识dfid,数据集内部有独立自增的ID字段 - 同一
dfid下的重复行只要ID不同就全部保留 - 相同内容的行如果出现在多个
dfid对应的数据集里,仅保留dfid最小的数据集下的所有该类行,删除其余dfid更大的数据集下的对应重复行
示例数据构造
library(tidyverse) # 构造两个测试数据集 df1 = head(iris,3) df2 = tail(iris,3) df2 = rbind(df2, df1[rep(1), ]) df1 = rbind(df1, df1[rep(1), ]) # 新增ID和dfid字段 df1 = df1 %>% mutate(ID=1:nrow(df1)) %>% mutate(dfid=1) df2 = df2 %>% mutate(ID=1:nrow(df2)) %>% mutate(dfid=2) # 合并为总数据集 dfexamp = rbind(df1, df2) %>% as.data.frame(row.names = 1:nrow(.))
合并后的数据集内容:
Sepal.Length Sepal.Width Petal.Length Petal.Width Species ID dfid 1 5.1 3.5 1.4 0.2 setosa 1 1 2 4.9 3.0 1.4 0.2 setosa 2 1 3 4.7 3.2 1.3 0.2 setosa 3 1 4 5.1 3.5 1.4 0.2 setosa 4 1 5 6.5 3.0 5.2 2.0 virginica 1 2 6 6.2 3.4 5.4 2.3 virginica 2 2 7 5.9 3.0 5.1 1.8 virginica 3 2 8 5.1 3.5 1.4 0.2 setosa 4 2
期望输出结果:
Sepal.Length Sepal.Width Petal.Length Petal.Width Species ID dfid 1 5.1 3.5 1.4 0.2 setosa 1 1 2 4.9 3.0 1.4 0.2 setosa 2 1 3 4.7 3.2 1.3 0.2 setosa 3 1 4 5.1 3.5 1.4 0.2 setosa 4 1 5 6.5 3.0 5.2 2.0 virginica 1 2 6 6.2 3.4 5.4 2.3 virginica 2 2 7 5.9 3.0 5.1 1.8 virginica 3 2
错误尝试
最初使用group_by直接过滤行数小于2的分组,错误将同一数据集内的合法重复行也删除了,错误代码如下:
dfexamp %>% group_by_at(vars(-dfid, -ID)) %>% filter(n() < 2)
错误输出:
Sepal.Length Sepal.Width Petal.Length Petal.Width Species ID dfid 1 4.9 3 1.4 0.2 setosa 2 1 2 4.7 3.2 1.3 0.2 setosa 3 1 3 6.5 3 5.2 2 virginica 1 2 4 6.2 3.4 5.4 2.3 virginica 2 2 5 5.9 3 5.1 1.8 virginica 3 2
可行实现方案
原实现代码
通过拼接内容生成唯一键,按键分组后保留每个分组下dfid最小的所有行:
dfexamp %>% unite(.,key, c(-dfid,-ID), sep=" ", remove= FALSE)%>% group_by(key, .add = TRUE) %>% group_split() %>% map(~ .x %>% filter(dfid == min(dfid))) %>% bind_rows(.) %>% select(-key)
更简洁的优化实现
无需生成中间键和拆分分组,直接按内容列分组后过滤即可,性能更优:
dfexamp %>% group_by(across(c(-ID, -dfid))) %>% filter(dfid == min(dfid)) %>% ungroup()
内容的提问来源于stack exchange,提问作者user16502008
相关产品推荐
相关产品推荐

