R语言筛选多份数据集 保留两列共有匹配值的解决方法
问题原因
你之前的代码有两个核心问题:
- 用
rbind合并三个数据集时没有添加模型来源标识,合并后无法区分每条数据属于哪个模型,根本做不到跨模型比对 filter(length(pointInTime))仅判断分组下pointInTime列是否有值,既没有校验fixture是否在三个模型中同时存在,也没有校验不同模型下同一fixture的pointInTime集合是否完全一致,自然无法达到预期效果
正确实现方案
核心思路是先给每个数据集打来源标签再合并,通过给每个fixture在对应模型下的pointInTime集合生成唯一签名做一致性校验,步骤如下:
- 加载依赖包,给每个数据集添加来源列后合并
library(dplyr) # 给每个模型数据集添加来源标识列 Model_A <- Model_A %>% mutate(model_source = "Model_A") Model_B <- Model_B %>% mutate(model_source = "Model_B") Model_C <- Model_C %>% mutate(model_source = "Model_C") # 合并三个数据集,用bind_rows比rbind兼容性更好 df <- bind_rows(Model_A, Model_B, Model_C)
- 校验符合要求的fixture
valid_fixture_df <- df %>% # 先按fixtureId、模型来源分组,生成时间点集合的唯一签名 group_by(fixtureId, model_source) %>% # 对pointInTime去重排序后拼接为字符串,消除顺序差异,作为集合的唯一标识 summarise( pit_set_sign = paste(sort(unique(pointInTime)), collapse = "|"), .groups = "drop" ) %>% # 再按fixtureId分组做双重校验 group_by(fixtureId) %>% filter( n_distinct(model_source) == 3, # 校验1:该fixture在三个模型中都存在 n_distinct(pit_set_sign) == 1 # 校验2:三个模型下该fixture的时间点集合完全一致 ) %>% ungroup() # 提取所有符合要求的fixtureId valid_fixture_ids <- unique(valid_fixture_df$fixtureId)
- 提取最终结果
# 若需要合并状态的有效数据集 df_final <- df %>% filter(fixtureId %in% valid_fixture_ids) # 若需要拆分回三个独立的过滤后数据集,去掉来源列即可 Model_A_final <- df_final %>% filter(model_source == "Model_A") %>% select(-model_source) Model_B_final <- df_final %>% filter(model_source == "Model_B") %>% select(-model_source) Model_C_final <- df_final %>% filter(model_source == "Model_C") %>% select(-model_source)
注意事项
- 生成时间点签名前必须对
pointInTime做排序,因为集合本身不考虑顺序,避免同一集合因为记录顺序不同被误判为不一致 - 两个过滤条件缺一不可:少了模型数量校验会保留只在1-2个模型存在的fixture,少了签名校验会保留同一fixture在不同模型下时间点不一致的情况
内容的提问来源于stack exchange,提问作者T.Omalley
相关产品推荐
相关产品推荐

