Important: Read this before posting to this forum

  1. This forum is for questions related to the use of Apollo. We will answer some general choice modelling questions too, where appropriate, and time permitting. We cannot answer questions about how to estimate choice models with other software packages.
  2. There is a very detailed manual for Apollo available at http://www.ApolloChoiceModelling.com/manual.html. This contains detailed descriptions of the various Apollo functions, and numerous examples are available at http://www.ApolloChoiceModelling.com/examples.html. In addition, help files are available for all functions, using e.g. ?apollo_mnl
  3. Before asking a question on the forum, users are kindly requested to follow these steps:
    1. Check that the same issue has not already been addressed in the forum - there is a search tool.
    2. Ensure that the correct syntax has been used. For any function, detailed instructions are available directly in Apollo, e.g. by using ?apollo_mnl for apollo_mnl
    3. Check the frequently asked questions section on the Apollo website, which discusses some common issues/failures. Please see http://www.apollochoicemodelling.com/faq.html
    4. Make sure that R is using the latest official release of Apollo.
  4. If the above steps do not resolve the issue, then users should follow these steps when posting a question:
    1. provide full details on the issue, including the entire code and output, including any error messages
    2. posts will not immediately appear on the forum, but will be checked by a moderator first. This may take a day or two at busy times. There is no need to submit the post multiple times.

HCM model with casulity between latent factors

Ask questions about model specifications. Ideally include a mathematical explanation of your proposed model.
Post Reply
Rui_Liu
Posts: 3
Joined: 02 Jun 2022, 01:56

HCM model with casulity between latent factors

Post by Rui_Liu »

Currently, I am trying to use the 'Apollo' package to run an HCM simultaneously considering the relationship between latent variables.
I have some questions to consult about the hybrid choice model.
1. Does it is feasible to consider the relationships between different latent factors in “Apollo” package, like SEM.
2. I have tried to run the code in “Apollo” package considering the relationship between latent variables, here, I list the code of the latent model part which defines the association between latent variables.
(i.e., LV_risk and LV_control are predictors of LV_pro, except for personal socio-demographics). From the perspective of model estimation, the code works well and produces good results.
So, I would like to request your help to confirm that it is correct to define the relationships between latent variables in this way.

### Create random parameters
apollo_randCoeff=function(apollo_beta, apollo_inputs){
randcoeff = list()

randcoeff[["LV_risk"]] = gamma_gender_risk * gender + gamma_age_risk * age60 + gamma_householdsizes_risk * householdsizes + gamma_education_risk * educationlevels_12 + eta_risk
randcoeff[["LV_control"]] = gamma_gender_control * gender + gamma_age_control * age60 + gamma_householdsizes_control * householdsizes + gamma_education_control * educationlevels_12 + eta_control
randcoeff[["LV_pro"]] = gamma_gender_pro * gender + gamma_age_pro * age60 + gamma_householdsizes_pro * householdsizes + gamma_education_pro * educationlevels_12 + eta_pro
+ theta_risk * (gamma_gender_risk * gender + gamma_age_risk * age60 + gamma_householdsizes_risk * householdsizes + gamma_education_risk * educationlevels_12 + eta_risk)
+ theta_control * (gamma_gender_control * gender + gamma_age_control * age60 + gamma_householdsizes_control * householdsizes + gamma_education_control * educationlevels_12 + eta_control)

return(randcoeff)
}

Looking forward to your kindly reply.

Sincerely yours
Rui Liu
stephanehess
Site Admin
Posts: 974
Joined: 24 Apr 2020, 16:29

Re: HCM model with casulity between latent factors

Post by stephanehess »

Hi

apologies for the slow reply.

could you share the rest of the code too, please?

Thanks

Stephane
--------------------------------
Stephane Hess
www.stephanehess.me.uk
Rui_Liu
Posts: 3
Joined: 02 Jun 2022, 01:56

Re: HCM model with casulity between latent factors

Post by Rui_Liu »

Hello, Pro. Stephane.
Thanks for your reply.
I have posted the whole code, so please kindly check it.

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

### set work directory ###
setwd('C:/download/data analysis software/data analysis/R/practice/social contact/final/result/result_verify/asc_chioce_latent_no_gender_age_PMT_cost_3_new/')

### Clear memory
rm(list = ls())

### Load Apollo library
library(apollo)

### Initialise code
apollo_initialise()

