This image完全描绘了我想要的内容:根据完全匹配{{}}的两列data.table
删除lat, lon
行{1}}另一个lat, lon
的列。
假设我有以下data.table
data.table
,其中超过100万行包含"dt.master"
和某个位置id
的坐标:
lat, lon
我想要做的是删除与某对坐标匹配的行。您可以将这对坐标视为放在以下黑名单中(同样是名为id lat lon
1 43.23 5.43
2 43.56 4.12
3 52.14 -9.85
4 43.56 4.12
5 43.83 9.43
... ... ...
的{{1}}):
data.table
在这种情况下,在应用黑名单时,答案必须是:
"dt.blacklist"
看起来很简单,我无法做到对。
使用lat lon
43.56 4.12
11.14 -5.85
,如下:
id lat lon
1 43.23 5.43
3 52.14 -9.85
5 43.83 9.43
... ... ...
但是这会产生匹配的行,因此是内部联接。我考虑过使用merge
:
dt.result <- merge(dt.master, dt.blacklist[, c("lat", "lon")], by.x=c("lat", "lon"), by.y=c("lat", "lon"))
但问题是它部分有效,因为上面的例子中只有1行被删除,而不是我想要的2行。不知怎的,它只删除了第一个“命中”。
使用快速而脏的解决方案,将subset
连接到两个数据表中名为subset(dt.master, lat != dt.result$lat & lon != dt.result$lon)
的新列,然后将其删除:
lat, lon
然而,同样的问题出现在两行中只有一行被移除。
答案 0 :(得分:4)
我认为你正在寻找这个:
dt.master[!dt.blacklist, on = .(lat,lon)]
输出:
id lat lon
1: 1 43.23 5.43
2: 3 52.14 -9.85
3: 5 43.83 9.43
由于绿色智者的警告,加入浮点可能会产生意想不到的副作用。通过转换为整数,您可以防止这种情况发生。因此,连接看起来会更复杂一些:
dt.master[, (2:3) := lapply(.SD,function(x) as.integer(x*100)), .SDcols = 2:3
][!dt.blacklist[, (1:2) := lapply(.SD,function(x) as.integer(x*100))], on = .(lat,lon)
][, (2:3) := lapply(.SD, `/`, 100), .SDcols = 2:3][]
输出相同:
id lat lon
1: 1 43.23 5.43
2: 3 52.14 -9.85
3: 5 43.83 9.43
答案 1 :(得分:2)
我们可以使用fsetdiff
data.table
fsetdiff(df1[,-1], df2)
或可以使用anti_join
dplyr
library(dplyr)
anti_join(df1, df2)
# id lat lon
#1 1 43.23 5.43
#2 3 52.14 -9.85
#3 5 43.83 9.43