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

问题描述 投票:0回答:3

所以,我有以下数据.表

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
作为目标向量,使用
DT
y
进行排序,并得到类似的结果。

> 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)]
我会得到原始数据的子集,但这不是我想要的。

r data.table
3个回答
18
投票

拨打电话至

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
以获得更快的匹配速度。


3
投票

你可以这样做:

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))]

或者(来自理查德的评论)

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"] 

0
投票

我想知道这种方法(使用

order
match
)是否可以使用目标向量对多列进行排序。我想出了以下内容,只是想发布它,因为它可能对其他人也有用。

这有点笨拙,也许更聪明的人有更好、更简洁的方法来做到这一点?

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, function(x, table) {
  match(x, table)
}, 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

创建于 2023-10-05,使用 reprex v2.0.2

© www.soinside.com 2019 - 2024. All rights reserved.