Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reorder rows in data.table in a specific order

Tags:

I have a data.table dumdt:

set.seed(123) dumdt <- data.table(v1=sample(1:10, 5), v2=1:5) 

whose rows I'd like to reorder in this specific indices order (so first the third observation, then the fifth, then second, etc.):

to_ord <- c(3, 5, 2, 1, 4) 

So I'd like dumdt to be the result of dumdt[to_ord] but I also would like to do it by reference and avoid doing dumdt <- dumdt[to_ord].

I know I can reorder rows by reference with setorder (or setorderv) but only according to one or several variables, in ascending or descending order, not in a customised order.
However, if I wanted to reorder the columns, not the rows, in a customised order, I could use setcolorder.

So here comes my question : is there a function that would work like setcolorder but with the rows (or a way to use setorder to do the same) ?

My desired output would be something like

setroworder(x=dumdt, neworder=to_ord) dumdt    # v1 v2 # 1:  4  3 # 2:  6  5 # 3:  8  2 # 4:  3  1 # 5:  7  4 
like image 409
Cath Avatar asked Jun 17 '16 09:06

Cath


2 Answers

If I understand correctly, you can just add a col and then order by it:

setorder(dumdt[, .r := order(to_ord)], .r)[, .r := NULL]     v1 v2 1:  4  3 2:  6  5 3:  8  2 4:  3  1 5:  7  4 
like image 139
Frank Avatar answered Oct 05 '22 16:10

Frank


This capability is not (yet) exported. After looking at the source of setorderv I was able to extract required call to C function which does what you need and supply it with custom order.

library(data.table) set.seed(123) dumdt <- data.table(v1=sample(1:10, 5), v2=1:5) print(dumdt) #   v1 v2 #1:  3  1 #2:  8  2 #3:  4  3 #4:  7  4 #5:  6  5 setroworder <- function(x, neworder) {     .Call(data.table:::Creorder, x, as.integer(neworder), PACKAGE = "data.table")     invisible(x) } to_ord <- c(3, 5, 2, 1, 4) setroworder(x=dumdt, neworder=to_ord) print(dumdt) #   v1 v2 #1:  4  3 #2:  6  5 #3:  8  2 #4:  3  1 #5:  7  4 

Yet the solution proposed by Frank looks a little bit nicer.

like image 42
jangorecki Avatar answered Oct 05 '22 17:10

jangorecki