R语言比对两个CSV数据集 合并匹配项生成新df并提取差异
R数据处理实现方案
一、生成目标数据框df3
实现逻辑
以id作为两表关联的唯一键,先将df1和df2做内连接,再筛选同id下两个表text字段取值完全一致的记录,最终保留id/text/response/volume四个字段即可,输出结果和给出的目标df3结构、数据完全匹配。
可运行代码
- dplyr实现(代码简洁,日常数据处理推荐)
# 加载dplyr包,未安装可先运行 install.packages("dplyr") library(dplyr) df3 <- df1 %>% inner_join(df2, by = "id", suffix = c("", "_df2")) %>% filter(text == text_df2) %>% select(id, text, response, volume)
- 基础R实现(无需安装第三方包)
# 按id合并两表 merge_temp <- merge(df1, df2, by = "id", suffixes = c("", "_df2")) # 筛选text一致的行,保留目标列 df3 <- merge_temp[merge_temp$text == merge_temp$text_df2, c("id", "text", "response", "volume")] # 重置行名 rownames(df3) <- NULL
运行以上任意一段代码,得到的df3和示例目标结果完全一致。
二、提取两表所有差异项
差异项分类
两个数据框的差异共分为三类:
- id仅在df1中存在、df2无匹配的记录
- id仅在df2中存在、df1无匹配的记录
- id在两表中都存在,但同id下text字段取值不一致的记录
可运行代码
- dplyr实现
library(dplyr) # 1. 提取仅在df1存在的记录 only_in_df1 <- anti_join(df1, df2, by = "id") # 2. 提取仅在df2存在的记录 only_in_df2 <- anti_join(df2, df1, by = "id") # 3. 提取共有id但text取值不一致的记录 common_diff <- df1 %>% inner_join(df2, by = "id", suffix = c("_df1", "_df2")) %>% filter(text_df1 != text_df2) # 所有差异可整合为列表统一查看 all_diffs <- list( "仅在df1存在的记录" = only_in_df1, "仅在df2存在的记录" = only_in_df2, "共有ID但文本不匹配的记录" = common_diff )
- 基础R实现
# 1. 仅在df1存在的记录 only_in_df1 <- df1[!df1$id %in% df2$id, ] # 2. 仅在df2存在的记录 only_in_df2 <- df2[!df2$id %in% df1$id, ] # 3. 共有id但text不匹配的记录 common_ids <- intersect(df1$id, df2$id) df1_sub <- df1[df1$id %in% common_ids, ] df2_sub <- df2[match(df1_sub$id, df2$id), ] common_diff <- data.frame( id = df1_sub$id, text_df1 = df1_sub$text, response_df1 = df1_sub$response, text_df2 = df2_sub$text, volume_df2 = df2_sub$volume )[df1_sub$text != df2_sub$text, ]
示例数据的差异结果
基于提供的测试数据,运行代码后得到的差异如下:
- 仅在df1存在的记录:0行,df1所有id都在df2中有匹配
- 仅在df2存在的记录:共10行,对应id为636809222、2004722036到2005866692的df2独有记录
- 共有ID但文本不匹配的记录:1行,id为632592651,df1中text为
asdf,df2中text为asdf_xyz,对应volume为1234
内容的提问来源于stack exchange,提问作者Catalyst
相关产品推荐
相关产品推荐

