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. We check the forum at least twice a week. It may thus take a couple of days for your post to appear and before we reply. There is no need to submit the post multiple times.

MMNL on SP/RP data - multiple cores error

Ask questions about errors you encouunter. Please make sure to include full details about your model specifications, and ideally your model file.
Post Reply
Mat2089119
Posts: 6
Joined: 06 Mar 2024, 10:00

MMNL on SP/RP data - multiple cores error

Post by Mat2089119 »

Hi,

I would like to estimate a mixed-logit from SP and RP data. The data comes from different RP/SP individuals, the SP data has 4 choice tasks for each individual, the RP data is just a single observation. I do not have the socio-demographics for the RP observations so they should only be used to scale the model.

The model is estimating on a single core, but this takes obviously very long with the complexity. When specifying multiple cores, I am encounting issues. Exactly the same has happened with a standard MNL, but there the computation speed was not such an issue.

First approach, error: "checkForRemoteErrors(lapply(cl, recvResult)) :
10 nodes produced errors; first error: SPECIFICATION ISSUE - You attempted to call the function apollo_panelProd at a stage where the probabilities are already at the individual level!"

Code: Select all

##############################################################
#### 1.  LOAD LIBRARY & CORE SETTINGS                      ####
##############################################################
library(apollo)
apollo_initialise()

apollo_control = list(
  modelName       = "MMNL_RP_SP",
  modelDescr      = "RP–SP mixed logit",
  indivID         = "RID",
  nCores          = 4,            # adjust to your machine
  outputDirectory = "output"
)

##############################################################
#### 2.  LOAD DATA                                         ####
##############################################################
database <- data  

##############################################################
#### 3.  DEFINE FIXED & MEAN/S.D. PARAMETERS               ####
##############################################################
apollo_beta = c(

  ## ─── Random coefficients: means & st. devs ─────────────────
  mu_asc_opt1    =  0,  sigma_asc_opt1    =  1,
  mu_asc_opt2    =  0,  sigma_asc_opt2    =  1,
  mu_asc_opt3    =  0,  sigma_asc_opt3    =  1,
  mu_log_b_price = -3, sigma_log_b_price = .5,  # log-normal, keeps sign < 0

  ## ─── Fixed taste parameters ────────────────────────────────
  b_opt3                 =  0,

  ## SP interactions: gender
  b_gender_opt1          =  0,  b_gender_opt2       = 0,  b_gender_opt3      = 0,
  ## SP interactions: city centre
  b_cityCenter_opt1      =  0,  b_cityCenter_opt2   = 0,  b_cityCenter_opt3  = 0,
  ## SP interactions: age categories
  b_age18_29_opt1        =  0,  b_age18_29_opt2     = 0,  b_age18_29_opt3    = 0,
  b_age30_44_opt1        =  0,  b_age30_44_opt2     = 0,  b_age30_44_opt3    = 0,
  b_age45_64_opt1        =  0,  b_age45_64_opt2     = 0,  b_age45_64_opt3    = 0,
  ## SP interactions: category segments 1–5
  b_cat1_opt1 = 0, b_cat1_opt2 = 0, b_cat1_opt3 = 0,
  b_cat2_opt1 = 0, b_cat2_opt2 = 0, b_cat2_opt3 = 0,
  b_cat3_opt1 = 0, b_cat3_opt2 = 0, b_cat3_opt3 = 0,
  b_cat4_opt1 = 0, b_cat4_opt2 = 0, b_cat4_opt3 = 0,
  b_cat5_opt1 = 0, b_cat5_opt2 = 0, b_cat5_opt3 = 0,
  ## SP interactions: PT subscription dummy
  b_ptsub_opt1 = 0, b_ptsub_opt2 = 0, b_ptsub_opt3 = 0,

  ## Scale parameters
  mu_RP  = 1,   # fixed
  mu_SP  = 1    # to be estimated
)

apollo_fixed = c("mu_RP")         # keep RP scale normalised

##############################################################
#### 4.  RANDOM COEFFICIENTS & DRAWS                        ####
##############################################################
apollo_draws = list(
  interDrawsType = "halton",
  interNDraws    = 500,
  interNormDraws = c("d_asc_opt1","d_asc_opt2","d_asc_opt3","d_b_price"),
  intraDrawsType = "none",  intraNDraws = 0
)

