user2165857
user2165857

Reputation: 2710

R: Convert a string from a function input to part of an expression in the function

I'm trying to use a string input for a function that then needs to be converted into useable form in R. For example:

I have the following function:

MyFunction <- function(MyDataFrame){ 
Fit <- aov(VariableA ~ A * B * C, MyDataFrame)
model = lme(VariableA ~ A * B * C, random=~1| Sample, method="REML", MyDataFrame)
return(anova(model))
}

This works fine. However, I sometimes want to use different formulas with a single function so my "Expression" can be "A * B * C" or "A * C". I tried using:

MyFunction <- function(MyDataFrame, Expression = "A * B * C"){ 
Fit <- aov(VariableA ~ Expression, MyDataFrame)
model = lme(VariableA ~ Expression, random=~1| Sample, method="REML", MyDataFrame)
return(anova(model))
}

This does not work. Any suggestions?

Upvotes: 0

Views: 288

Answers (2)

Julia Silge
Julia Silge

Reputation: 11663

R needs to know that the formula is actually a formula, and you run into issues with evaluating expressions, environments, and so forth when you have a string that you want to use as an expression in a formula. Based on what it looks like you are trying to do, I would probably set up my function like so:

library(nlme)

fun <- function(df, response, predictors){ 
  model_formula <- as.formula(paste0(response, " ~ ", predictors))
  fit <- aov(model_formula, df)
  model = nlme::lme(model_formula, df)
  return(anova(model))
}

fun(Orthodont, "distance", "age")
#>             numDF denDF   F-value p-value
#> (Intercept)     1    80 3096.4889  <.0001
#> age             1    80   85.8464  <.0001
fun(Orthodont, "distance", "age + Sex")
#>             numDF denDF  F-value p-value
#> (Intercept)     1    80 4226.931  <.0001
#> age             1    80  111.949  <.0001
#> Sex             1    25    4.429  0.0456

Upvotes: 1

Mike H.
Mike H.

Reputation: 14370

For your purposes, you don't even need to use strings, you could pass the expression directly and use match.call() with an eval(). A toy example is:

fun <- function(data, expression){
  m <- match.call()
  lm(hp ~ eval(m$expression), data)
}


fun(mtcars, cyl)
#Call:
#lm(formula = hp ~ eval(m$expression), data = data)

#Coefficients:
#       (Intercept)  eval(m$expression)  
#            -51.05               31.96  

Upvotes: 1

Related Questions