I've created a function, select_or_return , that should handle both column symbols and lists as input arguments. When providing it with a column symbol, it works as expected. However, when I provide a list, I encounter an error related to the ensym() function from the rlang package.
How could I create a function that can handle both a list or symbol as input argument?
library(rlang)
library(dplyr)
#>
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#>
#> filter, lag
#> The following objects are masked from 'package:base':
#>
#> intersect, setdiff, setequal, union
select_or_return <- function(data, x) {
x_sym <- ensym(x)
# If x is a symbol
if (is_symbol(x_sym)) {
return(data %>% select(!!x_sym))
}
# If x is a list
else if (is.list(x)) {
return(x)
}
# For other cases
else {
stop("x must be a symbol representing a column or a list.")
}
}
# Example usage:
# Create a sample dataframe
df <- data.frame(a = 1:5, b = 6:10)
# Use the function with a column name as a symbol
print(select_or_return(df, a))
#> a
#> 1 1
#> 2 2
#> 3 3
#> 4 4
#> 5 5
# Use the function with a list
print(select_or_return(df, list(1,2,3)))
#> Error in `ensym()`:
#> ! Can't convert to a symbol.
#> Backtrace:
#> ▆
#> 1. ├─base::print(select_or_return(df, list(1, 2, 3)))
#> 2. ├─global select_or_return(df, list(1, 2, 3))
#> 3. │ └─rlang::ensym(x)
#> 4. └─rlang::abort(message = message)
select_or_return <- function(data, x) {
x_sym <- enexpr(x)
if(inherits(x_sym,"call")){
force(x)
x_sym <- x
}
if (is.list(x_sym)) {
return(x_sym)
}
if (is_symbol(x_sym)) {
return(data %>% select(!!x_sym))
}
stop("x must be a symbol representing a column or a list.")
}
It seems to me your wrapper has the same requirements and challenge as what it tries to wrap; so it would need to have essentially the same code within it.
I don't get why it is working when I use the function on it's own but as soon as I wrap it inside another one it is not. I guess it has something to do with the environment.