在R中查找两个dataframe的差异:定位df2中的额外观测值
解决方法
以下几种方法可以帮你定位df2中多出来的观测值:
方法1:结合计数与dplyr的anti_join处理重复行
如果df1中存在重复行,setdiff会自动去重导致无法检测出多出来的重复项,用分组计数加关联对比可以解决:
library(dplyr) # 对两个数据框按两列分组统计出现次数 df1_count <- df1 %>% count(col1, col2) df2_count <- df2 %>% count(col1, col2) # 找出df2中计数多于df1的行 extra_info <- df2_count %>% left_join(df1_count, by = c("col1", "col2"), suffix = c("_df2", "_df1")) %>% mutate(n_df1 = ifelse(is.na(n_df1), 0, n_df1)) %>% filter(n_df2 > n_df1) # 还原出df2中多出来的具体观测值 extra_obs <- df2 %>% semi_join(extra_info, by = c("col1", "col2")) %>% slice(1:(extra_info$n_df2 - extra_info$n_df1))
方法2:生成行唯一标识对比频次
把两列字符拼接成唯一字符串,统计每个字符串在两个数据框中的出现次数,定位差异:
# 生成每行的唯一标识 df1_id <- apply(df1, 1, paste, collapse = "|") df2_id <- apply(df2, 1, paste, collapse = "|") # 统计各标识的出现频次 table_df1 <- table(df1_id) table_df2 <- table(df2_id) # 找出df2中频次更高的标识 extra_id <- names(which(table_df2 > table_df1)) # 提取对应的原始行 extra_row <- df2[df2_id %in% extra_id, ]
方法3:先清理字符列再对比
字符列的空格、大小写差异会导致setdiff失效,先统一处理后再查找:
library(dplyr) # 去除两端空格并统一为大写 df1_clean <- df1 %>% mutate(across(everything(), ~ trimws(toupper(.)))) df2_clean <- df2 %>% mutate(across(everything(), ~ trimws(toupper(.)))) # 找出清理后df2独有的行 clean_extra <- anti_join(df2_clean, df1_clean, by = names(df1)) # 对应回原始df2的行 original_extra <- df2[apply(df2_clean, 1, paste, collapse = "|") %in% apply(clean_extra, 1, paste, collapse = "|"), ]
方法4:使用data.table的fsetdiff
fsetdiff会保留重复行,能解决因重复项导致setdiff返回空的问题:
library(data.table) setDT(df1) setDT(df2) # 找出df2中不在df1里的行(保留重复) extra_row <- fsetdiff(df2, df1)
内容的提问来源于stack exchange,提问作者jo_
相关产品推荐
相关产品推荐

