wayne r
wayne r

Reputation: 129

calling variables within a custom function in r

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

Answers (1)

IceCreamToucan
IceCreamToucan

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

Related Questions