In this case, I would recommend refactoring the step that needs to be controlled into a separate function. That way, your logic around controlling execution is clearly separated and the pipe chain can still be a more or less linear flow of steps.
I usually do something similar to the following when I run into this sort of setup.
library(tidyverse)
# Write a tidy, pipe-compliant function that
# takes and returns a `tibble` or `data.frame`
choose_forking_path <- function(df, condition) {
if (condition) {
mutate(df, x = "own")
} else {
mutate(df, x = NA_real_)
}
}
Then, if an external_condition
(or function argument, etc) is set, this function handles the logic around the specifics of the call to mutate()
.
external_condition <- FALSE
tibble(a = 1:4) %>%
group_by(a) %>%
choose_forking_path(external_condition)
#> # A tibble: 4 x 2
#> # Groups: a [4]
#> a x
#> <int> <dbl>
#> 1 1 NA
#> 2 2 NA
#> 3 3 NA
#> 4 4 NA
external_condition <- TRUE
tibble(a = 1:4) %>%
group_by(a) %>%
choose_forking_path(external_condition)
#> # A tibble: 4 x 2
#> # Groups: a [4]
#> a x
#> <int> <chr>
#> 1 1 own
#> 2 2 own
#> 3 3 own
#> 4 4 own
For completeness, you can even embed the if
… else
into your pipe chain, but I think this style gets messy and difficult to follow very quickly.
tibble(a = 1:4) %>%
group_by(a) %>%
{
if (external_condition) {
mutate(., x = "own")
} else {
mtuate(., x = NA_real_)
}
}
#> # A tibble: 4 x 2
#> # Groups: a [4]
#> a x
#> <int> <chr>
#> 1 1 own
#> 2 2 own
#> 3 3 own
#> 4 4 own
Created on 2019-02-26 by the reprex package (v0.2.1)