H.B
H.B

Reputation: 55

R - How can I sort rows within groups in descending order?

I am looking for a way to sort the rows in my dataframe in descending order but by particular rows. I have a dataframe which looks like this:

df<- structure(list(Level = c("a", "b", "c", "alpha", "beta", "charlie", 
"red", "yellow", "blue", "green"), group1 = c("3.01", "1.51", 
"0.22", "1.08", "1.95", "1.36", "0.68", "0.1", "1.2", "4.4"), 
    Category = structure(list(Category = c("letter", "letter", 
    "letter", "word", "word", "word", "color", 
    "color", "color", "color")), row.names = c(NA, 
    -10L), class = c("tbl_df", "tbl", "data.frame"))), row.names = c(NA, 
-10L), class = c("tbl_df", "tbl", "data.frame"))

> df
# A tibble: 10 x 3
   Level   group1 Category$Category
   <chr>   <chr>  <chr>            
 1 a       3.01   letter           
 2 b       1.51   letter           
 3 c       0.22   letter           
 4 alpha   1.08   word             
 5 beta    1.95   word             
 6 charlie 1.36   word             
 7 red     0.68   color            
 8 yellow  0.1    color            
 9 blue    1.2    color            
10 green   4.4    color 

I am trying to rearrange the rows by their names in descending order based on the value for the variable 'group1'

This is my desired output:

# A tibble: 10 x 2
   Level   group1
   <chr>   <chr> 
 1 a       3.01  
 2 b       1.51  
 3 c       0.22  
 4 beta    1.95
 5 charlie 1.36  
 6 alpha   1.08  
 7 green   4.4            
 8 blue    1.2
 9 red     0.68  
 10 yellow  0.1

I have already tried using sort and order and subsetting the rows but this hasnt worked for me:

sort(df[1:3,],descending=TRUE)

is there another way for me to achieve this?

Upvotes: 2

Views: 961

Answers (2)

Daniel O
Daniel O

Reputation: 4358

in Base-R (this is not very efficient)

unsplit(lapply(split(df,df$Category), function(x) x[order(x$group1,decreasing=T),]),df$Category)

gives

     Level group1 Category
1        a   3.01   letter
2        b   1.51   letter
3        c   0.22   letter
5     beta   1.95     word
6  charlie   1.36     word
4    alpha   1.08     word
10   green    4.4    color
9     blue    1.2    color
7      red   0.68    color
8   yellow    0.1    color

Upvotes: 0

Ric S
Ric S

Reputation: 9277

One solution using dplyr could be

library(dplyr)

df %>%  
  group_by(Category) %>% 
  arrange(desc(group1), .by_group = TRUE)

Output

# A tibble: 10 x 3
# Groups:   Category [3]
#    Level   group1 Category
#    <chr>   <chr>  <chr>   
#  1 green   4.4    color   
#  2 blue    1.2    color   
#  3 red     0.68   color   
#  4 yellow  0.1    color   
#  5 a       3.01   letter  
#  6 b       1.51   letter  
#  7 c       0.22   letter  
#  8 beta    1.95   word    
#  9 charlie 1.36   word    
# 10 alpha   1.08   word 

This solution also orders the dataframe by Category

Upvotes: 1

Related Questions