R语言中dplyr::setdiff函数输出异常问题排查
问题分析:dplyr::setdiff的行为与你的预期偏差
首先要明确:你的代码本身没有语法错误,setdiff(t2, t1)返回的结果是符合这个函数的设计逻辑的——问题出在你对dplyr::setdiff的功能理解上。
为什么会得到这个输出?
dplyr::setdiff() 处理数据框时,是基于整行完全匹配来计算差异的:它会返回所有在第一个输入数据框(这里是t2)中存在,但在第二个数据框(t1)中完全不存在的整行记录。
看你的实际数据:
t1的行是(1,1)、(2,2)、(3,3)t2的行是(1,0)、(2,1)、(3,2)
t2里的每一行在t1中都找不到完全相同的匹配项,所以函数会返回t2的全部内容,这是它的正常输出。
如何得到你想要的结果?
你需要先明确自己的真实需求,这里提供几种常见场景的解决方案:
场景1:对比相同C1值对应的C2差异
如果你想找出t2中与t1同C1但C2不同的行,可以用left_join合并后筛选:
library(dplyr) left_join(t2, t1, by = "C1", suffix = c("_t2", "_t1")) %>% filter(C2_t2 != C2_t1)
输出会是t2的全部三行(因为每一行的C2都和t1对应值不同)。
场景2:找出所有t2有但t1没有的单个元素
如果想要忽略行结构,找出t2中存在但t1中没有的元素,可以把数据框转为向量后使用setdiff:
setdiff(unlist(t2), unlist(t1)) # 输出:[1] 0
因为只有0这个元素在t1中不存在。
场景3:找出t2中存在但t1中没有的行(基于指定列匹配)
如果想以C1为匹配键,找出t2中t1没有的行(比如t2有额外的C1值),可以用anti_join:
# 给t2加一行示例数据 t2_extra <- bind_rows(t2, data.frame(C1 = 4, C2 = 5)) anti_join(t2_extra, t1, by = "C1")
输出会是C1=4, C2=5这一行。
内容的提问来源于stack exchange,提问作者Pedram Azimzadeh
相关产品推荐
相关产品推荐

