dhe*_*rsz 5 grouping nested r data.table
我有一个数据框,它用 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
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,ida和cidentify 都是同一组值。a因此,我想创建一个“模式 id”,它标识与ids 关联的值集c(obs:一个 id 可能标识多于两行,为了简单起见,我只是将它们限制为两行)。
我确实设法使用嵌套 data.tables 提出了一个解决方案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
Run Code Online (Sandbox Code Playgroud)
它确实有效,但它没有我希望的那么快。match()文档对于列表的效率非常清楚:
列表匹配可能非常慢,最好避免,除非是简单的情况。
正如您所看到的,我不需要最终结果中的实际模式数据,只需要一个将 id 与模式 id 相关联的表。我觉得嵌套数据,用它来匹配然后删除它有点浪费,但不确定是否有更好的方法。我正在考虑将每个数据帧转换为字符串的方法,或者更好的是,完全避免嵌套的方法,但我想不出比现在更好的方法。
我创建了一个更大的数据集来尝试和测试不同的解决方案:
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
Run Code Online (Sandbox Code Playgroud)
更新(删除连接):
这复制了您的方法(即它要求顺序和值相同)
unique(
dt[, pattern:=.(paste0(c(value1,value2), collapse=",")), by=id][,.(id,pattern)]
)[,grp:=.GRP, by=pattern][,pattern:=NULL]
id grp
<char> <int>
1: a 1
2: b 2
3: c 1
Run Code Online (Sandbox Code Playgroud)
之前的解决方案:
dt[dt[, .(paste0(sort(c(value1,value2)), collapse=",")), by=id] %>%
.[,pattern:=.GRP, by=V1] %>%
.[,V1:=NULL], on=.(id)]
Run Code Online (Sandbox Code Playgroud)
输出:
id value1 value2 pattern
<char> <num> <num> <int>
1: a 1 0 1
2: a 1 3 1
3: b 1 0 2
4: b 2 3 2
5: c 1 0 1
6: c 1 3 1
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
192 次 |
| 最近记录: |