如何在 R 中使用 data.table 保持唯一的列表列值?

How to keep unique list-column values using data.table in R?

我有一个数据框,它用一个 ID 标识一组值。比方说:

library(data.table)

dt <- data.table(
  id = rep(c("a", "b", "c"), each = 2),
  value1 = c(1, 1, 1, 2, 1, 1),
  value2 = c(0, 3, 0, 3, 0, 3)
)

如您所见,一个 id 标识多行值,而不是单个值。我想要做的是只保留标识一组值的第一次出现的 id。例如,上面数据框中的 ac 标识同一组值,因此我希望结果为:

dt[1:4] # desired output
#>    id value1 value2
#> 1:  a      1      0
#> 2:  a      1      3
#> 3:  b      1      0
#> 4:  b      2      3

我发现这样做的一种简单方法是将值组也嵌套到数据框中,然后仅保留基于这个新的嵌套数据框列的唯一条目。嵌套非常简单:

dt <- dt[, .(data = list(.SD)), by = id]
dt
#>    id              data
#> 1:  a <data.table[2x2]>
#> 2:  b <data.table[2x2]>
#> 3:  c <data.table[2x2]>

但显然,实际的“保持唯一事件”是相当棘手的。我尝试了两种不同的方法,但都失败了。首先,使用 unique.data.table。但是 by 参数还不支持列表列:

dt <- unique(dt, by = "data")
#> Error in forderv(x, by = by, sort = FALSE, retGrp = TRUE): Column 1 passed to [f]order is type 'list', not yet supported.

然后使用 .I[],但我无法将列表列传递给 by 参数:

dt <- dt[dt[, .I[1], by = data]$V1]
#> Error: column or expression 1 of 'by' or 'keyby' is type list. Do not quote column names. Usage: DT[,sum(colC),by=list(colA,month(colB))]

我在这上面花了很多时间,但我似乎无法弄清楚如何实现我想要的。我不一定依附于“nest -> keep unique dataframe”路径,但这是解决我能想到的问题的唯一方法。

我们可以使用 duplicatedunnest

library(tidyr)
dt[, .(data = list(.SD)), by = id][!duplicated(data)] %>%
   unnest(data)

-输出

# A tibble: 4 × 3
  id    value1 value2
  <chr>  <dbl>  <dbl>
1 a          1      0
2 a          1      3
3 b          1      0
4 b          2      3

本着@akrun 回答的精神,但保持 data.table 作为唯一的依赖项:

library(data.table)

dt <- data.table(
  id = rep(c("a", "b", "c"), each = 2),
  value1 = c(1, 1, 1, 2, 1, 1),
  value2 = c(0, 3, 0, 3, 0, 3)
)

dt <- dt[, .(data = list(.SD)), by = id]
dt <- dt[!duplicated(data)]
dt[, unlist(data, recursive = FALSE), by = id]
#>    id value1 value2
#> 1:  a      1      0
#> 2:  a      1      3
#> 3:  b      1      0
#> 4:  b      2      3