### Set core controls
apollo_control = list(
modelName = "2_Hybird_model",
modelDescr = "social contact",
indivID = "id",
mixing = TRUE,
nCores = 14
)

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

database <- read.csv('C:/download/data analysis software/data analysis/R/practice/social contact/mydata_combine_1.csv',fileEncoding = 'GBK',header=TRUE)
database$choice <- database$B10r11

database <-database[complete.cases(database[1614]),]

### combining householdsizes 6+ into 6
database$householdsizes[which(database$householdsizes>=6)] <- 6

### combining both and physical contact_during
database$choice[which(database$choice==4)] <- 3

### combining both and physical contact_before
database$B10r2[which(database$B10r2==4)] <- 3

### substitute NA_before by 0
database$B10r2[is.na(database$B10r2)] <- 0

### Subtract mean of indicator variables to centre them on zero

########### Part C ##############
#### Threat appraisal ####
database$C3r1 = database$C3r1 - mean(database$C3r1)
database$C3r3 = database$C3r3 - mean(database$C3r3)
database$C3r4 = database$C3r4 - mean(database$C3r4)

#### Coping appraisal ####
database$C4r1 = database$C4r1 - mean(database$C4r1)
database$C4r4 = database$C4r4 - mean(database$C4r4)
database$C4r5 = database$C4r5 - mean(database$C4r5)

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

