我想通过将sort.field传递给函数来对我的data.table进行绝对降序排序(即排序忽略符号,例如5,-2、1)。

我已经看过descending sort,但是在我的努力中我遇到了错误,或者我正在转换变量的符号,而没有对其进行正确的排序。

这有效:

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

我已经尝试过各种评估,例如as.name和= 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,然后删除temp列,但是我正在寻找更优雅的解决方案。

编辑:其他人已经指出了类似的answer for filtering。该问题还涉及data.frames,而不仅仅是数据表,并且重点在于过滤数据行。它不使用字段文本的abs()之类的功能进行转换排序,保留所有行并且不更改数据。这个问题也可以帮助其他人查看data.table的这种绝对排序类型,而setorderv()并未涵盖该类型。

最佳答案

试试这个:

sort.field = "score"

sortme <- function(dt, sort.field) dt[order(-abs(dt[[sort.field]]))]

sortme(DT, sort.field)
#   id score
#1:  b     5
#2:  z    -2
#3:  a     1

在第一个函数定义之后,您要做的就是将字符串传递给abs函数,因此将ERROR get non-numeric argument to maths function as it sees string

关于r - 通过函数做data.table的绝对降序排序吗?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/29574716/

10-12 17:23
查看更多