使用R data.table获取满足条件的所有行

时间:2017-06-27 14:35:37

标签: r data.table

假设我们有这个玩具data.table

prueba  <- data.table(id=c(1,1,1,1,2,2,3,3,4), kk=c("FA", "N","N","N",NA,"FA","N", "FA", "N"), rrr=1:9)

id kk rrr
1 FA   1
1  N   2
1  N   3
1  N   4
2 NA   5
2 FA   6
3  N   7
3 FA   8
4  N   9

我们希望检索与给定&#34; id&#34;相关的所有行。如果该ID包含任何&#34; FA&#34; kk列上的值。

我必须这样做:

prueba[id %in% prueba[,any(kk=="FA", na.rm=T),
   by=id]$id[prueba[,any(kk=="FA", na.rm=T),by=id]$V1],]

id kk rrr
1 FA   1
1  N   2
1  N   3
1  N   4
2 NA   5
2 FA   6
3  N   7
3 FA   8

(我们得到id = 1,2和3的所有行。)

但我认为它太长而且没有优化。

如何使用data.table轻松完成?

3 个答案:

答案 0 :(得分:1)

我不确定是否已优化,但已清理并使用dplyr:

library(dplyr)
prueba %>% 
    group_by(id) %>% 
    filter('FA'%in%kk)

# A tibble: 8 x 3
# Groups:   id [3]
     id    kk   rrr
  <dbl> <chr> <int>
1     1    FA     1
2     1     N     2
3     1     N     3
4     1     N     4
5     2  <NA>     5
6     2    FA     6
7     3     N     7
8     3    FA     8

答案 1 :(得分:1)

对于data.table案例,我会将您的代码简化为:

prueba  <- data.table(id=c(1,1,1,1,2,2,3,3,4), kk=c("FA", "N","N","N",NA,"FA","N", "FA", "N"), rrr=1:9)  

prueba[id %in% unique(prueba[kk=="FA",id])]

输出结果为:

   id kk rrr
1:  1 FA   1
2:  1  N   2
3:  1  N   3
4:  1  N   4
5:  2 NA   5
6:  2 FA   6
7:  3  N   7
8:  3 FA   8 

答案 2 :(得分:1)

我一直在尝试使用microbenchmark的不同解决方案:

prueba  <- data.table(id=rep(c(1,1,1,1,2,2,3,3,4),1000000), kk=rep(c("FA", "N","N","N",NA,"FA","N", "FA", "N"),1000000), rrr=rep(1:9),1000000)

prueba[, if(any(kk == "FA")) .SD, by= id]               # docendo
prueba[id %in% unique(prueba[kk == "FA", id])]          # lmo
prueba[id %in% prueba[, .I[kk == "FA"], by = id]$id,]   # eddi
prueba[id %in% prueba[,any(kk=="FA", na.rm=T),by=id]
   $id[prueba[,any(kk=="FA", na.rm=T),by=id]$V1],]      # skan
prueba %>%   group_by(id) %>%   filter('FA'%in%kk)      # Andrew
prueba[prueba[kk == "FA", .(id)], on="id"]              # lmo

min       lq       mean     median       uq     max    name
2.206436 2.211022 2.258038 2.215607 2.283839 2.352071   docendo
1.456590 1.472334 1.596654 1.488077 1.666687 1.845296   lmo
2.767113 2.869260 2.953024 2.971408 3.045980 3.120552   eddi
3.431671 3.437914 3.451760 3.444157 3.461804 3.479451   skan
2.088516 2.247807 2.313196 2.407098 2.425535 2.443973   Andrew

lmo的最后一个解决方案不起作用,它说:

  

vecseq中的错误(f __,len __,if(allow.cartesian || notjoin ||)   !anyDuplicated(f __,:Join结果超过2 ^ 31行   (内部vecseq达到物理极限)。很可能是错误的   加入。检查i中的重复键值,每个键值都加入到   x中的同一组一遍又一遍。如果可以,请尝试= .EACHI   为每个组运行j以避免大量分配。

我希望看到方法之间有更大的差异。也许使用不同的数据集。 迄今为止最快的方法似乎是:

prueba[id %in% unique(prueba[kk == "FA", id])] 

我想必须有更好的选择使用.I,.GRP或类似的功能。