【问题标题】:How to filter cases in a data.table by multiple conditions defined in another data.table如何通过另一个 data.table 中定义的多个条件过滤 data.table 中的案例
【发布时间】:2015-02-24 20:08:23
【问题描述】:

我想知道是否有任何有效的方法可以通过另一个 data.table 中定义的多个条件来过滤 data.table。在这种情况下有2个data.table:

# the filter data.table defines the condition
dt_filter<-data.table(A=c(1,2),B=c(8,7))
# dt1 the data.table to be filtered
dt1<-data.table(A=rep(c(1,2),5),B=c(8,4,3,1,1,5,9,7,1,1),C=c(rep(1,5),rep(2,5)))

ls_tmp<-lapply (1:nrow(dt_filter),function(i){
# exclude the record with the A&B defined the filter
dt1_add<-dt1[A==dt_filter[[i,1]]&B!=dt_filter[[i,2]]]
})
result<- rbindlist(ls_tmp)

由于 lapply 循环,我的示例似乎效率不高。我不确定如何通过其他方式重写它。

【问题讨论】:

  • 什么是组?请标记A, B, CB!=dt_filter[...这里的不相等,是错字吗?
  • @Vlo A 列是组 ID。
  • 您的代码真的很难阅读。为了我们和您的利益,请尝试清理和简化!
  • @Señor 对不起。它们已被编辑。
  • 选择匹配 B dt2_add 和不匹配 B dt1_add 的行然后将列表绑定在一起有什么意义。这不等于选择了一个组的所有成员吗?这可以追溯到我最初的问题是dt1_add 中的!= 是错字吗?

标签: r data.table dplyr


【解决方案1】:
setkey(dt1, A)

dt1[dt_filter, allow = T][B != i.B, !'i.B']
#   A B C
#1: 1 1 1
#2: 1 1 2
#3: 1 3 1
#4: 1 9 2
#5: 2 1 1
#6: 2 1 2
#7: 2 4 1
#8: 2 5 2

【讨论】:

    【解决方案2】:

    另外两个阅读更清晰的解决方案,不需要setkey

    dt1[ which(dt1$A == dt_filter$A &amp; dt1$B != dt_filter$B) ,]

    现在使用%in%

    dt1[dt1$A %in% dt_filter$A &amp; !(dt1$B %in% dt_filter$B) ,]

    【讨论】:

    • 由于data.table默认使用“with”,相信你可以进一步简化为:dt1[ which(A == dt_filter$A &amp; B != dt_filter$B) , ]
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-03-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-29
    • 2018-07-16
    相关资源
    最近更新 更多