Reputation: 129
I am learning how to write functions in r and something that has tossed me is how to call variables within a function
for example. I am aware that this code works for writing variables in ggplot2
library(ggplot2)
df <- data(iris)
func_test <- function(data, variable1, variable2){
ggplot(data, aes(x = {{variable1}}, y = {{variable2}}) +
geom_point()
}
func_test(df, Sepal.Length, Sepal.Width) # this code processes the variables without the need for a character string like with aes_string()
However when I write this next code, the output does not match how I expect it looks in ggplot
func_test2 <- function(var.name){
{{var.name}}
}
func_test2(testing) # this code does not write out the variable and instead tries to find the object. I just want to return the text output as is
# Error in func_test2(testing) : object 'testing' not found
Here is a specific example of my use case where I create a couple objects in R then write a function intended to reference different columns as variables within a formula.
library(sf)
library(spData)
library(gstat)
library(raster)
library(tidyverse)
# in this example I use data from spData package to reproject a map of US states and interpolate total population in 2010 and 2015
data("us_states")
us_states <- st_transform(us_states, crs = 5070)
us_states[c('lon_m', 'lat_m')] <- us_states %>%
st_centroid(.$geometry) %>%
st_coordinates() %>%
as.data.frame() %>%
dplyr::select('lon_m' = X, 'lat_m' = Y)
us_states_centroid <- us_states %>%
st_drop_geometry() %>%
st_as_sf(.,
coords = c('lon_m', 'lat_m'),
crs = st_crs(us_states))
us_states_proj_grid <- us_states %>%
st_bbox() %>%
st_as_sfc() %>%
st_make_grid(., cellsize = 10000, what = 'centers') %>%
st_as_sf() %>%
cbind(., st_coordinates(.)) %>%
st_drop_geometry() %>%
mutate(., Z = 0)
raster <- rasterFromXYZ(us_states_proj_grid,
crs = crs(us_states))
# I want to use this function and replace variable with different parameters (in this case total_pop_10 and total_pop_15), but R only reads my text as an object
func.var <- function(variable){
model <- gstat(formula = eval(substitute(variable)) ~ 1,
data = as(us_states_centroid, 'Spatial'),
nmax = 10, nmin = 3,
set = list(idp = 2))
interpolate <- interpolate(raster, model)
interpolate
}
interpolation <- func.var(total_pop_15)
# Error in eval(predvars, data, env) : object 'total_pop_15' not found
My question to the forum is, how can I write a variable name to be read into a custom function as plain text like the example above?
Basically, I want to write custom functions that send text into other functions similar to how ggplot reads variables (compare aes() to aes_string()).
Upvotes: 0
Views: 924
Reputation: 28705
You can create expressions with substitute
and evaluate them with eval
Usually there's an easier way to do the thing you're trying to do without creating expressions in this way though. The {{ }}
method only works for specific tidyverse function arguments, it's not an R-wide syntax.
func_test2 <- function(var.name){
x <- 3
y <- 4
eval(substitute(var.name))
}
func_test2(x)
#> [1] 3
func_test2(y)
#> [1] 4
Created on 2022-05-04 by the reprex package (v2.0.1)
Upvotes: 1