我希望能够通过将排序字段传递到函数来执行绝对值降序排序(即忽略符号排序,例如 5、-2、1)。我的
下面是可以正常工作的内容:
data.table
上已经查看了降序排序,但是在我的尝试中,我遇到了错误或者变换了变量的符号,而没有正确地进行排序。下面是可以正常工作的内容:
library(data.table)
DT <- data.table(id = c("a","b","z"),
score = c(1, 5, -2))
DT1 <- copy(DT)
#doing sort direct works
DT1 <- DT1[order(-abs(score))]
# i.e. b, Z, a
但是当传递参数时,我找不到正确的语法(数学错误,必须提供j等)。
#in function
sort.field = "score"
sortme <- function(dt, sort.field){
dt <- dt[order(-abs(sort.field))]
}
DT2 <- sortme(DT, sort.field)
# ERROR get non-numeric argument to maths function as it sees string
我尝试了各种不同的evals、as.name、with = F等方法。
dt <- dt[, order(-abs(as.name(sort.field))]
# even
expr <- substitute(x := -abs(x), list(x=as.name(sort.field)))
dt<- dt[,eval(expr)]
DT3 <- DT[,eval(expr)] # changes all to negative
DT4 <- DT[order(eval(expr))] # DT not happy
请让我解脱吧!非常感谢。
P.S. setorderv()
处理纯粹的升序和降序情况。是的,我可以添加一列,对其取绝对值,然后使用 setorderv,最后删除临时列,但我正在寻找一个更加优雅的解决方案。
编辑:其他人指出了类似于 筛选答案 的问题。该问题也涉及到数据帧,而不仅仅是数据表,并且专注于过滤数据行。它没有使用像 abs()
这样的函数进行转换排序,保留所有行并且不改变数据。同时,这个问题可能有助于其他寻找 data.table
的绝对排序类型的人,因为它在其 setorderv()
中没有涵盖。
with = FALSE
。我的错误是重新分配数据表,而不仅仅是按引用搜索 - 因此在排序时应该避免使用DT <- DT [..]。我的答案与众不同,因为我试图在列名上放置一个函数,这有点棘手,我希望这个答案能帮助其他人。 - micstr[.data.table
调用中传递一个字符串列名(或名称向量)进行评估。无论它是在i
还是j
字段中;特定操作是什么;或者你是否要求将其转换为函数,都不会改变问题和答案的核心。我不介意它没有被投票为重复,但我认为有一个相当好的案例。我希望当有人询问如何对字符串列进行“大小写无关排序”时,我们至少可以将其标记为重复使用此内容。 - Frankdata.table
包非常复杂,因此掌握它可能会有些棘手。什么时候使用as.name()
,什么时候使用with = F
,难怪FAQ开头就是“为什么DT [,5]返回5!”。初学者可能还没有意识到变量选择= 通过函数= 参数化是相似的,尽管这对于全职编码人员来说可能是显而易见的。 - micstr