I'm looking to save an expression like this:
expression <- c(beta_a*a + beta_b*b + beta_d*d)
And I want to return this expression:
expression
> beta_a*a + beta_b*b + beta_d*d
But when I try to run the first line, it just says the error "Object 'beta_a' not found".
Ultimately, I'm using this for Apollo for an ordered logit model, where I have to make 60 different utility specifications. I thought it would be easier bundle the specifications into a short expression, so I can rerun the same code only changing the specification. A specification both consists of defining the beta variables and the utility functions. I was able to use this method for the beta values that have a structure like this:
betas = c(beta_a = 0, beta_b = 0, beta_d = 0)
To turn it into this:
b_specification1 <- c(beta_a = 0, beta_b = 0, beta_d = 0)
betas = b_specification1
But doing the utility function:
u_specification1 <- c(beta_a*a + beta_b*b + beta_d*d)
utility = u_specification1
Gives the error "object 'beta_a' not found". Both b_specification1 and u_specification1 are run before betas and utility.
Define the expression using quote
and then use eval
to evaluate it.
e <- quote(a + b)
a <- 1
b <- 2
eval(e)
## [1] 3
It is also possible to define it as a character string in which case parse
it and then evaluate it.
ch <- "a + b"
a <- 1
b <- 2
eval(parse(text = ch))
## [1] 3
Note that eval
has an envir
argument in case you need to evaluate it looking up variable names in a different environment than the current one. For example,
f <- function(s, envir = parent.frame()) {
eval(parse(text = s), envir)
}
a <- 1
b <- 2
g <- function() {
a <- 3
b <- 4
c(f("a+b"), f("a+b", .GlobalEnv))
}
g()
# [1] 7 3
To combine multiple expressions use substitute
but be careful because it acts differently when run at top level at the console vs within a function. The second argument in the first example is not needed if run within a funciton.
spec1 <- quote(beta_a * a + beta_b * b)
spec2 <- quote(beta_d * d + beta_e * e)
# run at top level
substitute(spec1 + spec2, as.list(environment()))
## beta_a * a + beta_b * b + (beta_d * d + beta_e * e)
# same
substitute(spec1 + spec2, list(spec1 = spec1, spec2 = spec2))
## beta_a * a + beta_b * b + (beta_d * d + beta_e * e)
# run within a function
f <- function() {
spec1 <- quote(beta_a * a + beta_b * b)
spec2 <- quote(beta_d * d + beta_e * e)
substitute(spec1 + spec2)
}
if (exists("spec1")) rm(spec1)
if (exists("spec2")) rm(spec2)
f()
## beta_a * a + beta_b * b + (beta_d * d + beta_e * e)
If using character string use paste
or sprintf
.