I can make a function that takes object names as arguments (this is just a normal function).
I can also now make a function that get's its data and column arguments via a named vector (utilising dataset <- eval(sym(dataset))
and date_col <- sym(date_col)
).
However I would like a function that can handle both types of inputs.
Step one is to detect the class of the input.
For the dataset argument, this (below) works fine for both the named vector and the actual object name.
if (is.character(dataset)) {
dataset <- eval(sym(dataset)) }
I am not able to figure out the appropriate way to handle the column arguments, however.
When I use the named-vector elements for them, the process (below) works fine.
if (is.character(date_col)) {
date_col <- sym(date_col) }
But I am unsure how to handle the actual column name (ie by adding in an else
component, above).
Essentially I want to turn it into a sym so I can still use the {{}} (or !!) in the function's steps.
Here is a minimum reproducible example for what I am after. As you will see the named vector version works but not the actual dataset and column names.
Is what I'm after even possible? Can a function be dynamic in this way or do I need to make two separate functions?
[edited: made a simpler example, as per comment]
library(dplyr)
library(rlang)
new_table <- tibble(
Date = seq.Date(as.Date("2016-01-01"), as.Date("2019-12-31"), 1)) %>%
mutate(total_sales = rnorm(n()))
f_arguments <- c("dataset" = "new_table",
"date_col" = "Date",
"sales_col" = "total_sales")
f <- function(data, x, envir = parent.frame()) {
if (is.character(data)) {
data <- get(data, envir)}
if (is.character(x)) {
x <- sym(x) }
data %>%
mutate(year_month = lubridate::floor_date(!!ensym(x), "months"),
year = lubridate::year(!!ensym(x)))
}
# this (below) works per the above code, but not if I comment out
# the if (is.character(x)) line
f(f_arguments[["dataset"]],
f_arguments[["date_col"]])
# this (below) does not work with the above code, but it will work if I comment out
# the if (is.character(x)) line
f(new_table, Date)