如何基于另一个data.table过滤目标data.table数据?
解决data.table中按组合列过滤行的问题
嗨,我来帮你搞定这个data.table的过滤需求!你想要的是移除dt_1中所有与dt_2的(id, v1)组合完全匹配的行,之前的方法没达到预期是因为没做到「组合匹配」,下面给你两种高效的解决方案:
方法一:使用on参数直接做反连接(推荐)
这是data.table最直观的做法,直接指定用来匹配的列组合,不需要提前设键:
library(data.table) dt_1 <- data.table(id = c('cg','fs','fs'), v1 = c('a','a','b'), v2 = c('d','e','f')) dt_2 <- data.table(id = c('cg','fs','cg'), v1 = c('a','a','b')) # 核心代码:反连接,保留dt_1中不在dt_2的(id,v1)组合的行 dt_1[!dt_2, on = .(id, v1)]
运行后得到的结果正好是你想要的:
id v1 v2 1: fs b f
方法二:设置键后做反连接
如果你习惯用键操作,可以先给两个表设置相同的键(即匹配列),再执行反连接:
setkey(dt_1, id, v1) setkey(dt_2, id, v1) dt_1[!dt_2]
这样也能得到完全一致的结果,之前dt_1[!dt_2]报错就是因为没有指定匹配的列或键,data.table不知道按什么规则去匹配两个表。
为什么之前的方法不对?
你之前用的dt_1[!(id%in%dt_2$id & v1%in%dt_2$v1)]是分别检查id是否在dt_2的id列表里、v1是否在dt_2的v1列表里,而不是检查**(id, v1)这个组合是否存在于dt_2中**。比如dt_1里的(fs,a),id=fs在dt_2的id里,v1=a也在dt_2的v1里,所以会被错误地判定为要过滤,但实际上这个组合确实存在于dt_2中,应该被移除;而(fs,b)这个组合在dt_2里没有,所以要保留——这正是上面两种方法能正确实现的逻辑。
内容的提问来源于stack exchange,提问作者quant
相关产品推荐
相关产品推荐

