adl
adl

Reputation: 1441

r - arrange values in a dataframe, within a group, based on a variable, in ascending or descending order

Got stuck with what I think is a very simple solve, but somehow I cannot find a way.

I'm trying to dplyr::arrange values in a dataframe. The thing is I want to apply the function on groups using dplyr::group_by, and decide whether it is in ascending or descending order based on a variable inside.

A simple example:

library(dplyr)

test <- 
    data.frame(
        var1 = c(rep(1,5), rep(2,5)),
        var2 = c(1,3,2,5,9,7,8,3,5,9),
        var3 = c(rep("i", 5), rep("d", 5))
    )

Here I try to arrange by a grouping variable var1, but everything is in ascending order:

test %>% 
    group_by(var1) %>% 
    arrange(var2, .by_group = T)

The goal is to automate arranging based on var3 values. More specifically, by ascending order if the var3 is "i" and in descending order if it is "d", but within the groups.

Desired result:

data.frame(
    var1 = c(rep(1,5), rep(2,5)),
    var2 = c(1,2,3,5,9,9,8,7,5,3),
    var3 = c(rep("i", 5), rep("d", 5)))

Upvotes: 1

Views: 1085

Answers (1)

zack
zack

Reputation: 5415

I think this accomplishes what you're looking for. You can add other cases to the case_when statement as well if there are more scenarios for var3 that you need to tackle. Also, for default sorting, you can add something like TRUE ~ var2 for the last case to handle an unknown value in var3.

test %>% 
  group_by(var1) %>% 
  arrange(case_when(var3 == "i" ~ var2,
                    var3 == "d" ~ -var2), .by_group = T)

# A tibble: 10 x 3
# Groups:   var1 [2]
    var1  var2 var3 
   <dbl> <dbl> <fct>
 1     1     1 i    
 2     1     2 i    
 3     1     3 i    
 4     1     5 i    
 5     1     9 i    
 6     2     9 d    
 7     2     8 d    
 8     2     7 d    
 9     2     5 d    
10     2     3 d  

Upvotes: 3

Related Questions