如果我想选择data.table中使用二进制搜索在键变量中不包含特定值的所有行,会发生什么?顺便问一下,我想做什么的正确行话是什么?它是“nojoin”吗?这是“否定选择”吗?
DT = data.table(x=rep(c("a","b","c"),each=3), y=c(1,3,6), v=1:9)
setkey(DT,x)
让我们对x ==“a”但使用二进制搜索
的所有行做出正选择DT["a"]
那很美,但我希望与此相反。我想要所有不是“a”的行,换句话说x!=“a”
DT[x!="a"]
这是矢量扫描。以上线路工作但使用矢量扫描。我想用二进制文件。我期待以下工作,但唉......
DT[!"a"]
DT[-"a"]
以上两种方法都不起作用,尝试使用nomatch无处可玩。
答案 0 :(得分:19)
这个成语是这样的:
DT[-DT["a", which=TRUE]]
x y v
1: b 1 4
2: b 3 5
3: b 6 6
4: c 1 7
5: c 3 8
6: c 6 9
灵感来自:
<强>更新即可。 v1.8.3中的新增内容是非连接语法。 Farrel的第一个期望(!
而不是-
)已经实施:
DT[-DT["a",which=TRUE,nomatch=0],...] # old idiom
DT[!"a",...] # same result, now preferred.
有关更多详细信息和示例,请参阅NEWS项目。
答案 1 :(得分:3)
Andrie的答案很棒,而且我可能会使用它。有趣的是,以下构造似乎(只是稍微)更快,特别是当data.tables的大小增加时。
DT[J(x = unique(DT)[x!="a"][,x])]
##-------------------------------- Timings -----------------------------------##
library(data.table)
library(rbenchmark)
DT = data.table(x=rep(c("a","b","c"),each=45e5), y=c(1,3,6), v=1:9, key="x")
Josh <- function() DT[J(x = unique(DT)[x!="a"][,x])]
Andrie <- function() DT[-DT["a", which=TRUE]]
## Compare results
identical(Josh(), setkey(Andrie(), "x"))
# [1] TRUE
## Compare timings
benchmark(replications = 10, order="relative", Josh=Josh(), Andrie=Andrie())
test replications elapsed relative user.self sys.self user.child sys.child
1 Josh 10 17.50 1.000 14.78 3.6 NA NA
2 Andrie 10 18.75 1.071 16.52 3.2 NA NA
如果DT[,x]
可以返回 data.table 而不是向量,我会特别想要使用它。然后,构造可以简化为DT[unique(DT[,x])[x!="a"]]
。此外,即使密钥中有多个列,它也可以工作,但目前它没有。