I'm chaining two functions together where both use the same column to perform some operation. I'd like to be able to specify this column as the input parameter only on the call to the first function but also have it accessible within the second function when I pass the output of function 1 into function 2.
The code below demonstrates what I mean and where i'm getting different results from what I want.
filter_function <- function(.x, .y){
.x %>%
dplyr::filter({{ .y }} != 4)
}
count_function <- function(.x, .y){
.x %>%
dplyr::count({{ .y }})
}
filter_function(mtcars %>% as_tibble(), cyl) %>%
count_function(.)
This returns a single value of 21
which is the count of all rows remaining in the tibble after filtering on cyl != 4
, as per the filter_function
. But what I want it to output is the same as:
mtcars %>%
as_tibble() %>%
filter(cyl != 4) %>%
count(cyl)
# A tibble: 2 × 2
cyl n
<dbl> <int>
1 6 7
2 8 14
So is there is a way I can access .y
in count_function
(within the context of chaining two functions together like in this example), without explicitly passing it to count_function
as a parameter?
1) If we reverse the order of the functions then the column of interest will always be first so we won't need to know which one it is:
library(dplyr)
mtcars %>%
count_function(cyl) %>%
filter_function(.[[1]])
## cyl n
## 1 6 7
## 2 8 14
2) The same idea holds more generally even if we keep the order of the functions:
mtcars %>%
relocate(cyl) %>%
filter_function(.[1]) %>%
count_function(.[1])
3) If the reason to do this is just that cyl
is only referred to once to make it easier to change later we could put it in a variable.
v <- "cyl"
mtcars %>%
filter_function(!!sym(v)) %>%
count_function(!!sym(v))
or we could perform the assignment within the pipeline in which case it will not be visible outside the pipeline.
mtcars %>% {
v <- "cyl"
filter_function(., !!sym(v)) %>%
count_function(!!sym(v))
}
4) It would also be possible to pass information via attributes
mtcars %>%
structure(var = "cyl") %>%
filter_function(!!sym(attr(., "var"))) %>%
count_function(!!sym(attr(., "var")))
5) A dummy column could be used.
mtcars %>%
mutate(dummy = "cyl") %>%
filter_function(!!sym(first(.$dummy))) %>%
count_function(!!sym(first(.$dummy)))