Thank you for your support in organizing this forum.
I have conducted a choice experiment-based survey using a dual response design. After referring the Apollo manual, I thought I should use a joint estimation. I have a couple of questions and would greatly appreciate your guidance.
For context, my experiment focuses on zero-emission truck choices, including Battery Electric Trucks (BETs) and Hydrogen Fuel Cell Electric Trucks (HFCETs). The dual response format that I used consists of a forced choice followed by an unforced choice. The survey respondents are segmented into two groups: fleet operators who exclusively use diesel trucks ("diesel fleets") and those who also operate natural gas trucks ("NG fleets"). For diesel fleets, the reference alternative is a diesel truck, while for NG fleets, the reference alternatives include both diesel and natural gas trucks.
In each choice task, I asked two questions: the first requires choosing between BET and HFCET, and the second asks if they would still choose the option selected in the first question if the reference alternative(s) were available. Thus, in the second question, diesel fleets choose between 1) a diesel truck and 2) the BET/HFCET selected previously, while NG fleets choose from 1) a diesel truck, 2) a natural gas truck, and 3) the BET/HFCET selected previously.
I have a total of 54 respondents for this choice experiment section, with 12 from NG fleets and 42 from diesel fleets. Each respondent received 6 choice tasks, resulting in a total of 324 choice tasks in my survey data. Each task consists of a forced choice followed by an unforced choice.
Regarding the joint estimation, which of the following approaches would you recommend? I have also included R scripts below.
- CASE 1: Joint estimation of two datasets – forced choice data (324 observations) and unforced choice data (324 observations)
- CASE 2: Joint estimation of three datasets – forced choice data (324 observations), unforced choice data for diesel fleets (252 observations), and unforced choice data for NG fleets (72 observations)
Code: Select all
###############################################
### LOAD LIBRARY AND DEFINE CORE SETTINGS ###
###############################################
rm(list=ls())
install.packages("apollo")
library(apollo)
#Initialize code
apollo_initialise()
#Set core controls
apollo_control = list(
modelName = "Main_JOINT-INTRTN1-TWO-DATASETS",
modelDescr = "Forced-unforced data joint model",
indivID = "ID",
outputDirectory = "output"
)
###############################################
### LOAD DATA AND APPLY ANY TRANSFORMATIONS ###
###############################################
#consider both forced and unforced choice data
database = read.csv("E:/Survey/Estimation/main_survey.csv", header=TRUE)
###############################################
### DEFINE MODEL PARAMETERS ###
###############################################
#Vector of parameters
apollo_beta = c(asc_bev = 0, asc_hfcev = 0, asc_ngv = 0, asc_dsl = 0,
b_pcost = 0, b_ocost = 0, b_range = 0, b_offsite = 0, b_onsite_bev = 0, b_onsite_hfcev = 0,
asc_bev_shift_adopter = 0, asc_hfcev_shift_adopter = 0,
asc_ngv_shift_small_org = 0,
b_ocost_shift_small_fleet = 0,
mu_unforced = 1)
# Vector with names (in quotes) of parameters to be kept fixed at their starting value in apollo_beta, use
apollo_fixed = c("asc_dsl")
###############################################
### 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()
### Create coefficients using interactions with fleet characteristics
asc_bev_value = asc_bev + asc_bev_shift_adopter * bev_adopter
asc_hfcev_value = asc_hfcev + asc_hfcev_shift_adopter * hfcev_adopter
asc_ngv_value = asc_ngv + asc_ngv_shift_small_org * small_org3
b_pcost_value = b_pcost / relative_annual_revenue
b_ocost_value = b_ocost + b_ocost_shift_small_fleet * small_fleet3
b_offsite_value = b_offsite * small_fleet3
### List of utilities: these must use the same names as in mnl_settings, order is irrelevant
V = list()
V[["bev"]] = asc_bev_value + b_pcost_value * bev_pcost + b_ocost_value * bev_ocost + b_range * bev_range + b_offsite_value * bev_offsite_binary + b_onsite_bev * bev_onsite
V[["hfcev"]] = asc_hfcev_value + b_pcost_value * hfcev_pcost + b_ocost_value * hfcev_ocost + b_range * hfcev_range + b_offsite_value * hfcev_offsite_binary + b_onsite_hfcev * hfcev_onsite
V[["dsl"]] = asc_dsl + b_pcost_value * dsl_pcost + b_ocost_value * dsl_ocost + b_range * dsl_range + b_offsite_value * dsl_offsite_binary
V[["ngv"]] = asc_ngv_value + b_pcost_value * ngv_pcost + b_ocost_value * ngv_ocost + b_range * ngv_range + b_offsite_value * ngv_offsite_binary
### Compute probabilities for "forced" choice using MNL model
mnl_settings_forced = list(
alternatives = c(bev=1, hfcev=2),
avail = list(bev=alt_electric, hfcev=alt_hydrogen),
choiceVar = choice,
utilities = list(bev = V[["bev"]],
hfcev = V[["hfcev"]]),
rows = (forced==1)
)
P[["choice_forced"]] = apollo_mnl(mnl_settings_forced, functionality)
### Compute probabilities for "unforced" choice using MNL model
mnl_settings_unforced = list(
alternatives = c(bev=1, hfcev=2, dsl=3, ngv=4),
avail = list(bev=alt_electric, hfcev=alt_hydrogen, dsl=alt_diesel, ngv=alt_cng),
choiceVar = choice,
utilities = list(bev = mu_unforced*V[["bev"]],
hfcev = mu_unforced*V[["hfcev"]],
dsl = mu_unforced*V[["dsl"]],
ngv = mu_unforced*V[["ngv"]]),
rows = (forced==2)
)
P[["choice_unforced"]] = apollo_mnl(mnl_settings_unforced, functionality)
### Combined model
P = apollo_combineModels(P, apollo_inputs, 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)
Code: Select all
###############################################
### LOAD LIBRARY AND DEFINE CORE SETTINGS ###
###############################################
rm(list=ls())
install.packages("apollo")
library(apollo)
#Initialize code
apollo_initialise()
#Set core controls
apollo_control = list(
modelName = "Main_JOINT-INTRTN2-THREE-DATASETS",
modelDescr = "Joint estimation of forced, unforced diesel, and unforced NG datasets",
indivID = "ID",
outputDirectory = "output"
)
###############################################
### LOAD DATA AND APPLY ANY TRANSFORMATIONS ###
###############################################
#consider both forced and unforced choice data
database = read.csv("E:/Survey/Estimation/main_survey.csv", header=TRUE)
###############################################
### DEFINE MODEL PARAMETERS ###
###############################################
#Vector of parameters
apollo_beta = c(asc_bev = 0, asc_hfcev = 0, asc_ngv = 0, asc_dsl = 0,
b_pcost = 0, b_ocost = 0, b_range = 0, b_offsite = 0, b_onsite_bev = 0, b_onsite_hfcev = 0,
asc_bev_shift_adopter = 0, asc_hfcev_shift_adopter = 0,
asc_ngv_shift_small_org = 0,
b_ocost_shift_small_fleet = 0,
mu_unforced_dsl = 1, mu_unforced_ng = 1)
# Vector with names (in quotes) of parameters to be kept fixed at their starting value in apollo_beta, use
apollo_fixed = c("asc_dsl")
###############################################
### 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()
### Create coefficients using interactions with fleet characteristics
asc_bev_value = asc_bev + asc_bev_shift_adopter * bev_adopter
asc_hfcev_value = asc_hfcev + asc_hfcev_shift_adopter * hfcev_adopter
asc_ngv_value = asc_ngv + asc_ngv_shift_small_org * small_org3
b_pcost_value = b_pcost / relative_annual_revenue
b_ocost_value = b_ocost + b_ocost_shift_small_fleet * small_fleet3
b_offsite_value = b_offsite * small_fleet3
### List of utilities: these must use the same names as in mnl_settings, order is irrelevant
V = list()
V[["bev"]] = asc_bev_value + b_pcost_value * bev_pcost + b_ocost_value * bev_ocost + b_range * bev_range + b_offsite_value * bev_offsite_binary + b_onsite_bev * bev_onsite
V[["hfcev"]] = asc_hfcev_value + b_pcost_value * hfcev_pcost + b_ocost_value * hfcev_ocost + b_range * hfcev_range + b_offsite_value * hfcev_offsite_binary + b_onsite_hfcev * hfcev_onsite
V[["dsl"]] = asc_dsl + b_pcost_value * dsl_pcost + b_ocost_value * dsl_ocost + b_range * dsl_range + b_offsite_value * dsl_offsite_binary
V[["ngv"]] = asc_ngv_value + b_pcost_value * ngv_pcost + b_ocost_value * ngv_ocost + b_range * ngv_range + b_offsite_value * ngv_offsite_binary
### Compute probabilities for "forced" choice using MNL model
mnl_settings_forced = list(
alternatives = c(bev=1, hfcev=2),
avail = list(bev=alt_electric, hfcev=alt_hydrogen),
choiceVar = choice,
utilities = list(bev = V[["bev"]],
hfcev = V[["hfcev"]]),
rows = (choice_set==2)
)
P[["choice_forced"]] = apollo_mnl(mnl_settings_forced, functionality)
### Compute probabilities for "unforced" choice for "diesel fleets" using MNL model
mnl_settings_unforced_dsl = list(
alternatives = c(bev=1, hfcev=2, dsl=3),
avail = list(bev=alt_electric, hfcev=alt_hydrogen, dsl=alt_diesel),
choiceVar = choice,
utilities = list(bev = mu_unforced_dsl*V[["bev"]],
hfcev = mu_unforced_dsl*V[["hfcev"]],
dsl = mu_unforced_dsl*V[["dsl"]]),
rows = (choice_set==3)
)
P[["choice_unforced_dsl"]] = apollo_mnl(mnl_settings_unforced_dsl, functionality)
### Compute probabilities for "unforced" choice for "NG fleets" using MNL model
mnl_settings_unforced_ng = list(
alternatives = c(bev=1, hfcev=2, dsl=3, ngv=4),
avail = list(bev=alt_electric, hfcev=alt_hydrogen, dsl=alt_diesel, ngv=alt_cng),
choiceVar = choice,
utilities = list(bev = mu_unforced_ng*V[["bev"]],
hfcev = mu_unforced_ng*V[["hfcev"]],
dsl = mu_unforced_ng*V[["dsl"]],
ngv = mu_unforced_ng*V[["ngv"]]),
rows = (choice_set==4)
)
P[["choice_unforced_ng"]] = apollo_mnl(mnl_settings_unforced_ng, functionality)
### Combined model
P = apollo_combineModels(P, apollo_inputs, 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)
Thank you very much!
Best regards,
YB