R语言 如何使用目标向量对data.table进行排序

enxuqcxy  于 2023-10-13  发布在  其他
关注(0)|答案(3)|浏览(134)

所以,我有以下数据。表

DT = data.table(x=rep(c("b","a","c"),each=3), y=c(1,2,3))

> DT
   x y
1: b 1
2: b 2
3: b 3
4: a 1
5: a 2
6: a 3
7: c 1
8: c 2
9: c 3

我有下面的矢量

k <- c("2","3","1")

我想使用k作为目标向量,使用yDT进行排序,得到如下结果。

> DT
   x y
1: b 2
2: a 2
3: c 2
4: b 3
5: a 3
6: c 3
7: b 1
8: a 1
9: c 1

如果我使用DT[order(k)],我得到的是原始数据的一个子集,而这不是我想要的。

hts6caw3

hts6caw31#

在那里调用match()

DT[order(match(y, as.numeric(k)))]
#    x y
# 1: b 2
# 2: a 2
# 3: c 2
# 4: b 3
# 5: a 3
# 6: c 3
# 7: b 1
# 8: a 1
# 9: c 1

实际上,DT[order(match(y, k))]也可以工作,但是为了以防万一,最安全的方法可能是将参数设置为同一个类的match()

注意:match()在某些情况下是次优的。如果您有大量的行,您可能希望切换到fastmatch::fmatch以实现更快的匹配。

ygya80vv

ygya80vv2#

你可以这样做:

DT = data.table(x=rep(c("b","a","c"),each=3), y=c(1,2,3))
k <- c("2","3","1")
setkey(DT,y)
DT[data.table(as.numeric(k))]

(来自Richard的评论)

DT = data.table(x=rep(c("b","a","c"),each=3), y=c(1,2,3))
k <- c("2","3","1")
DT[data.table(y = as.numeric(k)), on = "y"]
ddhy6vgd

ddhy6vgd3#

我想知道这个answer中提出的方法(使用ordermatch)是否可以扩展到使用目标向量对多个列进行排序。我想出了以下内容,只是想把它贴出来,因为它可能对其他人也有用。
这是一个有点笨拙,也许有人谁是聪明的有更好的和更简洁的方式来做?

library(data.table)
set.seed(42L)
DT <- data.table(
  x = rep(letters[1:3], each = 3), 
  y = sample(letters[1:3], 9, TRUE),
  z = c(1, 2, 3)
)

k <- c("b", "a", "c")

x <- DT[, lapply(.SD, match, table = k), .SDcols = c("x", "y")]

# https://stackoverflow.com/a/29483058/4524755
ii <- do.call(order, x)

DT[ii]
#>    x y z
#> 1: b b 2
#> 2: b b 3
#> 3: b a 1
#> 4: a a 1
#> 5: a a 2
#> 6: a a 3
#> 7: c b 1
#> 8: c a 2
#> 9: c c 3

第二种方法是将列转换为factor,并将levels设置为k。然后按两列排序。这可以使用set*函数来实现。沿着…的路线;

# method2
DT2 <- copy(DT)

for(col in c("x", "y")) {
  set(DT2, j = col, value = factor(DT[[col]], levels = k))  
}

setorderv(DT2, col = c("x", "y"))
DT2
#>    x y z
#> 1: b b 2
#> 2: b b 3
#> 3: b a 1
#> 4: a a 1
#> 5: a a 2
#> 6: a a 3
#> 7: c b 1
#> 8: c a 2
#> 9: c c 3

相关问题