apollo_randCoeff = function(apollo_beta, apollo_inputs){
  rc = list()

  ## Normally-distributed ASCs
  rc[["asc_opt1"]] =  mu_asc_opt1 + sigma_asc_opt1 * d_asc_opt1
  rc[["asc_opt2"]] =  mu_asc_opt2 + sigma_asc_opt2 * d_asc_opt2
  rc[["asc_opt3"]] =  mu_asc_opt3 + sigma_asc_opt3 * d_asc_opt3

  ## Log-normal (negative) price coefficient
  rc[["b_price"]]  = -exp(mu_log_b_price + sigma_log_b_price * d_b_price)

  return(rc)
}

##############################################################
#### 5.  GROUP & VALIDATE INPUTS                            ####
##############################################################
apollo_inputs = apollo_validateInputs()

##############################################################
#### 6.  LIKELIHOOD FUNCTION                                ####
##############################################################
apollo_probabilities = function(apollo_beta, apollo_inputs, functionality="estimate"){  

  apollo_attach(apollo_beta, apollo_inputs)
  on.exit(apollo_detach(apollo_beta, apollo_inputs))

  P = list()                                          # container

  ## ── (1) SP-only ASC terms with interactions ─────────────────
  asc_opt1_val = asc_opt1
  asc_opt2_val = asc_opt2
  asc_opt3_val = asc_opt3

  if(functionality=="estimate"){                      # only needed when estimating
    asc_opt1_val = asc_opt1_val +
      ifelse(rp==0, b_gender_opt1    * gender,        0) +
      ifelse(rp==0, b_cityCenter_opt1* city_center,   0) +
      ifelse(rp==0, b_age18_29_opt1  * age_cat_18_29, 0) +
      ifelse(rp==0, b_age30_44_opt1  * age_cat_30_44, 0) +
      ifelse(rp==0, b_age45_64_opt1  * age_cat_45_64, 0) +
      ifelse(rp==0, b_cat1_opt1      * category_1,    0) +
      ifelse(rp==0, b_cat2_opt1      * category_2,    0) +
      ifelse(rp==0, b_cat3_opt1      * category_3,    0) +
      ifelse(rp==0, b_cat4_opt1      * category_4,    0) +
      ifelse(rp==0, b_cat5_opt1      * category_5,    0) +
      ifelse(rp==0, b_ptsub_opt1     * ptsub,         0)

    asc_opt2_val = asc_opt2_val +
      ifelse(rp==0, b_gender_opt2    * gender,        0) +
      ifelse(rp==0, b_cityCenter_opt2* city_center,   0) +
      ifelse(rp==0, b_age18_29_opt2  * age_cat_18_29, 0) +
      ifelse(rp==0, b_age30_44_opt2  * age_cat_30_44, 0) +
      ifelse(rp==0, b_age45_64_opt2  * age_cat_45_64, 0) +
      ifelse(rp==0, b_cat1_opt2      * category_1,    0) +
      ifelse(rp==0, b_cat2_opt2      * category_2,    0) +
      ifelse(rp==0, b_cat3_opt2      * category_3,    0) +
      ifelse(rp==0, b_cat4_opt2      * category_4,    0) +
      ifelse(rp==0, b_cat5_opt2      * category_5,    0) +
      ifelse(rp==0, b_ptsub_opt2     * ptsub,         0)

    asc_opt3_val = asc_opt3_val +
      ifelse(rp==0, b_gender_opt3    * gender,        0) +
      ifelse(rp==0, b_cityCenter_opt3* city_center,   0) +
      ifelse(rp==0, b_age18_29_opt3  * age_cat_18_29, 0) +
      ifelse(rp==0, b_age30_44_opt3  * age_cat_30_44, 0) +
      ifelse(rp==0, b_age45_64_opt3  * age_cat_45_64, 0) +
      ifelse(rp==0, b_cat1_opt3      * category_1,    0) +
      ifelse(rp==0, b_cat2_opt3      * category_2,    0) +
      ifelse(rp==0, b_cat3_opt3      * category_3,    0) +
      ifelse(rp==0, b_cat4_opt3      * category_4,    0) +
      ifelse(rp==0, b_cat5_opt3      * category_5,    0) +
      ifelse(rp==0, b_ptsub_opt3     * ptsub,         0)
  }

  ## ── (2) Utilities ───────────────────────────────────────────
  V = list(
    opt1   = asc_opt1_val + b_price * price_opt1,
    opt2   = asc_opt2_val + b_price * price_opt2,
    opt3   = asc_opt3_val + b_price * price_opt3 + b_opt3 * opt3,
    opt4   = 0
  )

  ## ── (3) RP model block ──────────────────────────────────────
  mnl_RP = list(
    alternatives = c(opt1=1, opt2=2, opt3=3, opt4=4),
    avail        = list(opt1=avail_opt1, opt2=avail_opt2, opt3=avail_opt3, opt4=1),
    choiceVar    = pref1,
    utilities    = lapply(V, function(x) mu_RP * x),
    rows         = (rp==1)
  )
  P[["RP"]] = apollo_mnl(mnl_RP, functionality)

  ## ── (4) SP model block ──────────────────────────────────────
  mnl_SP = list(
    alternatives = c(opt1=1, opt2=2, opt3=3, opt4=4),
    avail        = list(opt1=avail_opt1, opt2=avail_opt2, opt3=avail_opt3, opt4=1),
    choiceVar    = pref1,
    utilities    = lapply(V, function(x) mu_SP * x),
    rows         = (rp==0)
  )
  P[["SP"]] = apollo_mnl(mnl_SP, functionality)

  ## ── (5) Combine, panel product, average draws, return ───────
  P = apollo_combineModels(P, apollo_inputs, functionality)
  P = apollo_panelProd(       P, apollo_inputs, functionality)
  P = apollo_avgInterDraws(   P, apollo_inputs, functionality)
  P = apollo_prepareProb(     P, apollo_inputs, functionality)
  return(P)
}

