Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

shorten case_when syntax when applying between command over multiple variables

Tags:

r

dplyr

tidyverse

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?

like image 763
user63230 Avatar asked Sep 19 '26 18:09

user63230


1 Answers

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_))
like image 183
akrun Avatar answered Sep 21 '26 09:09

akrun



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!