3

This question though having three answers raised me doubts as I am mulling my head over the problem. Though I am aware that problem can be solved by other methods (and using purrr or apply group of functions especially), Yet I am not sure that can It be actually done through mutate(across(...? I am reproducing the problem for sake of clarity here. Note: I am not looking for its answer but only an answer to my doubt whether two sets of variables can actually be passed through mutate/across

There are two sets of variables (one without suffix and one set with suffix avail).

df <- tibble(a = c(0, 1, 0, 0, 0),
       a_avail = c(1, 1, 1, 0, 0),
       b = c(1, 1, 1, 0, 0),
       b_avail = c(1, 0, 0, 1, 0))
# A tibble: 5 x 4
      a a_avail     b b_avail
  <dbl>   <dbl> <dbl>   <dbl>
1     0       1     1       1
2     1       1     1       0
3     0       1     1       0
4     0       0     0       1
5     0       0     0       0

Now If we want to mutate one set of variables say (a and b) but by comparing these by another set in tandem. That is to say when column a is mutating it may use its corresponding variable a_avail and while b is mutating it is b_avail and so on upto n variables.

I have tried these codes apart from OP has

df %>% mutate(d = row_number()) %>%
  mutate(across(.cols = c(a_avail, b_avail),
                .fns = ~case_when(
                  .x == 1 ~ {str_replace(cur_column(), "_avail", "")[d]},
                  .x == 0 ~ NA_character_
                ),
                .names = "{.col}_new"))

OR

df %>% 
  mutate(across(.cols = c(a, b),
                .fns = ~case_when(
                  glue::glue("{cur_column()}_avail") == 1 ~ .x,
                  glue::glue("{cur_column()}_avail") == 0 ~ as.numeric(NA)
                ),
                .names = "{.col}_new"))

but to no avail. can someone clarify that whether it can be done through mutate(across.. syntax?

AnilGoyal
  • 25,297
  • 4
  • 27
  • 45

1 Answers1

5

You can do this with get with cur_column().

library(dplyr)

df %>% 
  mutate(across(.cols = c(a, b),
                .fns = ~case_when(
                  get(glue::glue("{cur_column()}_avail")) == 1 ~ .x,
                  get(glue::glue("{cur_column()}_avail")) == 0 ~ as.numeric(NA)
                ),
                .names = "{.col}_new"))

#      a a_avail     b b_avail a_new b_new
#  <dbl>   <dbl> <dbl>   <dbl> <dbl> <dbl>
#1     0       1     1       1     0     1
#2     1       1     1       0     1    NA
#3     0       1     1       0     0    NA
#4     0       0     0       1    NA     0
#5     0       0     0       0    NA    NA

PS - I am not sure if this should be an answer to the post that you linked.

Ronak Shah
  • 377,200
  • 20
  • 156
  • 213
  • Exactly this was I looking for. I was not aware of `get` that's why I was not reaching the solution. P.S. This is also the answer of my linked post and you should also post it there please for further reference. Thanks a lot. – AnilGoyal Apr 09 '21 at 05:48