##############################################################
#### 7.  ESTIMATE                                           ####
##############################################################
model = apollo_estimate(
  apollo_beta, apollo_fixed,
  apollo_probabilities, apollo_inputs
)

##############################################################
#### 8.  OUTPUT                                             ####
##############################################################
apollo_modelOutput(model)
apollo_saveOutput(model)
With the help of ChatGPT I tried a different solution, but now the error becomes: "apollo_avgInterDraws(P, apollo_inputs, functionality) :
SPECIFICATION ISSUE - Observations from the same individual must be combined (i.e. multiplied) before averaging over inter-individual draws."

Code: Select all

##############################################################
#### 1. LIBRARIES & CORE CONTROLS                          ####
##############################################################
library(apollo)
apollo_initialise()

apollo_control = list(
  modelName       = "RP–SP mixed logit",
  modelDescr      = "RP–SP mixed logit",
  indivID         = "RID",
  nCores          = 4,
  outputDirectory = "output"
)

##############################################################
#### 2. LOAD DATA                                          ####
##############################################################
database <- data

##############################################################
#### 3. STARTING VALUES                                    ####
##############################################################
apollo_beta = c(
  ## random-coeff means & s.d.'s
  mu_asc_opt1    =  0, sigma_asc_opt1    = 1,
  mu_asc_opt2    =  0, sigma_asc_opt2    = 1,
  mu_asc_opt3    =  0, sigma_asc_opt3    = 1,
  mu_log_b_price = -3, sigma_log_b_price = .5,
  ## fixed taste parameters
  b_opt3             = 0,
  b_gender_opt1      = 0, b_gender_opt2     = 0, b_gender_opt3     = 0,
  b_cityCenter_opt1  = 0, b_cityCenter_opt2 = 0, b_cityCenter_opt3 = 0,
  b_age18_29_opt1    = 0, b_age18_29_opt2   = 0, b_age18_29_opt3   = 0,
  b_age30_44_opt1    = 0, b_age30_44_opt2   = 0, b_age30_44_opt3   = 0,
  b_age45_64_opt1    = 0, b_age45_64_opt2   = 0, b_age45_64_opt3   = 0,
  b_cat1_opt1        = 0, b_cat1_opt2       = 0, b_cat1_opt3       = 0,
  b_cat2_opt1        = 0, b_cat2_opt2       = 0, b_cat2_opt3       = 0,
  b_cat3_opt1        = 0, b_cat3_opt2       = 0, b_cat3_opt3       = 0,
  b_cat4_opt1        = 0, b_cat4_opt2       = 0, b_cat4_opt3       = 0,
  b_cat5_opt1        = 0, b_cat5_opt2       = 0, b_cat5_opt3       = 0,
  b_ptsub_opt1       = 0, b_ptsub_opt2      = 0, b_ptsub_opt3      = 0,
  ## scales
  mu_RP             = 1,
  mu_SP             = 1
)
apollo_fixed = c("mu_RP")     # keep RP scale normalised

