Lets say we're using mtcars dataset and want to create a variable based on another within a certain interval, I can use between command and case_when:
library(tidyverse)
test <- mtcars %>%
mutate(new_var = case_when(
between(cyl, 0, 170)~ cyl,
TRUE ~ NA_real_)
)
However is there a way to shorten this if we are looking over many variables (say 30+) at once within the same intervals. For example, take just 5 variables here:
test <- mtcars %>%
mutate(new_var = case_when(
between(cyl, 0, 170) &
between(disp, 0, 170) &
between(hp, 0, 170) &
between(drat, 0, 170) &
between(wt, 0, 170) ~ cyl,
TRUE ~ NA_real_)
)
I thought there could be a way using all command and passing a vector of the variables through %in% but cant think of a way. Would anyone have a suggestion?
An option would be to create the logical columns with mutate_at, then reduce to a single logical vector for passing onto case_when
library(tidyverse)
test1 <- mtcars %>%
mutate_at(vars(cyl:wt), list(new= ~ between(., 0, 170))) %>%
mutate(new_var = case_when(reduce(select(.,ends_with('new')), `&`)
~ cyl, TRUE ~ NA_real_)) %>%
select(-ends_with('new'))
all.equal(test, test1)
#[1] TRUE
Another option is map
mtcars %>%
select(cyl:wt) %>%
map(~ between(.x, 0, 170)) %>%
reduce(`&`) %>%
bind_cols(mtcars, new_var = .) %>%
mutate(new_var = case_when(new_var ~ cyl, TRUE ~ NA_real_))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With