选择ID的子集

时间:2014-11-29 00:30:10

标签: r data.table

我在dt列上有一个数据表idnum,在ids列中有一个包含ID列表的data.table idnum(所有其中存在dt

我想要

  • 交叉点:dt其中dt.idnum == ids.idnum`
  • 交叉点的补充:dt其中dt.idnum not in ids.idnum

我使用

轻松获得了第一个
setkey(dt, idnum)
setkey(ids, idnum)
dt[ids]

然而,我坚持得到第二个。我的方法是

dt[is.element(idnum, ids[, idnum]) == FALSE]

但是,这两个组的行号不等于nrow(dt)。我怀疑第二个命令。我该怎么做/我哪里错了?是否有更有效的计算第二组的方法,因为它是第一组的补充,我已经有了第二组?

更新 我尝试了答案中给出的方法,但我的数字并没有加起来:

> nrow(x[J(ids$idnum)])
[1] 148
> nrow(x[!J(ids$idnum)])
[1] 52730
> nrow(x)
[1] 52863

虽然,前两个数字增加了 52878 。也就是说,我的 15 行太多了。我的数据包含 adj 中的重复项,可能是这个原因吗?

以下是我使用的数据的一些描述:

> str(x)
Classes 'data.table' and 'data.frame':  52863 obs. of  1 variable:
 $ idnum: int  6 6 11 21 22 22 22 22 27 27 ...
 - attr(*, ".internal.selfref")=<externalptr> 
 - attr(*, "sorted")= chr "idnum"
> head(x)
   idnum
1:     6
2:     6
3:    11
4:    21
5:    22
6:    22


> str(ids)
Classes 'data.table' and 'data.frame':  46 obs. of  1 variable:
 $ idnum: int  2909 5012 5031 5033 5478 6289 6405 6519 7923 7940 ...
 - attr(*, ".internal.selfref")=<externalptr> 
 - attr(*, "sorted")= chr "idnum"
> head(ids)
   idnum
1:  2909
2:  5012
3:  5031
4:  5033
5:  5478
6:  6289

,这是

> sessionInfo()
R version 3.1.1 (2014-07-10)
Platform: x86_64-apple-darwin10.8.0 (64-bit)

locale:
[1] C/C/C/C/C/en_US.UTF-8

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods  
[7] base     

other attached packages:
[1] yaml_2.1.13      ggplot2_1.0.0    mFilter_0.1-3   
[4] data.table_1.9.4 foreign_0.8-61  

loaded via a namespace (and not attached):
 [1] MASS_7.3-35      Rcpp_0.11.3      chron_2.3-45    
 [4] colorspace_1.2-4 digest_0.6.4     grid_3.1.1      
 [7] gtable_0.1.2     labeling_0.3     munsell_0.4.2   
[10] plyr_1.8.1       proto_0.3-10     reshape2_1.4    
[13] scales_0.2.4     stringr_0.6.2    tools_3.1.1 

1 个答案:

答案 0 :(得分:3)

这是一种方式:

library(data.table)
set.seed(1)  # for reproducible example
dt <- data.table(idnum=1:1e5,x=rnorm(1e5))   # 10,000 rows, unique ids
ids <- data.table(idnum=sample(1:1e5,10))    # 10 random ids

setkey(dt,idnum)
result.1 <- dt[J(ids$idnum)]             # inclusive set (records with common ids)
result.2 <- dt[!J(ids$idnum)]            # exclusive set (records from dt with ids$idnum excluded
any(result.2$idnum %in% result.1$isnum)
# [1] FALSE

编辑:对OP评论的回应。

比较行数没有意义。连接将返回与所有匹配对应的行。因此,如果给定idnumdt中出现两次,在ids中出现三次,则结果中将得到2 X 3 = 6行。我做过的重要测试是result.1中的result.2中的任何ID?如果是这样,那就错了。

如果您有重复的ids$idnum,请尝试:

result.1 <- dt[J(unique(ids$idnum))]    # inclusive set (records with common ids)