4

After seeing Sort a data.table fast by Ascending/Descending order

I would like to wrap either

X <- X[order(Year, MemberID, -Month)]

or

X[,Month:=-Month]
setkey(X,Year,MemberID,Month)
X[,Month:=-Month]

Into a function, like d.setkey(data, key)

However, seems order and := rhs only accept column names instead of character, I don't know how I can pass argument?

Community
  • 1
  • 1
colinfang
  • 20,909
  • 19
  • 90
  • 173

1 Answers1

4

You can use get:

DT[, "Month" := -get("Month"),with=TRUE]

Or :

DT[,`:=`("Month"=-get("Month"))]

Or more general using an expression:

expr <- substitute(x := -x,  list(x=as.name("Month")))
DT[,eval(expr)]
agstudy
  • 119,832
  • 17
  • 199
  • 261
  • why i cannot use `DT[,Month:=-as.name("Month")]`? – colinfang Nov 12 '13 at 13:21
  • because you cannot do `-as.name("Month")`. (Not related to data.table here) – agstudy Nov 12 '13 at 13:26
  • 3
    you can also do `DT[, "Month" := -eval(as.name("Month"))]` in 1.8.11 (and this is much more efficient than `get`, as the latter constructs *all* columns from `DT`) – eddi Nov 12 '13 at 18:02
  • @eddi what does "constructs all columns" mean? Can you elaborate a bit more? – colinfang Nov 13 '13 at 01:05
  • 1
    @colinfang `data.table` generally tries to understand the j-expression and figure out what columns are used and only internally populates those columns to do further operations with, like grouping (I'm actually not 100% sure it does that when there is no by). Unfortunately that logic goes out of the door the moment `get` or `.SD` are used, which is why those should generally be avoided if speed is a consideration. I actually added a FR today motivated by this question to internally replace get. – eddi Nov 13 '13 at 03:12