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.
CodePudding user response:
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
CodePudding user response:
Without modifying the position of the other rows, you can use a base
-style assignment.
df[df$COLOR == "BLUE", ] <- df %>%
filter(COLOR == "BLUE") %>%
arrange(desc(NUMBER))
df
# # 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
CodePudding user response:
Here a solution:
library(dplyr)
df %>%
group_by(COLOR) %>%
arrange(row_number(x = if_else(COLOR == "BLUE",-NUMBER,NUMBER )),.by_group = TRUE)