Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to arrange only some rows of a dataframe, based on a condition without affecting the rest of the rows (in R)

i have a data frame like this:

df <- tibble::tribble(
   ~COLOR, ~NUMBER, ~VALUE,
  "BLACK",      1L,   100L,
  "BLACK",      2L,   200L,
   "BLUE",      1L,   100L,
   "BLUE",      2L,   500L,
   "BLUE",      3L,   600L,
    "RED",      1L,   200L,
    "RED",      2L,   300L)

I would like to arrange only the rows labeled "BLUE" in the COLOR column in descending order by the value of the NUMBER column, without modifying the position or order of the other rows, like this:

tibble::tribble(
    ~COLOR, ~NUMBER, ~VALUE,
    "BLACK",    1L,   100L,
    "BLACK",    2L,   200L,
    "BLUE",     3L,   600L,
    "BLUE",     2L,   500L,
    "BLUE",     1L,   100L,
    "RED",      1L,   200L,
    "RED",      2L,   300L)

It seems like an easy task, i've been trying with different some combinations of 'arrange()', 'across()', and 'group_by', but I am not getting the correct code.

I think the code might be like this:

df %>%
  group_by(COLOR) %>%
  arrange(.by_group = TRUE, if(condition == COLOR = "BLUE", true = desc(NUMBER)))

I appreciate the help. Thank you.

like image 704
AlvaroFernandez56 Avatar asked Oct 21 '25 13:10

AlvaroFernandez56


1 Answers

If the column is numeric, we may just modify the values in 'NUMBER' to negative where COLOR is "BLUE" within arrange to order in descending

library(dplyr)
df %>% 
    arrange(factor(COLOR, levels = unique(COLOR)),
      NUMBER * c(1, -1)[(COLOR == "BLUE") + 1])

-output

# A tibble: 7 × 3
  COLOR NUMBER VALUE
  <chr>  <int> <int>
1 BLACK      1   100
2 BLACK      2   200
3 BLUE       3   600
4 BLUE       2   500
5 BLUE       1   100
6 RED        1   200
7 RED        2   300

Or another option with group_by/group_modify in case the column is not numeric

df %>% 
  group_by(COLOR = factor(COLOR, levels = unique(COLOR))) %>%
  group_modify(~ .x %>% arrange(if(.y == "BLUE") desc(NUMBER) else 
       NUMBER, .by_group = TRUE)) %>% 
  ungroup

-output

# A tibble: 7 × 3
  COLOR NUMBER VALUE
  <chr>  <int> <int>
1 BLACK      1   100
2 BLACK      2   200
3 BLUE       3   600
4 BLUE       2   500
5 BLUE       1   100
6 RED        1   200
7 RED        2   300
like image 139
akrun Avatar answered Oct 24 '25 03:10

akrun



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!