如何在R中还原data.table的独立列排序操作?
用reordering_dt和DT2还原原data.table DT
示例数据
原表DT
| ID | Letter |
|---|---|
| 1 | B |
| 4 | A |
| 3 | C |
| 2 | D |
| 5 | E |
每列独立排序后的表DT2
| ID | Letter |
|---|---|
| 1 | A |
| 2 | B |
| 3 | C |
| 4 | D |
| 5 | E |
生成数据与排序规则的代码
# 原data.table DT <- data.table( ID = c(1, 4, 3, 2, 5), Letter = c("B", "A", "C", "D", "E") ) # 生成每列独立排序后的DT2 DT2 <- DT[, lapply(.SD, function(col) col[order(col)])] # 存储从DT到DT2的排序规则 reordering_dt <- as.data.table(lapply(DT, order))
还原原表的正确方法
要从DT2和reordering_dt还原DT,核心是给每一列匹配对应的逆排序索引:reordering_dt存储的是从DT到DT2的排序位置,我们需要用order(reordering_dt的对应列)来获取从DT2回到原DT的逆位置。
方法1:用Map逐列匹配(直观易懂)
recovered_DT <- as.data.table(Map(function(col, idx) col[order(idx)], DT2, reordering_dt))
方法2:在data.table内按列名关联
利用DT2和reordering_dt列名一致的特点,直接通过列名对应索引:
# 简洁写法 recovered_DT <- DT2[, mapply(function(x, y) x[order(y)], .SD, reordering_dt, SIMPLIFY = FALSE)] # 或更清晰的分步写法 recovered_DT <- DT2[, lapply(names(.SD), function(col_name) { .SD[[col_name]][order(reordering_dt[[col_name]])] })]
运行后验证,recovered_DT与原DT完全一致:
> recovered_DT ID Letter 1: 1 B 2: 4 A 3: 3 C 4: 2 D 5: 5 E
内容的提问来源于stack exchange,提问作者TeeGeeVee
相关产品推荐
相关产品推荐

