Home > database >  Use case when() across multiple columns and refer to current column names
Use case when() across multiple columns and refer to current column names

Time:09-07

I want to loop using case_when command. Below is my data.

data <- data_frame(
  id = sample(letters[1:15], size = 60, replace = TRUE),
  age = round(runif(60, min = 48, max = 90)),
  a = runif(60),
  b = rnorm(60),
  c = rnorm(60),
  d = rnorm(60),
  e = rnorm(60),
  f = rnorm(60),
  g = rnorm(60),
  h = rnorm(60),
  i = rnorm(60),
  j = rnorm(60),
  k = rnorm(60),
  l = rnorm(60))

data <- data %>% 
  group_by(id) %>%
  arrange(age) %>%
  mutate(across(a:l, ~ .x - lag(.x, default = first(.x)),.names = "{col}_change")) %>%
  mutate(across(a:l, ~ .x - lag(.x, 2, default = first(.x)),.names = "{col}_change1")) %>%
  mutate(across(a:l, ~ .x - lag(.x, 3, default = first(.x)),.names = "{col}_change2")) 

I want to loop this below process from columns "a" to "l".

data$new_a_change <- case_when(data$age < 70 ~ data$a_change,
                               data$age >= 70 & data$age < 80 ~ data$a_change1,
                               data$age >= 80 ~ data$a_change2)

I tried looping with mutate_across, but failed this one.

data <- data %>% 
  mutate(across(a:l, ~ case_when(age <70 ~  which(colnames(data)== paste(.x,"_change") ),
                                 age >70 & age <= 80 ~  which(colnames(data)== paste(.x,"_change1") ),
                                 age >80 ~  which(colnames(data)== paste(.x,"_change2") )), 
                .names = "new_{col}_change") ) 

My desired outcome is data$new_a_change, data$new_b_change... data$new_l_change.

Thank you!

CodePudding user response:

You could use cur_data() cur_column():

data %>% 
  ungroup() %>%
  mutate(across(a:l, ~ case_when(age < 70 ~ cur_data()[[paste0(cur_column(), "_change")]],
                                 age > 70 & age <= 80 ~ cur_data()[[paste0(cur_column(), "_change1")]], 
                                 age > 80 ~ cur_data()[[paste0(cur_column(), "_change2")]]), 
                .names = "new_{.col}_change"))
  • Related