我有一个数据框,用一个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)
)
dt
#> id value1 value2
#> 1: a 1 0
#> 2: a 1 3
#> 3: b 1 0
#> 4: b 2 3
#> 5: c 1 0
#> 6: c 1 3
如您所见,ids a
和c
标识了相同的一组值.所以我想创建一个"模式id",它标识与IDa
和c
相关联的一组值(obs:一个id可能标识两行以上,为了简单起见,我只将它们限制为两行).
我确实设法用嵌套数据想出了一个解决方案.表1和表match()
:
dt <- dt[, .(data = list(.SD)), by = id]
unique_groups <- unique(dt$data)
dt[, pattern_id := match(data, unique_groups)]
dt[, data := NULL]
dt
#> id pattern_id
#> 1: a 1
#> 2: b 2
#> 3: c 1
这是一个技巧,但它并没有我希望的那么快.match()
.关于列表的效率,文档非常清楚:
列表匹配可能非常缓慢,最好避免,除非是在简单的情况下.
如您所见,我不需要最终结果中的实际模式数据,只需要一个将ID与模式ID关联的表.我觉得把数据嵌套起来,用它来匹配,然后再删除它有点浪费,但不确定是否有更好的方法.我一直在思考如何将每个数据帧转换成一个字符串,或者更好的是,如何完全避免嵌套,但我想不出比现在更好的方法.
我已经创建了一个更大的数据集,可以使用和测试不同的解决方案:
set.seed(0)
size <- 1000000
dt <- data.table(
id = rep(1:(size / 2), each = 2),
value1 = sample(1:10, size, replace = TRUE),
value2 = sample(1:10, size, replace = TRUE)
)