Justin Dhindsa
Justin Dhindsa

Reputation: 109

Ordering column of dataframe by group in different directions

I have an example dataframe:

dd <- data.frame(a = factor(c("Hi", "Hi", "Low", "Low"), 
                 levels = c("Low", "Hi"), ordered = T),
                 b = c(1,2,3,4))
dd
#     a b
# 1  Hi 1
# 2  Hi 2
# 3 Low 3
# 4 Low 4

I'd like to order column b in ascending order if column a has "Hi" as its value, and I'd like to order column b in descending if column a has "Low" as its value. I'd appreciate any help!

Upvotes: 2

Views: 42

Answers (3)

Ronak Shah
Ronak Shah

Reputation: 389325

A base R option, multiply b by 1 if a has 'High' value else multiply it by -1 and order the rows.

with(dd, dd[order(a, b * ifelse(a == 'Hi', 1, -1)), ])

#    a b
#4 Low 4
#3 Low 3
#1  Hi 1
#2  Hi 2

Upvotes: 1

TarJae
TarJae

Reputation: 79311

We could use dplyr::arrange with an ifelse condition. Instead of using desc we could use base R rev function:

library(dplyr)
dd %>% 
    arrange(a, ifelse(a == "Hi", b, rev(b))) %>% 
    arrange(rev(a))

output:

    a b
1  Hi 1
2  Hi 2
3 Low 4
4 Low 3

Upvotes: 2

akrun
akrun

Reputation: 887961

One option is to make use of desc and rev based on the value of 'a'

library(dplyr)
dd %>% 
    arrange(match(a, c("Hi", "Low")),
          case_when(a == "Low"  ~ desc(b), TRUE ~ rev(desc(b))))

-output

    a b
1  Hi 1
2  Hi 2
3 Low 4
4 Low 3

Or another option is to convert the numeric column by changing the sign based on the values in 'a'

dd %>% 
    arrange(match(a, c("Hi", "Low")), b * c(1, -1)[1 + (a == "Low")])
    a b
1  Hi 1
2  Hi 2
3 Low 4
4 Low 3

Upvotes: 2

Related Questions