##############################################################
#### 4. DRAWS & RANDOM COEFFICIENTS                       ####
##############################################################
apollo_draws = list(
  interDrawsType = "halton",
  interNDraws    = 500,
  interNormDraws = c("d_asc_opt1","d_asc_opt2","d_asc_opt3","d_b_price"),
  intraDrawsType = "none",
  intraNDraws    = 0
)

apollo_randCoeff = function(apollo_beta, apollo_inputs){
  rc = list()
  rc[["asc_opt1"]] = mu_asc_opt1 + sigma_asc_opt1 * d_asc_opt1
  rc[["asc_opt2"]] = mu_asc_opt2 + sigma_asc_opt2 * d_asc_opt2
  rc[["asc_opt3"]] = mu_asc_opt3 + sigma_asc_opt3 * d_asc_opt3
  rc[["b_price"]] = -exp(mu_log_b_price + sigma_log_b_price * d_b_price)  # log-normal <0
  return(rc)
}

##############################################################
#### 5. VALIDATE INPUTS                                   ####
##############################################################
apollo_inputs = apollo_validateInputs()

##############################################################
#### 6. LIKELIHOOD                                        ####
##############################################################
apollo_probabilities = function(apollo_beta, apollo_inputs,
                                functionality = "estimate"){  

  apollo_attach(apollo_beta, apollo_inputs)
  on.exit(apollo_detach(apollo_beta, apollo_inputs))

  P = list()

  ## --- 6.1 SP-only ASC adjustments ---------------------------
  asc_opt1_val = asc_opt1
  asc_opt2_val = asc_opt2
  asc_opt3_val = asc_opt3
  if(functionality == "estimate"){  
    asc_opt1_val = asc_opt1_val +
      ifelse(rp==0, b_gender_opt1    * gender,      0) +
      ifelse(rp==0, b_cityCenter_opt1* city_center, 0) +
      ifelse(rp==0, b_age18_29_opt1  * age_cat_18_29,0) +
      ifelse(rp==0, b_age30_44_opt1  * age_cat_30_44,0) +
      ifelse(rp==0, b_age45_64_opt1  * age_cat_45_64,0) +
      ifelse(rp==0, b_cat1_opt1      * category_1,  0) +
      ifelse(rp==0, b_cat2_opt1      * category_2,  0) +
      ifelse(rp==0, b_cat3_opt1      * category_3,  0) +
      ifelse(rp==0, b_cat4_opt1      * category_4,  0) +
      ifelse(rp==0, b_cat5_opt1      * category_5,  0) +
      ifelse(rp==0, b_ptsub_opt1     * ptsub,       0)
    asc_opt2_val = asc_opt2_val +
      ifelse(rp==0, b_gender_opt2    * gender,      0) +
      ifelse(rp==0, b_cityCenter_opt2* city_center, 0) +
      ifelse(rp==0, b_age18_29_opt2  * age_cat_18_29,0) +
      ifelse(rp==0, b_age30_44_opt2  * age_cat_30_44,0) +
      ifelse(rp==0, b_age45_64_opt2  * age_cat_45_64,0) +
      ifelse(rp==0, b_cat1_opt2      * category_1,  0) +
      ifelse(rp==0, b_cat2_opt2      * category_2,  0) +
      ifelse(rp==0, b_cat3_opt2      * category_3,  0) +
      ifelse(rp==0, b_cat4_opt2      * category_4,  0) +
      ifelse(rp==0, b_cat5_opt2      * category_5,  0) +
      ifelse(rp==0, b_ptsub_opt2     * ptsub,       0)
    asc_opt3_val = asc_opt3_val +
      ifelse(rp==0, b_gender_opt3    * gender,      0) +
      ifelse(rp==0, b_cityCenter_opt3* city_center, 0) +
      ifelse(rp==0, b_age18_29_opt3  * age_cat_18_29,0) +
      ifelse(rp==0, b_age30_44_opt3  * age_cat_30_44,0) +
      ifelse(rp==0, b_age45_64_opt3  * age_cat_45_64,0) +
      ifelse(rp==0, b_cat1_opt3      * category_1,  0) +
      ifelse(rp==0, b_cat2_opt3      * category_2,  0) +
      ifelse(rp==0, b_cat3_opt3      * category_3,  0) +
      ifelse(rp==0, b_cat4_opt3      * category_4,  0) +
      ifelse(rp==0, b_cat5_opt3      * category_5,  0) +
      ifelse(rp==0, b_ptsub_opt3     * ptsub,       0)
  }

  ## --- 6.2 Utilities -----------------------------------------
  V = list(
    opt1   = asc_opt1_val + b_price * price_opt1,
    opt2   = asc_opt2_val + b_price * price_opt2,
    opt3   = asc_opt3_val + b_price * price_opt3 + b_opt3 * opt3,
    opt4   = 0
  )

  ## --- 6.3 RP likelihood (one row per person) ----------------
  mnl_RP = list(
    alternatives = c(opt1=1, opt2=2, opt3=3, opt4=4),
    avail        = list(opt1=avail_opt1, opt2=avail_opt2, opt3=avail_opt3, opt4=1),
    choiceVar    = pref1,
    utilities    = lapply(V, function(x) mu_RP * x),
    rows         = (rp == 1)
  )
  P[["RP"]] = apollo_mnl(mnl_RP, functionality)

  ## --- 6.4 SP likelihood (panel) -----------------------------
  mnl_SP = list(
    alternatives = c(opt1=1, opt2=2, opt3=3, opt4=4),
    avail        = list(opt1=avail_opt1, opt2=avail_opt2, opt3=avail_opt3, opt4=1),
    choiceVar    = pref1,
    utilities    = lapply(V, function(x) mu_SP * x),
    rows         = (rp == 0)
  )
  P[["SP"]] = apollo_mnl(mnl_SP, functionality)

  ## --- 6.5 Combine RP & SP (still obs × draw) ----------------
  P = apollo_combineModels(P, apollo_inputs, functionality)

  ## --- 6.6 Collapse across panel observations ----------------
  if(any(apollo_inputs$rowsPerIndiv > 1)){
    P = apollo_panelProd(P, apollo_inputs, functionality)
  }

  ## --- 6.7 Average draws & tidy ------------------------------
  P = apollo_avgInterDraws(P, apollo_inputs, functionality)
  P = apollo_prepareProb(P, apollo_inputs, functionality)
  return(P)
}

