I have a dataframe with variable number of columns. I want to pass
for instance let's say I have the dataframe df and I want to pass columns a and b as individual arguments to my custom function; but the issue is that the list of column names of interest changes depending on the outcome of another operation and could be any lemgth etc.
df <- tibble(a = c(1:3), b = c(4:6), c=(7:9), d=c(10:12))
custom_function <- function(...){ do something }
custom_function(df$a, df$b)
I haven't found a clean way to achieve this. Any help would be great.
UPDATE
for better clarity I need to add that the challenge is the fact the list of columns of interest is retrieved from another variable. for instance col_names <- c("a","b")
CodePudding user response:
We can capture the ...
as a list
can then apply the function within do.call
custom_function <- function(fn, data = NULL, ...) {
args <- list(...)
if(length(args) == 1 && is.character(args[[1]]) && !is.null(data)) {
args <- data[args[[1]]]
}
do.call(fn, args)
}
custom_function(pmax, df$a, df$b)
[1] 4 5 6
and we can pass ridge
> custom_function(ridge, df$a, df$b)
[,1] [,2]
[1,] 1 4
[2,] 2 5
[3,] 3 6
attr(,"class")
[1] "coxph.penalty"
...
> custom_function(ridge, data = df, c("a", "b"))
a b
[1,] 1 4
[2,] 2 5
[3,] 3 6
attr(,"class")
[1] "coxph.penalty"
attr(,"pfun")
...
> custom_function(ridge, data = df, col_names)
a b
[1,] 1 4
[2,] 2 5
[3,] 3 6
attr(,"class")
...
CodePudding user response:
If your outcome is a data.frame, a possibility is to use the the curly-curly tidyverse
operator, using the command {{}}
, the goal of this operator is to allow us to have an argument passed to our function refering to a column inside a dataframe.
Data
df <- tibble(a = c(1:3), b = c(4:6), c=(7:9), d=c(10:12))
Example
library(dplyr)
operations <- function(df,col1,col2){
df %>%
summarise(
n = n(),
addition = {{col1}} {{col2}},
subtraction = {{col1}} - {{col2}},
multiplication = {{col1}} * {{col2}},
division = {{col1}} / {{col2}}
)
}
Output
operations(df,a,b)
# A tibble: 3 x 5
n addition subtraction multiplication division
<int> <int> <int> <int> <dbl>
1 3 5 -3 4 0.25
2 3 7 -3 10 0.4
3 3 9 -3 18 0.5