Say I have this tibble:
df <- tibble::tribble(
~how_bright_txt, ~how_bright_num, ~how_hard_txt, ~how_hard_num, ~how_hot_txt, ~how_hot_num,
"Not very much", 1L, "Really hard", 5L, "Cold", 1L,
"Somewhat", 2L, "Somewhat hard", 2L, "A bit cold", 2L,
"Medium", 3L, "Medium", 3L, "Medium", 3L,
"Quite a bit", 4L, "Quite hard", 4L, "Quite hot", 4L,
"A lot", 5L, "Not very hard", 1L, "Really hot", 5L
)
I want to make new columns named with the first part of the existing column names (minus the _txt or _num prefix) and which take the value of the _txt columns but converting them to factors ordered by the corresponding _num columns.
I can do this by repeating fct_reorder inside mutate for each column, like so:
require(tidyverse)
df %>%
mutate(how_bright = fct_reorder(how_bright_txt, -how_bright_num),
how_hard = fct_reorder(how_hard_txt, -how_hard_num),
how_hot = fct_reorder(how_hot_txt, -how_hot_num)) %>%
select(-c(ends_with("_txt"), ends_with("_num")))
But I want to streamline this and use mutate(across()). So I tried doing this:
df %>%
mutate(across(ends_with("_txt"),
~ fct_reorder(.x, str_replace(.x, "_txt", "_num")),
.names = '{stringr::str_remove({col}, "_txt")}')) %>%
select(-c(ends_with("_txt"), ends_with("_num")))
But the ordering of the resulting factors (how_bright, how_hard, how_hot) are incorrect and don't correspond to the ordering in the original _num columns. I have also tried replacing the str_replace call with a gsub call but I get the same output
Can anyone see what I'm doing wrong?
What you need is
cur_column()andget().cur_column()gives the current column name, i.e.*_txt. Afterstr_replace()is used on it,get()searches the new name (i.e.*_num) in the current dataset and returns its values.