Sort rows in data.table in decreasing order on string key `order(-x,v)` gives error on data.table 1.9.4 or earlier
Solution 1
Update
data.table v1.9.6+ now supports OP's original attempt and the following answer is no longer necessary.
You can use DT[order(-rank(x), y)]
.
x y v
1: c 1 7
2: c 3 8
3: c 6 9
4: b 1 1
5: b 3 2
6: b 6 3
7: a 1 4
8: a 3 5
9: a 6 6
Solution 2
You can only use -
on the numeric entries, so you can use decreasing and negate the ones you want in increasing order:
DT[order(x,-v,decreasing=TRUE),]
x y v
[1,] c 1 7
[2,] c 3 8
[3,] c 6 9
[4,] b 1 1
[5,] b 3 2
[6,] b 6 3
[7,] a 1 4
[8,] a 3 5
[9,] a 6 6
Solution 3
DT[order(-x)]
works as expected. I have data.table version 1.9.4. Maybe this was fixed in a recent version.
Also, I suggest the setorder(DT, -x)
syntax in keeping with the set* commands like setnames
, setkey
Comments
-
nhern121 over 4 years
Let's say I have the following
data.table
inR
:library(data.table) DT = data.table(x=rep(c("b","a","c"),each=3), y=c(1,3,6), v=1:9)
I want to order it by two columns (say columns
x
andv
). I used this:DT[order(x,v)] # sorts first by x then by v (both in ascending order)
But now, I want to sort it by
x
(in decreasing order) and have the following code:DT[order(-x)] #Error in -x : invalid argument to unary operator
Therefore, I think this error is due to the fact that
class(DT$x)=character
. Could you give me any suggestion in order to solve this issue?I know I can use
DT[order(x,decreasing=TRUE)]
, but I want to know the syntax to sort by several columns using both ways (some decreasing, some increasing) at the same time.Note that if you use
DT[order(-y,v)]
the result is ok, but if you useDT[order(-x,v)]
there is an error. So, my question is: how to solve this error? -
Matthew Plourde over 11 yearsI like this way, unless you have two
character
columns and you want to sort one increasing and the other decreasing. -
nhern121 over 11 years@mplourde I think you can combine your solution with this one to tackle the problem you have posed. For instance, you can put:
DT[order(x,-rank(w),decreasing=TRUE)]
given thatx
andw
are both character columns. Thank you! -
MichaelChirico about 8 yearsAs pointed out by @PankilShah below this has been fixed for some time and OP's original approach now works as expected. I couldn't find the commit since it was fixed on the C level and I don't know what to search for.
-
MichaelChirico about 8 yearsCool, thanks. It seems unlikely that anyone would end up here... but on the other hand I myself ended up here from googling something vaguely-related.
-
Matthew Plourde about 8 years@MichaelChirico actually, I routinely get up-votes for this answer, so I'm really glad you pointed this out. I'm not really a data.table user and haven't been keeping up with its development.
-
smci about 6 yearsIt's very useful to state the actual release number (1.9.6?), so we don't have to go hunt in the archives of NEWS.md.