apollo_beta = c(
asc_phy = 0,
asc_nonphy = 0,
b_travelparty_other_phy = 0,
b_travelparty_other_nonphy = 0,
b_duration_phy = 0,
b_duration_nonphy = 0,
b_past_no_phy = 0,
b_past_nonphy_phy = 0,
b_past_phy_phy = 0,
b_past_no_nonphy = 0,
b_past_nonphy_nonphy = 0,
b_past_phy_nonphy = 0,
b_3cs2_phy = 0,
b_3cs2_nonphy = 0,
lambda_risk_phy = 0,
lambda_risk_nonphy = 0,
lambda_control_phy = 0,
lambda_control_nonphy = 0,
lambda_pro_phy = 0,
lambda_pro_nonphy = 0,
gamma_gender_risk = 0,
gamma_age_risk = 0,
gamma_education_risk = 0,
gamma_householdsizes_risk = 0,
gamma_gender_control = 0,
gamma_age_control = 0,
gamma_education_control = 0,
gamma_householdsizes_control = 0,
gamma_gender_pro = 0,
gamma_age_pro = 0,
gamma_education_pro = 0,
gamma_householdsizes_pro = 0,
zeta_risk_1 = 1,
zeta_risk_2 = 1,
zeta_risk_3 = 1,
zeta_control_1 = 1,
zeta_control_2 = 1,
zeta_control_3 = 1,
zeta_pro_1 = 1,
zeta_pro_2 = 1,
zeta_pro_3 = 1,
sigma_risk_1 = 1,
sigma_risk_2 = 1,
sigma_risk_3 = 1,
sigma_control_1 = 1,
sigma_control_2 = 1,
sigma_control_3 = 1,
theta_risk = 0,
theta_control = 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('b_past_no_phy','b_past_no_nonphy')

# ################################################################# #
#### DEFINE RANDOM COMPONENTS ####
# ################################################################# #

### Set parameters for generating draws
apollo_draws = list(
interDrawsType="halton",
interNDraws=100,
interUnifDraws=c(),
interNormDraws=c('eta_risk','eta_control','eta_pro'),

intraDrawsType='',
intraNDraws=0,
intraUnifDraws=c(),
intraNormDraws=c()
)

### Create random parameters
apollo_randCoeff=function(apollo_beta, apollo_inputs){
randcoeff = list()

randcoeff[["LV_risk"]] = gamma_gender_risk * gender + gamma_age_risk * age60 + gamma_householdsizes_risk * householdsizes + gamma_education_risk * educationlevels_12 + eta_risk
randcoeff[["LV_control"]] = gamma_gender_control * gender + gamma_age_control * age60 + gamma_householdsizes_control * householdsizes + gamma_education_control * educationlevels_12 + eta_control
randcoeff[["LV_pro"]] = gamma_gender_pro * gender + gamma_age_pro * age60 + gamma_householdsizes_pro * householdsizes + gamma_education_pro * educationlevels_12 + eta_pro + theta_risk * (gamma_gender_risk * gender + gamma_age_risk * age60 + gamma_householdsizes_risk * householdsizes + gamma_education_risk * educationlevels_12 + eta_risk) + theta_control * (gamma_gender_control * gender + gamma_age_control * age60 + gamma_householdsizes_control * householdsizes + gamma_education_control * educationlevels_12 + eta_control)

return(randcoeff)
}

# ################################################################# #
#### 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()

### Likelihood of indicators

normalDensity_settings1 = list(outcomeNormal = C3r1,
xNormal = zeta_risk_1*LV_risk,
mu = 0,
sigma = sigma_risk_1,
componentName = "indic_risk_1")
normalDensity_settings2 = list(outcomeNormal = C3r3,
xNormal = zeta_risk_2*LV_risk,
mu = 0,
sigma = sigma_risk_2,
componentName = "indic_risk_2")
normalDensity_settings3 = list(outcomeNormal = C3r4,
xNormal = zeta_risk_3*LV_risk,
mu = 0,
sigma = sigma_risk_3,
componentName = "indic_risk_3")
normalDensity_settings4 = list(outcomeNormal = C4r2,
xNormal = zeta_control_1*LV_control,
mu = 0,
sigma = sigma_control_1,
componentName = "indic_control_1")
normalDensity_settings5 = list(outcomeNormal = C4r4,
xNormal = zeta_control_2*LV_control,
mu = 0,
sigma = sigma_control_2,
componentName = "indic_control_2")
normalDensity_settings6 = list(outcomeNormal = C4r5,
xNormal = zeta_control_3*LV_control,
mu = 0,
sigma = sigma_control_3,
componentName = "indic_control_3")

V = list()
V[['no_mask']] = 0
V[['yes_mask']] = zeta_pro_1 * LV_pro
mnl_settings1 = list(
alternatives = c(no_mask=0, yes_mask=1),
avail = list(no_mask=1,yes_mask=1),
choiceVar = B13r11c1,
V = V,
componentName = "indic_pro_1")
V = list()
V[['no_disinfect']] = 0
V[['yes_disinfect']] = zeta_pro_2 * LV_pro
mnl_settings2 = list(
alternatives = c(no_disinfect=0, yes_disinfect=1),
avail = list(no_disinfect=1,yes_disinfect=1),
choiceVar = B13r11c2,
V = V,
componentName = "indic_pro_2")

V = list()
V[['no_touch']] = 0
V[['yes_touch']] = zeta_pro_3 * LV_pro
mnl_settings3 = list(
alternatives = c(no_touch=0, yes_touch=1),
avail = list(no_touch=1,yes_touch=1),
choiceVar = B13r11c4,
V = V,
componentName = "indic_pro_3")

P[["indic_risk_1"]] = apollo_normalDensity(normalDensity_settings1, functionality)
P[["indic_risk_2"]] = apollo_normalDensity(normalDensity_settings2, functionality)
P[["indic_risk_3"]] = apollo_normalDensity(normalDensity_settings3, functionality)
P[["indic_control_1"]] = apollo_normalDensity(normalDensity_settings4, functionality)
P[["indic_control_2"]] = apollo_normalDensity(normalDensity_settings5, functionality)
P[["indic_control_3"]] = apollo_normalDensity(normalDensity_settings6, functionality)
P[["indic_pro_1"]] = apollo_mnl(mnl_settings1, functionality)
P[["indic_pro_2"]] = apollo_mnl(mnl_settings2, functionality)
P[["indic_pro_3"]] = apollo_mnl(mnl_settings3, functionality)

### Likelihood of choices
### List of utilities: these must use the same names as in mnl_settings, order is irrelevant
V = list()
V[['nocon']] = 0
V[['phy']] = ( asc_phy
+ b_travelparty_other_phy * cmtravelparty_amusementparks_during
+ b_duration_phy * B7r11
+ b_past_no_phy * (B10r2==1)
+ b_past_nonphy_phy * (B10r2==2)
+ b_past_phy_phy * (B10r2==3)
+ b_3cs2_phy * B12r11c2
+ lambda_risk_phy * LV_risk
+ lambda_control_phy * LV_control
+ lambda_pro_phy * LV_pro)
V[['nonphy']] = ( asc_nonphy
+ b_travelparty_other_nonphy * cmtravelparty_amusementparks_during
+ b_duration_nonphy * B7r11
+ b_past_no_nonphy * (B10r2==1)
+ b_past_nonphy_nonphy * (B10r2==2)
+ b_past_phy_nonphy * (B10r2==3)
+ b_3cs2_nonphy * B12r11c2
+ lambda_risk_nonphy * LV_risk
+ lambda_control_nonphy * LV_control
+ lambda_pro_nonphy * LV_pro)

### Define settings for MNL model component
mnl_settings = list(
alternatives = c(nocon=1, nonphy=2, phy=3),
avail = list(nocon=1, nonphy=1, phy=1),
choiceVar = choice,
V = V
)

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

### Likelihood of the whole model
P = apollo_combineModels(P, apollo_inputs, functionality)

### Average across inter-individual draws
P = apollo_avgInterDraws(P, apollo_inputs, functionality)

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

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

### Optional: calculate LL before model estimation
apollo_llCalc(apollo_beta, apollo_probabilities, apollo_inputs)

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

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

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

apollo_modelOutput(model, modelOutput_settings = list(printPVal=2))

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

apollo_saveOutput(model, saveOutput_settings = list(printPVal=2))


Looking forward to your reply.
Best regards
Rui
dpalma
Posts: 190
Joined: 24 Apr 2020, 17:54

Re: HCM model with casulity between latent factors

Post by dpalma »

Hi Rui,

You code looks correct.

A shorter way to write the interrelation between latent variables is as follows. Apollo should be smart enough to replace the latent variables by their definitions by itself.

Code: Select all

### Create random parameters
apollo_randCoeff=function(apollo_beta, apollo_inputs){
  randcoeff = list()
  
  randcoeff[["LV_risk"]]    = gamma_gender_risk * gender + gamma_age_risk * age60 + gamma_householdsizes_risk * householdsizes + gamma_education_risk * educationlevels_12 + eta_risk
  randcoeff[["LV_control"]] = gamma_gender_control * gender + gamma_age_control * age60 + gamma_householdsizes_control * householdsizes + gamma_education_control * educationlevels_12 + eta_control
  randcoeff[["LV_pro"]]     = gamma_gender_pro * gender + gamma_age_pro * age60 + gamma_householdsizes_pro * householdsizes + gamma_education_pro * educationlevels_12 + eta_pro + theta_risk * randcoeff[["LV_risk"]] + theta_control * randcoeff[["LV_control"]]
  
  return(randcoeff)
}
Best wishes
David
Rui_Liu
Posts: 3
Joined: 02 Jun 2022, 01:56

Re: HCM model with casulity between latent factors

Post by Rui_Liu »

Hi David,

Thanks for your kind reply.
It helps a lot. Then I can use the code in the data analysis part of my research.

Best wishes
Rui Liu
ha.ortiz10
Posts: 4
Joined: 02 Jun 2020, 23:17

Re: HCM model with casulity between latent factors

Post by ha.ortiz10 »

Hi all

I see that risk, control, and pro, all are parameters in the Utility function, i.e.:

... + lambda_risk_nonphy * LV_risk + lambda_control_nonphy * LV_control + lambda_pro_nonphy * LV_pro)

