Bogaso
Bogaso

Reputation: 3308

Using pipe operation in R properly

I was examining below code

library(dplyr)
DF = data.frame('A' = 1:3, 'B' =2:4)
Condition = 'A'
fn1 = function(x) x + 3
fn2 = function(x) x + 5
DF %>% mutate('aa' = 3:5) %>%
{if (Condition == 'A') {
bb = . %>% mutate('A1' = fn1(A), 'B1' = fn1(B)) 
bb
} else {
bb = . %>% mutate('A1' = fn2(A), 'B1' = fn2(B)) 
bb
}   
}

Basically, I have 2 similar functions fn1 and fn2. Now based on some condition, I want to use one of these functions.

Above implementation is throwing below error -

Functional sequence with the following components:

 1. mutate(., A1 = fn1(A), B1 = fn1(B))

Use 'functions' to extract the individual functions. 

Can you please help be how to properly write the pipe sequence to execute above code?

Upvotes: 1

Views: 78

Answers (1)

akrun
akrun

Reputation: 886938

We could use across within mutate

library(dplyr)
DF %>% 
   mutate(aa = 3:5, across(c(A, B), ~  if(Condition == 'A') fn1(.) 
         else fn2(.), .names = "{.col}1"))

-output

  A B aa A1 B1
1 1 2  3  4  5
2 2 3  4  5  6
3 3 4  5  6  7

Also, an option is to get the functions in a list and convert the logical vector to numeric index for subsetting

DF %>% 
   mutate(aa = 3:5, 
   across(c(A, B), ~  list(fn2, fn1)[[1 + (Condition == 'A')]](.), 
         .names = "{.col}1"))

-output

 A B aa A1 B1
1 1 2  3  4  5
2 2 3  4  5  6
3 3 4  5  6  7

Based on the comments, if we need a custom name for the new columns, create a named vector and replace with str_replace_all

library(stringr)
nm1 <- setNames(c("XXX", "YYY"), names(DF)[1:2])
DF %>% 
   mutate(aa = 3:5, 
   across(c(A, B), ~  list(fn2, fn1)[[1 + (Condition == 'A')]](.), 
         .names = "{str_replace_all(.col, nm1)}"))
  A B aa XXX YYY
1 1 2  3   4   5
2 2 3  4   5   6
3 3 4  5   6   7

Upvotes: 3

Related Questions