【问题标题】:Remove rows from data.table that meet condition从 data.table 中删除满足条件的行
【发布时间】:2018-03-02 03:58:26
【问题描述】:

我有一个数据表

DT <- data.table(col1=c("a", "b", "c", "c", "a"), col2=c("b", "a", "c", "a", "b"), condition=c(TRUE, FALSE, FALSE, TRUE, FALSE))

   col1 col2 condition
1:    a    b      TRUE
2:    b    a     FALSE
3:    c    c     FALSE
4:    c    a      TRUE
5:    a    b     FALSE

并希望在以下情况下删除行:

  • condition==TRUE 对应的每一行(第 1 行和第 4 行)
  • col1 和 col2 的值与 condition==TRUE 具有相同值的每一行(即第 5 行,col1=a,col2=b)
  • 最后每一行的 col1 和 col2 的值都相同,condition==TRUE,但 col1 和 col2 已切换(即第 2 行,col1=b 和 col2=a)

所以应该只保留第 3 行。

我这样做是通过创建一个所有行都满足条件的新数据表DTcond,循环遍历 col1 和 col2 的值,并从 DT 收集索引,这些索引将被删除。

DTcond <- DT[condition==TRUE,]
indices <- c()
for (i in 1:nrow(DTcond)) {
    n1 <- DTcond[i, col1]
    n2 <- DTcond[i, col2]
    indices <- c(indices, DT[ ((col1 == n1 & col2 == n2) | (col1==n2 & col2 == n1)), which=T])
}

DT[!indices,]
   col1 col2 condition
1:    c    c     FALSE

这可行,但对于大型数据集来说速度非常慢,我猜 data.table 中必须有其他方法可以在没有循环或应用的情况下执行此操作。有什么建议可以改进(我是 data.table 的新手)?

【问题讨论】:

    标签: r data.table


    【解决方案1】:

    你可以做一个反连接:

    mDT = DT[(condition), !"condition"][, rbind(.SD, rev(.SD), use.names = FALSE)]
    DT[!mDT, on=names(mDT)]
    
    #    col1 col2 condition
    # 1:    c    c     FALSE
    

    【讨论】:

    • 对我来说 mDT = DT[(condition), !"condition"] 不起作用,但与 DT[(condition), .(col1, col2)]
    • @user1981275 哦,那是版本控制的事情。在最新版本的 data.table 中,此语法有效。对于年龄较大的,您需要DT[(condition), !"condition", with=FALSE]
    猜你喜欢
    • 2016-12-04
    • 2016-10-20
    • 2015-10-13
    • 2015-03-21
    • 1970-01-01
    • 2020-09-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多