4

我经常使用 data.table。它运行良好,但我发现转换语法需要很长时间才能利用二进制搜索。

在下面的数据表中,如何 1 选择所有行,包括 CPT 值所在的行,NA但排除 CPT 值为 23456 或 10000 的行。

cpt <- c(23456,23456,10000,44555,44555,NA)
description <- c("tonsillectomy","tonsillectomy in >12 year old","brain transplant","castration","orchidectomy","miscellaneous procedure")
cpt.desc <- data.table(cpt,description)

setkey(cpt.desc,cpt)

以下行有效,但我认为它使用矢量扫描方法而不是二进制搜索(或二进制排除)。有没有办法通过二进制方法删除行?

cpt.desc[!cpt %in% c(23456,10000),]
4

1 回答 1

2

只是部分答案,因为我是 data.table 的新手。自联接适用于数字,但同样适用于字符串。我确信其中一位专业的数据表格师知道该怎么做。

library(data.table)

n <- 1000000
cpt.desc <- data.table(
  cpt=rep(c(23456,23456,10000,44555,44555,NA),n),
  description=rep(c("tonsillectomy","tonsillectomy in >12 year old","brain transplant","castration","orchidectomy","miscellaneous procedure"),n))

# Added on revision. Not very elegant, though. Faster by factor of 3
# but probably better scaling 
setkey(cpt.desc,cpt)
system.time(a<-cpt.desc[-cpt.desc[J(23456,45555),which=TRUE]])
system.time(b<-cpt.desc[!(cpt %in% c(23456,45555))] )
str(a)
str(b)

identical(as.data.frame(a),as.data.frame(b))

# A self-join works Ok with numbers
setkey(cpt.desc,cpt)
system.time(a<-cpt.desc[cpt %in% c(23456,45555),])
system.time(b<-cpt.desc[J(23456,45555)])
str(a)
str(b)

identical(as.data.frame(a),as.data.frame(b)[,-3])

# But the same failes with characters
setkey(cpt.desc,description)
system.time(a<-cpt.desc[description %in% c("castration","orchidectomy"),])
system.time(b<-cpt.desc[J("castration","orchidectomy"),])
identical(as.data.frame(a),as.data.frame(b)[,-3])

str(a)
str(b)
于 2012-01-19T09:22:51.013 回答