如果我想使用二进制搜索选择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也无济于事。
发布于 2012-09-07 14:08:57
成语是这样的:
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
灵感来自:
在Porting set operations from R's data frames to data tables: How to identify duplicated rows?上发布上一个问题的邮件列表
更新。v1.8.3中的新功能是not-join语法。法雷尔的第一个期望(!
而不是-
)已经实现了:
DT[-DT["a",which=TRUE,nomatch=0],...] # old idiom
DT[!"a",...] # same result, now preferred.
有关更多详细信息和示例,请参阅NEWS项目。
发布于 2012-09-07 17:30:16
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"]]
。此外,即使键中有多个列,它也可以工作,而目前它还不能。
https://stackoverflow.com/questions/12319083
复制