If you mean just avoiding using which.max you could do something like this:
dplyr::mutate(
tibble::tibble(
a = c("X", "Y", "X", "Y", "Z"),
b = LETTERS[1:5],
c = c(rep.int(3, 2), rep.int(5, 1), rep.int(2, 2))
),
b = dplyr::if_else(
a == "X",
dplyr::filter(
dplyr::pick(tidyselect::everything()),
a == "X"
) |>
dplyr::slice_max(c, n = 1) |>
dplyr::pull(b),
b
)
)
#> # A tibble: 5 × 3
#> a b c
#> <chr> <chr> <dbl>
#> 1 X C 3
#> 2 Y B 3
#> 3 X C 5
#> 4 Y D 2
#> 5 Z E 2
But I kind of like the succinctness of how you wrote it above.
library(tidyverse)
t <- tibble(
a=c('X', 'Y', 'X', 'Y', 'Z'),
b=LETTERS[1:5],
c = c(rep.int(3,2), rep.int(5,1), rep.int(2,2))
)
t |>
mutate(
temp =
t |>
slice_max(c) |>
pull(b),
b = if_else(a == 'X', temp, b)
) |>
select(!temp)
#> # A tibble: 5 × 3
#> a b c
#> <chr> <chr> <dbl>
#> 1 X C 3
#> 2 Y B 3
#> 3 X C 5
#> 4 Y D 2
#> 5 Z E 2