inst/examples/mdcev_no_outside_good/example_utils.R

# Shared data and command-line preparation for the MDCEV examples.
#
# This file deliberately contains no model equations.  The model specification
# stays in each example script so that the scripts can be read and run on their
# own.  The helper only handles paths, Python configuration, and the native
# database input used by process_data.py in the corresponding Biogeme example.

parse_mdcev_arguments <- function(arguments, defaults = list()) {
  options <- defaults
  for (argument in arguments) {
    if (!startsWith(argument, "--") || !grepl("=", argument, fixed = TRUE)) {
      stop("Arguments must use the --name=value form: ", argument, call. = FALSE)
    }
    pieces <- strsplit(sub("^--", "", argument), "=", fixed = TRUE)[[1L]]
    key <- gsub("-", "_", pieces[[1L]], fixed = TRUE)
    value <- paste(pieces[-1L], collapse = "=")
    if (!nzchar(key)) stop("Argument names must not be empty.", call. = FALSE)
    options[[key]] <- value
  }
  options
}

prepare_mdcev_example <- function(arguments, default_model) {
  file_arguments <- commandArgs(trailingOnly = FALSE)
  script_argument <- file_arguments[startsWith(file_arguments, "--file=")]
  script_directory <- if (length(script_argument) == 1L) {
    dirname(normalizePath(sub("^--file=", "", script_argument)))
  } else {
    getwd()
  }

  options <- parse_mdcev_arguments(
    arguments,
    defaults = list(
      data = file.path(script_directory, "data.csv"),
      python = Sys.getenv("RBIOGEME_PYTHON", unset = ""),
      output = ""
    )
  )
  if (is.null(options$data) || !nzchar(options$data) || !file.exists(options$data)) {
    stop("The MDCEV data file is missing: ", options$data, call. = FALSE)
  }
  if (!is.null(options$python) && nzchar(options$python)) {
    if (!file.exists(options$python)) {
      stop("The selected Python executable does not exist: ", options$python, call. = FALSE)
    }
    rbiogeme::biogeme_config(python = options$python)
  }

  data <- read.csv(options$data, check.names = FALSE, stringsAsFactors = FALSE)
  required <- c(
    "PersonID", "weight", "hhsize", "childnum", "faminc", "faminc25K",
    "income", "employed", "fulltime", "spousepr", "spousemp", "male",
    "married", "age", "age2", "age15_40", "age41_60", "age61_85",
    "bachigher", "white", "metro", "diaryday", "Sunday", "holiday",
    "weekearn", "weekwordur", "hhchild", "ohhchild", "t1", "t2", "t3",
    "t4", "number_chosen"
  )
  if (!all(required %in% names(data))) {
    missing <- required[!required %in% names(data)]
    stop("The MDCEV data file is missing column(s): ", paste(missing, collapse = ", "), call. = FALSE)
  }

  if (is.null(options$output) || !nzchar(options$output)) {
    stop("Provide --output=/path/to/output.", call. = FALSE)
  }
  output <- normalizePath(path.expand(options$output), mustWork = FALSE)
  dir.create(output, recursive = TRUE, showWarnings = FALSE)
  list(
    options = options,
    data = data,
    output = output,
    data_path = normalizePath(options$data)
  )
}

prepare_mdcev_database <- function(data, name = "mdcev_example") {
  # This is the exact operation performed by process_data.py: read every row
  # without a filter or panel declaration and retain all source columns. The
  # model scripts scale t1:t4 symbolically when they define consumption.
  rbiogeme::biogeme_database(name, data)
}

Try the rbiogeme package in your browser

Any scripts or data that you put into this service are public.

rbiogeme documentation built on Sept. 29, 2026, 5:09 p.m.