I am working on a problem where I need to fit many additive models of the form y ~ s(x)
, where the response y
is constant whereas the predictor x
varies between each model. I am using mgcv::smoothCon()
to set up the bases, and lm()
to fit the models. The reason why I do this, rather than calling gam()
directly, is that I need the unpenalized fits. My problem is that smoothCon()
requires it object
argument to be unquoted, e.g., s(x)
, and I wonder how I can generated such unquoted arguments from a character vector of variable names.
A minimal example can be illustrated using the mtcars
dataset. The following snippet shows what I am able to do at the moment:
library(mgcv)
# Variables for which I want to create a smooth term s(x)
responses <- c("mpg", "disp")
# At the moment, this is the only solution which I am able to make work
bs <- list(
smoothCon(s(mpg), data = mtcars),
smoothCon(s(disp), data = mtcars)
)
It would be nicer to be able to generate bs
using some functional programming approach. I imagine something like this, where foo()
is my missing link:
lapply(paste0("s(", responses, ")"), function(x) smoothCon(foo(x),
data = mtcars))
I have tried noquote()
and as.symbol()
, but both fail.
responses <- c("mpg", "disp")
lapply(paste0("s(", responses, ")"),
function(x) smoothCon(noquote(x), data = mtcars))
#> Error: $ operator is invalid for atomic vectors
lapply(paste0("s(", responses, ")"),
function(x) smoothCon(as.symbol(x), data = mtcars))
#> Error: object of type 'symbol' is not subsettable
We can do this by converting to language class
, eval
uate and then apply the smoothCon
library(tidyverse)
out <- paste0("s(", responses, ")") %>%
map(~ rlang::parse_expr(.x) %>%
eval %>%
smoothCon(., data = mtcars))
identical(out, bs)
#[1] TRUE