Nils
Nils

Reputation: 120

How to mutate two columns with one case_when expression in R?

Depending on the text in one column I want to assign a character and a integer to two other columns. Multiple case_when conditions (LHS) for assigning the character to one column and the integer to another column are equal only the outcome (RHS) is different. I am using exprs and !!! because I want to maintain the base of the expressions list in only one table.

My code is:

library(rlang)
library(tidyverse)

df <- data.frame(a=c("text-1" , "text_2", "text3"))

e1 <- 
  exprs(
    grepl("text-", a) ~ "a",
    grepl("text_", a) ~ "b",
    grepl("text[0-9]", a) ~ "c"
  )

e2 <- 
  exprs(
    grepl("text-", a) ~ 0,
    grepl("text_", a) ~ 1,
    grepl("text[0-9]", a) ~ 2
  )

test <- df %>% mutate(b=case_when(!!!e1),
                      c=case_when(!!!e2)
)

And expected outcome is:

> test
       a b c
1 text-1 a 0
2 text_2 b 1
3  text3 c 2

But it seems redundant and inefficient (with millions of records) to use two case_when expression lists with the same LHS. How can I reach the same result more efficiently?

Upvotes: 5

Views: 838

Answers (1)

Ronak Shah
Ronak Shah

Reputation: 389335

The main motive behind this is not clear to me but using @zx8754's suggestion we can do

library(dplyr)
library(rlang)

e1 <- exprs(
      grepl("text-", a) ~ "a, 0",
      grepl("text_", a) ~ "b, 1",
      grepl("text[0-9]", a) ~ "c, 2")

df %>% 
  mutate(b=case_when(!!!e1)) %>%
  tidyr::separate(b, into = c("b", "c"), sep = ",", convert = TRUE)

#       a b  c
#1 text-1 a  0
#2 text_2 b  1
#3  text3 c  2

Upvotes: 2

Related Questions