我正在寻找一种方法,以有效的方式对alphatical顺序的data.table的每一行进行重新排序。因此,我假设每列确实提供相同的信息并且具有可比性。当你看到这个例子时会更有意义:
test <- data.table(A = c("A", "b", "c"),
B = c(1,"a","d"),
C = c("F", 0, 1))
预期结果:
result <- data.table(t(apply(test,1, sort)))
names(result) <- colnames(test)
在这个解决方案中,我必须遍历所有行,这可以防止吗? 对于2列,我找到了解决此问题的有效方法:
result <- data.table(A = pmin(test$A, test$B), B = pmax(test$A, test$B) )
但是这个解决方案不适用于超过2列
编辑:
让我们在两列上添加不同解决方案的基准:
test <- data.table(A = sample(c("A","B", "C", "D"), 1000000, replace = T),
B = sample(c("A","B", "C", "D"), 1000000, replace = T))
OptionOne <- function(test){
result <- data.table(A = pmin(test$A, test$B), B = pmax(test$A, test$B) )
}
OptionTwo <- function(test){
test[, names(test) := as.list(sort(unlist(.SD))), 1:nrow(test)][]
}
OptionThree <- function(test){
test[, id := .I]
test <- melt(test, id.vars = "id")
setorder(test, id, value)
test[, variable1 := seq_len(.N), by = id]
dcast(test, id ~ variable1, value.var = "value")
}
system.time(OptionOne(test))
#user system elapsed
#0.13 0.00 0.12
system.time(OptionTwo(test))
# user system elapsed
# 17.58 0.00 18.27
system.time(OptionThree(test))
#user system elapsed
# 0.23 0.00 0.24
对于两列来说,pmin和pmax似乎是最有效的方式,但对于更多列,重塑可以很好地完成。
答案 0 :(得分:2)
您的data.table在概念上形状错误。对行进行排序(即,对变量进行排序)没有意义。因此,要有效地做到这一点,你需要重塑:
library(data.table)
test <- data.table(A = c("A", "b", "c"),
B = c(1,"a","d"),
C = c("F", 0, 1))
test[, id := .I]
test <- melt(test, id.vars = "id")
setorder(test, id, value)
# id variable value
#1: 1 B 1
#2: 1 A A
#3: 1 C F
#4: 2 C 0
#5: 2 B a
#6: 2 A b
#7: 3 C 1
#8: 3 A c
#9: 3 B d
如果必须,你可以再次重塑,但我不建议这样做。
test[, variable1 := seq_len(.N), by = id]
dcast(test, id ~ variable1, value.var = "value")
# id 1 2 3
#1: 1 1 A F
#2: 2 0 a b
#3: 3 1 c d
答案 1 :(得分:0)
我们可以尝试
test[, names(test) := as.list(sort(unlist(.SD))), 1:nrow(test)][]