87

With arrange function in dplyr, we can arrange row in ascending or descending order. Wonder how to arrange rows in custom order. Please see MWE.

Reg <- rep(LETTERS[1:3], each = 2) Res <- rep(c("Urban", "Rural"), times = 3) set.seed(12345) Pop <- rpois(n = 6, lambda = 500000) df <- data.frame(Reg, Res, Pop) df Reg Res Pop 1 A Urban 500414 2 A Rural 500501 3 B Urban 499922 4 B Rural 500016 5 C Urban 501638 6 C Rural 499274 df %>% arrange() 

Desired Output

 Reg Res Pop 5 C Urban 501638 6 C Rural 499274 1 A Urban 500414 2 A Rural 500501 3 B Urban 499922 4 B Rural 500016 
0

3 Answers 3

149
Answer recommended by R Language Collective

We can use factor to change the order in a custom way

df %>% arrange(factor(Reg, levels = LETTERS[c(3, 1, 2)]), desc(Res), desc(Pop)) # Reg Res Pop #1 C Urban 501638 #2 C Rural 499274 #3 A Urban 500414 #4 A Rural 500501 #5 B Urban 499922 #6 B Rural 500016 

Or with match to get the index and arrange on it

df %>% arrange(match(Reg, c("C", "A", "B")), desc(Res), desc(Pop)) 

If we have multiple columns to arrange in descending order

df %>% arrange_at(2:3, desc) %>% arrange(match(Reg, c("C", "A", "B"))) 
Sign up to request clarification or add additional context in comments.

6 Comments

Thanks @akrun for nice solution. Is there any was to use desc for all remaining variables without typing their names? Thanks
@MYaseen208 Thanks for the note. I added another option. Hope it helps
Yes, to echo @MYaseen208, is there any way to pick a couple to be at the bottom, but have the rest at the top? For instance, if i have 20 vars, and i want 2 of them at the bottom, this method seems to only work if I name the first 18 in the match. Regardless of the desc() and !match I use, I always get the unnamed values at the bottom.
Just a side note for future viewers: first solution can be shortened to df %>% arrange(factor(Reg, levels = LETTERS[c(3,1,2)]))
It seems that if the sorting variable is already defined as an ordered factor outside of arrange, the behaviour of arrange is still to order alphabetically... How come?
|
19

I used the slice() function:

 df %<>% slice(5,6,1:4) 

1 Comment

I found this the simplest and easiest to follow answer but found I could use %>% rather than %<>%
7

using data.table

df1[order(factor(Reg,levels = LETTERS[c(3,1,2)]))] 

Here df1 is data.table

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.