Page 1 of 1

Apollo estimation issues for putting estimation procedure in a function

Posted: 05 Dec 2024, 12:34
by chenchaodut
Hello,

I have encountered one issue in using Apollo to estimate choice models and I am writing to you for your kindly helps.

Here is the problem:

I want to put apollo estimation procedure in one function, and using another main function to call that function and return the key parameters i need to continue the main function. Attached is the example i used to show the issue. Could you kindly help me solve it? Or is it impossible to put estimation procedure in subfunctions?

Code:

# ################################################################# #
#### LOAD LIBRARY AND DEFINE CORE SETTINGS ####
# ################################################################# #


rm(list = ls())
library(apollo)

#Put the Apollo in one function
Fitness <- function(){
### Initialise code
apollo_initialise()

### Set core controls
apollo_control = list(
modelName = "MNL_SP",
modelDescr = "Simple MNL model on mode choice SP data",
indivID = "ID",
outputDirectory = "output"
)

# ################################################################# #
#### LOAD DATA AND APPLY ANY TRANSFORMATIONS ####
# ################################################################# #

### Loading data from package
### if data is to be loaded from a file (e.g. called data.csv),
### the code would be: database = read.csv("data.csv",header=TRUE)
database = apollo_modeChoiceData
### for data dictionary, use ?apollo_modeChoiceData

### Use only SP data
database = subset(database,database$SP==1)

# ################################################################# #
#### DEFINE MODEL PARAMETERS ####
# ################################################################# #

### Vector of parameters, including any that are kept fixed in estimation
apollo_beta=c(asc_car = 0,
asc_bus = 0,
asc_air = 0,
asc_rail = 0,
b_tt_car = 0,
b_tt_bus = 0,
b_tt_air = 0,
b_tt_rail = 0,
b_access = 0,
b_cost = 0,
b_no_frills = 0,
b_wifi = 0,
b_food = 0)

### Vector with names (in quotes) of parameters to be kept fixed at their starting value in apollo_beta, use apollo_beta_fixed = c() if none
apollo_fixed = c("asc_car","b_no_frills")

# ################################################################# #
#### GROUP AND VALIDATE INPUTS ####
# ################################################################# #

apollo_inputs = apollo_validateInputs()

# ################################################################# #
#### DEFINE MODEL AND LIKELIHOOD FUNCTION ####
# ################################################################# #

apollo_probabilities=function(apollo_beta, apollo_inputs, functionality="estimate"){

### Attach inputs and detach after function exit
apollo_attach(apollo_beta, apollo_inputs)
on.exit(apollo_detach(apollo_beta, apollo_inputs))

### Create list of probabilities P
P = list()

### List of utilities: these must use the same names as in mnl_settings, order is irrelevant
V = list()
V[["car"]] = asc_car + b_tt_car * time_car + b_cost * cost_car
V[["bus"]] = asc_bus + b_tt_bus * time_bus + b_access * access_bus + b_cost * cost_bus
V[["air"]] = asc_air + b_tt_air * time_air + b_access * access_air + b_cost * cost_air + b_no_frills * ( service_air == 1 ) + b_wifi * ( service_air == 2 ) + b_food * ( service_air == 3 )
V[["rail"]] = asc_rail + b_tt_rail * time_rail + b_access * access_rail + b_cost * cost_rail + b_no_frills * ( service_rail == 1 ) + b_wifi * ( service_rail == 2 ) + b_food * ( service_rail == 3 )

### Define settings for MNL model component
mnl_settings = list(
alternatives = c(car=1, bus=2, air=3, rail=4),
avail = list(car=av_car, bus=av_bus, air=av_air, rail=av_rail),
choiceVar = choice,
utilities = V
)

### Compute probabilities using MNL model
P[["model"]] = apollo_mnl(mnl_settings, functionality)

### Take product across observation for same individual
P = apollo_panelProd(P, apollo_inputs, functionality)

### Prepare and return outputs of function
P = apollo_prepareProb(P, apollo_inputs, functionality)
return(P)
}

# ################################################################# #
#### MODEL ESTIMATION ####
# ################################################################# #

model = apollo_estimate(apollo_beta, apollo_fixed, apollo_probabilities, apollo_inputs)

# ################################################################# #
#### MODEL OUTPUTS ####
# ################################################################# #

# ----------------------------------------------------------------- #
#---- FORMATTED OUTPUT (TO SCREEN) ----
# ----------------------------------------------------------------- #

apollo_modelOutput(model)

# ----------------------------------------------------------------- #
#---- FORMATTED OUTPUT (TO FILE, using model name) ----
# ----------------------------------------------------------------- #

apollo_saveOutput(model)
fitnessValue = model$maximum
return(fitnessValue)
}

#Use outside main function to all Apollo and return the value i need

Value=Fitness()

print(Value)


Thank you! Looking forwards to your replys.

Best regards,

Chao

Re: Apollo estimation issues for putting estimation procedure in a function

Posted: 06 Dec 2024, 17:05
by stephanehess
Hi

this does not work as your function does not have access to the inputs that are needed by the functions inside. Can you be more specific about why you would want to do this as it's simple to obtain the outputs you need from the model object.

Stephane

Re: Apollo estimation issues for putting estimation procedure in a function

Posted: 10 Dec 2024, 05:06
by chenchaodut
Hi, Stephane,

Thanks for your reply. The reason I want to put the estimation procedure into a function in R code is that I want to iteratively re-estimate the model by changing only the input data. To be more specific, in each iteration, I will change the values of two columns, i.e., change the input data, and then estimate the model to output the loglikelihood value. Are there any other methods to implement the procedure? Thank you!

Looking forward to your reply!

Best regards,
Chao

Re: Apollo estimation issues for putting estimation procedure in a function

Posted: 11 Dec 2024, 10:07
by stephanehess
Okay, the thing to do in that case is to have a list of databases, and write a loop after the model defintiion, so something like this:

Code: Select all

database_list = list()
database[[1]] = ..
database[[2]] = ..
...

apollo_probabilities=function(apollo_beta, apollo_inputs, functionality="estimate"){

...

return(P)
}

models=list()
for(m) in 1:length(database_list()){
database=database_list[[m]]
apollo_inputs = apollo_validateInputs()
models[[m]]] = apollo_estimate(apollo_beta, apollo_fixed, apollo_probabilities, apollo_inputs)
}