Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Use custom function (with tidy eval) within mutate & across

I have the following data:

my_data <- structure(list(case_one = c("A", "B", "A", "B", "A", "B", "A", 
"B", "A", "B"), case_two = c("A", "A", "A", "A", "A", "B", "B", 
"B", "B", "B"), id = 1:10), class = c("tbl_df", "tbl", "data.frame"
), row.names = c(NA, -10L))


# A tibble: 10 × 3
   case_one case_two    id
   <chr>    <chr>    <int>
 1 A        A            1
 2 B        A            2
 3 A        A            3
 4 B        A            4
 5 A        A            5
 6 B        B            6
 7 A        B            7
 8 B        B            8
 9 A        B            9
10 B        B           10

What works:

creating custom function and using it to transform each column individually

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

times_100 <- function(data, case_column){
  data %>%
    mutate("{{case_column}}" := case_when(
      {{case_column}} == "A" ~ paste({{case_column}}, id, sep = "_"),
      {{case_column}} == "B" ~ paste({{case_column}}, id * 100, sep = "_")
    ))
}


my_data %>%
  times_100(case_one) %>% 
  times_100(case_two)


# A tibble: 10 × 3
   case_one case_two    id
   <chr>    <chr>    <int>
 1 A_1      A_1          1
 2 B_200    A_2          2
 3 A_3      A_3          3
 4 B_400    A_4          4
 5 A_5      A_5          5
 6 B_600    B_600        6
 7 A_7      B_700        7
 8 B_800    B_800        8
 9 A_9      B_900        9
10 B_1000   B_1000      10

What I want:

Using the custom function to work within mutate(across(contains("case")), so I can apply it to multiple columns at once.

# like this: 
my_data %>%
  mutate(across(contains("case"), ~ tolower(.x)))

# but with my custom function

I tried different ways of changing my function so it would work within that context, but cant get it to work.

>Solution :

Another option, which corresponds to your expected function, is to drop the mutate call and the data argument and use case_when() directly, but we need to add id as argument to access the column:

library(dplyr)

times_100 <- function(x, id) {
  case_when(
      x == "A" ~ paste(x, id, sep = "_"),
      x == "B" ~ paste(x, id * 100, sep = "_")
    )
}

my_data %>%
  mutate(across(contains("case"), ~ times_100(.x, id)))

Data from OP

my_data <- structure(list(case_one = c("A", "B", "A", "B", "A", "B", "A", 
"B", "A", "B"), case_two = c("A", "A", "A", "A", "A", "B", "B", 
"B", "B", "B"), id = 1:10), class = c("tbl_df", "tbl", "data.frame"
), row.names = c(NA, -10L))
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading