【问题标题】:R data.table - only keep rows with duplicate ID (most efficient solution)R data.table - 仅保留具有重复 ID 的行(最有效的解决方案)
【发布时间】:2020-04-08 23:41:55
【问题描述】:

我想使用data.table 创建一个函数,该函数仅保留 ID 列(存储为字符串向量)重复的行。请注意,如果有多个 ID 列,我只想保留 ID 列组合重复的行。

library(data.table)

dt <- data.table(x = c(1:5,5), y = rep(c(1,3,5), each = 2), z = rep(1:3, 2))

get_duplicate_id_rows1 <- function(dt_in, id_str) {
  dt_in[, if(.N > 1) .SD, by = id_str]
}

get_duplicate_id_rows1(dt, c("x", "y"))
#>    x y z
#> 1: 5 5 2
#> 2: 5 5 3

get_duplicate_id_rows1(dt[, .(x,y)], c("x", "y"))
#> Empty data.table (0 rows and 2 cols): x,y

如上所述,当数据表有一个非 ID 列时,我的第一次尝试有效。但是,当所有列都是 ID 列时,则数据表没有行。我认为这是因为,根据?data.table.SD 包括原始数据表的所有变量,分组行除外。因此,.SD 的列为零,这似乎是导致我的问题的原因。

get_duplicate_id_rows2 <- function(dt_in, id_str) {
  dt_in[, if(.N > 1) .SD, by = id_str, .SDcols = names(dt_in)]
}

get_duplicate_id_rows2(dt, c("x", "y"))
#>    x y x y z
#> 1: 5 5 5 5 2
#> 2: 5 5 5 5 3

get_duplicate_id_rows2(dt[, .(x,y)], c("x", "y"))
#>    x y x y
#> 1: 5 5 5 5
#> 2: 5 5 5 5

我的第二次尝试尝试使用.SDcols 来规避我第一次尝试时遇到的问题。这确实解决了我的数据表中的所有列都是 ID 列的问题。但是,这里id_str 中的列名是重复的。

我认为这是因为一组列名来自by 参数,而另一组列名来自.SDcols,尽管我对此不确定,因为在我的第一次尝试中,结果数据表有零个,而不是零个

因此,我很想了解这里发生了什么,以及对我的问题最有效的解决方案是什么 - 特别是对于大型数据集,这就是我从 tidyverse 迁移到 data.table 的原因。

reprex package (v0.3.0) 于 2020-04-09 创建

【问题讨论】:

    标签: r data.table


    【解决方案1】:

    我们可以使用.I获取频率计数大于1的组的索引,提取列并对data.table进行子集化

    dt[dt[, .I[.N >1], .(x, y)]$V1]
    

    注意:应该比.SD

    【讨论】:

      【解决方案2】:

      这是另一种选择:

      dt[dt[rowid(x, y) > 1], on=.(x, y), .SD]
      

      在示例中,您对返回 0 行的解释是正确的。由于分组列用于分组,因此每个组的列都是相同的,可以通过.BY 访问,因此.SD 不需要这些列以防止重复。

      默认情况下,当使用by 时,这些也会作为输出中最左侧的列返回,因此在get_duplicate_id_rows2 中,您会看到x、y 以及.SD 中指定的列,如.SDcols 中所指定。

      最后,关于效率,您可以使用microbenchmark 将此处发布的各种选项与您的实际数据集一起计时并分享您的结果。

      【讨论】:

      • 1.我从来没有真正使用过id_str = c("x", "y", "z")。 2.有道理! 3. 当然!更想知道为什么某些选项比其他选项更有效。抱歉,如果不清楚。
      • 哦,我误解了但是,当所有的列都是ID列时,数据表就没有行了。。这是什么意思?
      • 对不起,我不清楚!查看get_duplicate_id_rows1(dt[, .(x,y)], c("x", "y")) 的输出。此外,您的答案会生成第三列 i.z,它不等于所有行的 z
      • 添加了 .SD 并且您对它为什么返回 0 行的理解是正确的,即 我认为这是因为,根据 ?data.table,.SD 包含原始数据的所有变量表,分组行除外。因此,.SD 有零列,这似乎是我的问题。
      猜你喜欢
      • 2014-03-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-06
      • 1970-01-01
      • 2019-06-30
      • 1970-01-01
      相关资源
      最近更新 更多