But, then, you would be including direct and indirect effects of risk and control over the utility... How would you proceed if you want to test only indirect effects? That is... if you wanted to test only the effect of PRO on the utility function (considering that pro is explained by risk and control) would you just not include this part "+ lambda_risk_nonphy * LV_risk + lambda_control_nonphy * LV_control" on the utility function? Does it make sense...

Excuse me if this is a super dumb question.
dpalma
Posts: 190
Joined: 24 Apr 2020, 17:54

Re: HCM model with casulity between latent factors

Post by dpalma »

Hi,

I am not an expert in Structural Equation Modelling, but my understanding is that a given factor can have both direct and indirect effects in an outcome (the choice, in this case), without causing issue. In this case factors "risk" and "control" both influence "pro", and all three influence the utility of the choice. So the the structure is:

Code: Select all

risk ----> pro <--- control
 \         |          /
  \        v         /
   ---> U_choice <---
  • The indirect effect of risk on the choice utility would be theta_risk * lambda_pro
  • The direct effect of risk on the choice utility would be lambda_risk
  • The indirect effect of control on the choice utility would be theta_control * lambda_pro
  • The direct effect of control on the choice utility would be lambda_control
  • The direct effect of pro on the choice utility would be lambda_pro

Even if you are interested only in the indirect effect of risk and control, it might be useful to test the full model, and only discard the direct effects of risk and control if lambda_risk and lambda_control are not significant. Only if you have strong theoretical reasons to assume those should be zero, then you can go straight for a model where you fix lambda_risk and lambda_control to zero.

Cheers
David
Post Reply