##############################################################
#### 7. ESTIMATE                                           ####
##############################################################
model = apollo_estimate(
  apollo_beta, apollo_fixed,
  apollo_probabilities, apollo_inputs
)

##############################################################
#### 8. OUTPUT                                             ####
##############################################################
apollo_modelOutput(model)
apollo_saveOutput(model)
Thank you for looking at this!
stephanehess
Site Admin
Posts: 1355
Joined: 24 Apr 2020, 16:29

Re: MMNL on SP/RP data - multiple cores error

Post by stephanehess »

Hi

I suspect your issue might come from

Code: Select all

if(functionality=="estimate"){                      # only needed when estimating
why are you doing this? It will mean that during model validation, this part of the code is not used

Stephane
--------------------------------
Stephane Hess
www.stephanehess.me.uk
Mat2089119
Posts: 6
Joined: 06 Mar 2024, 10:00

Re: MMNL on SP/RP data - multiple cores error

Post by Mat2089119 »

Thanks for the quick reply. This seems to have been added when I was trying to debug the error with ChatGPT.

However, exactly the same error has happened before and is still happening when I remove this if statement. It also happens with a simple MNL version: 2 nodes produced errors; first error: SPECIFICATION ISSUE - You attempted to call the function apollo_panelProd at a stage where the probabilities are already at the individual level!

Is is possible that is caused by the different structure of the SP/RP data (SP is panel, RP is not)?

Code: Select all

 ################################################################# #
#### LOAD LIBRARY AND DEFINE CORE SETTINGS                       ####
# ################################################################# #
library(apollo)
apollo_initialise()

apollo_control = list(
  modelName       = "MNL_RP_SP",
  modelDescr      = "RP-SP model for opt1 / opt2 / opt3 / opt4 choice",
  indivID         = "RID",
  outputDirectory = "output",
  nCores          = 4
)

# ################################################################# #
#### LOAD DATA                                                   ####
# ################################################################# #

database <- cov_df

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

apollo_beta = c(
  ## ASCs
  asc_opt1   = 0,
  asc_opt2   = 0,
  asc_opt3   = 0,
  ## common taste parameters
  b_price    = 0,
  b_opt3     = 0,
  ## SP interactions: gender
  b_gender_opt1   = 0,
  b_gender_opt2   = 0,
  b_gender_opt3   = 0,
  ## SP interactions: city_center
  b_cityCenter_opt1 = 0,
  b_cityCenter_opt2 = 0,
  b_cityCenter_opt3 = 0,
  ## SP interactions: age categories
  b_age18_29_opt1   = 0,
  b_age18_29_opt2   = 0,
  b_age18_29_opt3   = 0,
  b_age30_44_opt1   = 0,
  b_age30_44_opt2   = 0,
  b_age30_44_opt3   = 0,
  b_age45_64_opt1   = 0,
  b_age45_64_opt2   = 0,
  b_age45_64_opt3   = 0,
  ## SP interactions: category segments 1–5
  b_cat1_opt1 = 0,
  b_cat1_opt2 = 0,
  b_cat1_opt3 = 0,
  b_cat2_opt1 = 0,
  b_cat2_opt2 = 0,
  b_cat2_opt3 = 0,
  b_cat3_opt1 = 0,
  b_cat3_opt2 = 0,
  b_cat3_opt3 = 0,
  b_cat4_opt1 = 0,
  b_cat4_opt2 = 0,
  b_cat4_opt3 = 0,
  b_cat5_opt1 = 0,
  b_cat5_opt2 = 0,
  b_cat5_opt3 = 0,
  b_ptsub_opt1 = 0,
  b_ptsub_opt2 = 0,
  b_ptsub_opt3 = 0,
  ## scale parameters
  mu_RP      = 1,
  mu_SP      = 0.65
)

## fix scale of RP
apollo_fixed = c("mu_RP")

# ################################################################# #
#### VALIDATE INPUTS                                             ####
# ################################################################# #

apollo_inputs = apollo_validateInputs()

# ################################################################# #
#### DEFINE LIKELIHOOD                                            ####
# ################################################################# #

apollo_probabilities = function(apollo_beta, apollo_inputs, functionality="estimate") {
  apollo_attach(apollo_beta, apollo_inputs)
  on.exit(apollo_detach(apollo_beta, apollo_inputs))
  
  P = list()
  
  ## 1) Build SP‐only ASCs with every socio demo interaction
  asc_opt1_val = asc_opt1
  asc_opt2_val = asc_opt2
  asc_opt3_val = asc_opt3
  
  ## SP‐only ASC for opt1
  asc_opt1_val = asc_opt1 +
      ifelse(rp==0, b_gender_opt1      * gender,           0) +
      ifelse(rp==0, b_cityCenter_opt1  * city_center,      0) +
      ifelse(rp==0, b_age18_29_opt1    * age_cat_18_29,    0) +
      ifelse(rp==0, b_age30_44_opt1    * age_cat_30_44,    0) +
      ifelse(rp==0, b_age45_64_opt1    * age_cat_45_64,    0) +
      ifelse(rp==0, b_cat1_opt1       * category_1,       0) +
      ifelse(rp==0, b_cat2_opt1       * category_2,       0) +
      ifelse(rp==0, b_cat3_opt1       * category_3,       0) +
      ifelse(rp==0, b_cat4_opt1       * category_4,       0) +
      ifelse(rp==0, b_cat5_opt1       * category_5,       0) +
      ifelse(rp==0, b_ptsub_opt1      * ptsub,            0)
    
  ## SP‐only ASC for opt2
  asc_opt2_val = asc_opt2 +
      ifelse(rp==0, b_gender_opt2      * gender,           0) +
      ifelse(rp==0, b_cityCenter_opt2  * city_center,      0) +
      ifelse(rp==0, b_age18_29_opt2    * age_cat_18_29,    0) +
      ifelse(rp==0, b_age30_44_opt2    * age_cat_30_44,    0) +
      ifelse(rp==0, b_age45_64_opt2    * age_cat_45_64,    0) +
      ifelse(rp==0, b_cat1_opt2       * category_1,       0) +
      ifelse(rp==0, b_cat2_opt2       * category_2,       0) +
      ifelse(rp==0, b_cat3_opt2       * category_3,       0) +
      ifelse(rp==0, b_cat4_opt2       * category_4,       0) +
      ifelse(rp==0, b_cat5_opt2       * category_5,       0) +
      ifelse(rp==0, b_ptsub_opt2      * ptsub,            0)
    
  ## SP‐only ASC for opt3
  asc_opt3_val = asc_opt3 +
      ifelse(rp==0, b_gender_opt3      * gender,           0) +
      ifelse(rp==0, b_cityCenter_opt3  * city_center,      0) +
      ifelse(rp==0, b_age18_29_opt3    * age_cat_18_29,    0) +
      ifelse(rp==0, b_age30_44_opt3    * age_cat_30_44,    0) +
      ifelse(rp==0, b_age45_64_opt3    * age_cat_45_64,    0) +
      ifelse(rp==0, b_cat1_opt3       * category_1,       0) +
      ifelse(rp==0, b_cat2_opt3       * category_2,       0) +
      ifelse(rp==0, b_cat3_opt3       * category_3,       0) +
      ifelse(rp==0, b_cat4_opt3       * category_4,       0) +
      ifelse(rp==0, b_cat5_opt3       * category_5,       0) +
      ifelse(rp==0, b_ptsub_opt3      * ptsub,            0)
  
  ## 2) Define utilities
  V = list(
    opt1   = asc_opt1_val + b_price * price_opt1,
    opt2   = asc_opt2_val + b_price * price_opt2,
    opt3   = asc_opt3_val + b_price * price_opt3 + b_opt3 * opt3,
    opt4   = 0
  )
  
  ## 3) RP model
  mnl_RP = list(
    alternatives = c(opt1=1, opt2=2, opt3=3, opt4=4),
    avail        = list(opt1=avail_opt1, opt2=avail_opt2, opt3=avail_opt3, opt4=1),
    choiceVar    = pref1,
    utilities    = lapply(V, function(x) mu_RP * x),
    rows         = (rp==1)
  )
  P[["RP"]] = apollo_mnl(mnl_RP, functionality)
  
  ## 4) SP model
  mnl_SP = list(
    alternatives = c(opt1=1, opt2=2, opt3=3, opt4=4),
    avail        = list(opt1=avail_opt1, opt2=avail_opt2, opt3=avail_opt3, opt4=1),
    choiceVar    = pref1,
    utilities    = lapply(V, function(x) mu_SP * x),
    rows         = (rp==0)
  )
  P[["SP"]] = apollo_mnl(mnl_SP, functionality)
  
  ## 5) Combine & return
  P = apollo_combineModels(P, apollo_inputs, functionality)
  P = apollo_panelProd(P, apollo_inputs, functionality)
  P = apollo_prepareProb(P, apollo_inputs, functionality)
  return(P)
}

# ################################################################# #
#### ESTIMATE MODEL                                              ####
# ################################################################# #

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

# ################################################################# #
#### OUTPUT & POST‐PROCESSING                                   ####
# ################################################################# #

apollo_modelOutput(model)
apollo_saveOutput(model)
stephanehess
Site Admin
Posts: 1355
Joined: 24 Apr 2020, 16:29

Re: MMNL on SP/RP data - multiple cores error

Post by stephanehess »

Hi

doesn't look like it. If you are happy to share the code and data with me, then I can have a look for you

Stephane
--------------------------------
Stephane Hess
www.stephanehess.me.uk
stephanehess
Site Admin
Posts: 1355
Joined: 24 Apr 2020, 16:29

Re: MMNL on SP/RP data - multiple cores error

Post by stephanehess »

Matthias

What happened here is that when splitting the data across cores, then in some cores, there is only one row per person. You can avoid the error by replacing

P = apollo_panelProd(P, apollo_inputs, functionality)

with

if(length(unique(apollo_inputs$database[, apollo_inputs$apollo_control$indivID]))<nrow(apollo_inputs$database)) P = apollo_panelProd(P, apollo_inputs, functionality)

Stephane
--------------------------------
Stephane Hess
www.stephanehess.me.uk
Post Reply