I am trying to treat a character string as a column name in case_when:
Data:
> df <- data.frame(col1 = c(NA, 1, 1, 0, 0),
col2 = c(NA, 1, 1, 0, 0),
col1_add=1:5,
col2_add=c(6:9,NA))
> df
col1 col2 col1_add col2_add
1 NA NA 1 6
2 1 1 2 7
3 1 1 3 8
4 0 0 4 9
5 0 0 5 NA
Attempt:
df %>% mutate_at(c("col1_add", "col2_add"), ~case_when(as.name(str_remove(., "_add"))==1 & .>3 ~ 0, TRUE ~ .))
How can str_remove(., "_add")
be treated as a column name (col1, col2
)?
CodePudding user response:
We can use across
with cur_column()
(cur_column()
- returns the column name, where the str_remove
is used to remove the substring "_add", use get
to get the value of the corresponding column, apply the logic in case_when
library(dplyr)
library(stringr)
df %>%
mutate(across(ends_with("_add"),
~ case_when(get(str_remove(cur_column(), "_add")) == 1 &
.x >3 ~ 0L, TRUE ~ .x)))
-output
col1 col2 col1_add col2_add
1 NA NA 1 6
2 1 1 2 0
3 1 1 3 0
4 0 0 4 9
5 0 0 5 NA
NOTE: It was previously possible to get the column name with deparse/substitute
from mutate_at
, but now it is not possible in the newer dplyr
versions. In addition, the _at/_all
are deprecated in favor of across