Victor Nielsen
Victor Nielsen

Reputation: 493

How to save an expression with multiplication to later call it?

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.

Upvotes: 1

Views: 92

Answers (1)

G. Grothendieck
G. Grothendieck

Reputation: 269854

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.

Upvotes: 3

Related Questions