Home > Enterprise >  Why can't the utility function be condensed to a single argument in Apollo?
Why can't the utility function be condensed to a single argument in Apollo?

Time:01-06

I am using Apollo for an ordered logit model. Since I have to make over 100 specifications, I wanted to condense it a bit, so I don't have to make it too hard and painful for myself to go through the process.

If I condense betas by first specifying them as a single argument like this:

randstad <- c(
  #b_randstad_is = 0,
  b_randstad_not = 0,
  b_randstad_to = 0,
  b_randstad_from = 0
)

wdist <- c(
  b_weekdist_dec    = 0,
  b_weekdist_inc    = 0,
  b_weekdist_same         = 0,
  #b_weekdist_nojob              = 0,
  b_weekdist_lostjob             = 0,
  b_weekdist_gotjob              = 0,
  b_weekdist_alwayswfh  = 0,
  b_weekdist_wfhtocommuting = 0,
  b_weekdist_commutingtowfh = 0,
  b_weekdist_differingaddresses  = 0
)

spec1 <- c(
  randstad,
  wdist
)

apollo_beta = c(spec1,
                tau_nautos_change_1                = 0,
                tau_nautos_change_2                = 1)

It totally works, and it's very handy cause I can save a lot of coding space by doing that and condense all the specifications in a separate file.

However, doing the same with the utility function does not work. Since it is an equation and not a list, I use the quote function:

uspec1 <- quote(
  #b_randstad_is*randstad_change_randstad   
  b_randstad_not*randstad_change_notrandstad   
  b_randstad_to*randstad_change_torandstad   
  b_randstad_from*randstad_change_fromrandstad  
  b_weekdist_dec*weekdist_woonwerk_changecat_decreasedcommute  
  b_weekdist_inc*weekdist_woonwerk_changecat_increasedcommute  
  b_weekdist_same*weekdist_woonwerk_changecat_samecommute  
  #b_weekdist_nojob*weekdist_woonwerk_changecat_nojob  
  b_weekdist_lostjob*weekdist_woonwerk_changecat_lostjob  
  b_weekdist_gotjob*weekdist_woonwerk_changecat_gotjob  
  b_weekdist_alwayswfh*weekdist_woonwerk_changecat_alwaysworkfromhome  
  b_weekdist_wfhtocommuting*weekdist_woonwerk_changecat_workfromhometocommuting  
  b_weekdist_commutingtowfh*weekdist_woonwerk_changecat_commutingtoworkfromhome  
  b_weekdist_differingaddresses*weekdist_woonwerk_changecat_differingaddresses
) 

... 

  ol_settings = list(outcomeOrdered = nautos_change,
                     utility        =   
                                      uspec1,
                     tau            = list(tau_nautos_change_1, tau_nautos_change_2))

This gives the error "Error in apollo_preprocess(inputs = ol_settings, modelType, functionality, : "utility" for model component "OL" needs to be a function, a scalar, or a vector/matrix/cube with one row per observation in the "database""

Keep in mind that if I simply write:

  ol_settings = list(outcomeOrdered = nautos_change,
                     utility        =   
  #b_randstad_is*randstad_change_randstad   
  b_randstad_not*randstad_change_notrandstad   
  b_randstad_to*randstad_change_torandstad   
  b_randstad_from*randstad_change_fromrandstad  
  b_weekdist_dec*weekdist_woonwerk_changecat_decreasedcommute  
  b_weekdist_inc*weekdist_woonwerk_changecat_increasedcommute  
  b_weekdist_same*weekdist_woonwerk_changecat_samecommute  
  #b_weekdist_nojob*weekdist_woonwerk_changecat_nojob  
  b_weekdist_lostjob*weekdist_woonwerk_changecat_lostjob  
  b_weekdist_gotjob*weekdist_woonwerk_changecat_gotjob  
  b_weekdist_alwayswfh*weekdist_woonwerk_changecat_alwaysworkfromhome  
  b_weekdist_wfhtocommuting*weekdist_woonwerk_changecat_workfromhometocommuting  
  b_weekdist_commutingtowfh*weekdist_woonwerk_changecat_commutingtoworkfromhome  
  b_weekdist_differingaddresses*weekdist_woonwerk_changecat_differingaddresses,
                     tau            = list(tau_nautos_change_1, tau_nautos_change_2))

It does work.

Also, if I call uspec1, I get the exact thing I want to put in there.

Why does it not work to condense it?

CodePudding user response:

This doesn't appear to have anything to do with apollo specifically. This seems to just be an issue about how R itself evaluates function calls. Note that a quoted expression is not the same as a plain expression. Consider the case of

foo <- function(a, b) {
  a b
}

x <- 5
foo(x, 2)
# [1] 10

q <- quote(x)
foo(q, 4)
# Error in a   b : non-numeric argument to binary operator

You can't just swap in a quoted expression anywhere a regular expression appears. You need to unquote the expression. One way to do that is with do.call() to build the call you want to evaulate. In this case it would look like

do.call("foo", list(q, 2))
# [1] 7

Basically you create a call to foo and build the list of parameters which would include the quoted symbol name. In your call to list, it might look something like

ol_settings = do.call("list", list(
   outcomeOrdered = quote(nautos_change),
   utility        = uspec1,
   tau            = quote(list(tau_nautos_change_1, tau_nautos_change_2))
))
  •  Tags:  
  • r
  • Related