I will treat this answer in two parts:
Why would you want to do this?
To begin with, variables like cost and travel time vary across alternatives, which actually makes them generic variables. The multinomial logit model is defined on the difference between two utility functions. Say you have two alternatives (1 and 2), where $x$ is the same in both. If you difference the utility equations, $\alpha_1 + \beta x - [\alpha_2 + \beta x]$ will cancel out $\beta$. So you estimate them as alternative-specific parameters $\alpha_1 + \beta_1 x - [\alpha_2 + \beta_2 x]$, allowing them to be defined.
But if $x_1$ and $x_2$ are different, the equation is identifiable with a single $\beta$,
$\alpha_1 + \beta x_1 - [\alpha_2 + \beta x_2]$
If you estimate this model (I'm only going to use one travel time)
$$ U_{train} = \alpha_{train} + \beta_{tt} (TT_{train})$$
$$ U_{auto} = \alpha_{auto} + \beta_{tt} (TT_{auto})$$
You estimate three parameters ($\alpha_{train}, \alpha_{auto}, \beta_{tt}$). If
you insist on estimating alternative-specific parameters for $\beta_{tt:auto},
\beta_{tt:train}$, you have spent a degree of freedom estimating a parameter
that you don't actually need, which makes your model less efficient, with
knock-on consequences for your hypothesis tests. Not to mention that
cross-elasticities are lots easier to calculate with generic coefficients...
You only need alternative specific coefficients if you have variables that
don't vary across alternatives, like if you had income, or the distance
between the start and end of the trip.
Okay, you want to do this anyways, so how do you do it?
There are a couple of ways that I might do this. First I'm going to build
a simple dataset from the Biogeme swissmetro dataset.
library(foreign)
swissmetro <- read.delim("~/Downloads/swissmetro.dat")
library(dplyr)
swissmetro <- swissmetro %>%
filter(CHOICE %in% c(1, 3)) %>%
mutate(choice = factor(CHOICE, labels = c("train", "car")),
tt.train = TRAIN_TT, tt.car = CAR_TT,
cost.train = TRAIN_CO, cost.car = CAR_CO) %>%
select(ID, choice, tt.train, tt.car, cost.train, cost.car)
library(mlogit)
sm <- reshape(swissmetro, varying = 3:6, direction = "long")
sm <- sm %>%
mutate(choice = ifelse(choice == time, TRUE, FALSE), alt = time) %>%
arrange(id) %>% select(-time)
sm.mlogit <- mlogit.data(sm, choice = "choice", id.var = "ID", alt.var = "alt",
shape = "long")
head(sm.mlogit)
## ID choice tt cost id alt
## 1.train 1 TRUE 103 36 1 train
## 1.car 1 FALSE 90 65 1 car
## 2.train 7 TRUE 80 42 2 train
## 2.car 7 FALSE 72 140 2 car
## 3.train 8 FALSE 100 22 3 train
## 3.car 8 TRUE 80 24 3 car
This replicates (what I think is) your data pretty well, though with only one
travel time
variable. We can and should treat both tt
and cost
as generic, giving us
the most efficient model,
mnl1 <- mlogit(choice ~ tt + cost, data = sm.mlogit)
summary(mnl1)
##
## Call:
## mlogit(formula = choice ~ tt + cost, data = sm.mlogit, method = "nr",
## print.level = 0)
##
## Frequencies of alternatives:
## car train
## 0.684 0.316
##
## nr method
## 6 iterations, 0h:0m:0s
## g'(-H)^-1g = 2.11E-05
## successive function values within tolerance limits
##
## Coefficients :
## Estimate Std. Error t-value Pr(>|t|)
## train:(intercept) -1.33e+00 4.56e-02 -29.16 <2e-16 ***
## tt -2.57e-04 4.69e-04 -0.55 0.58
## cost 1.40e-03 5.92e-05 23.71 <2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Log-Likelihood: -2180
## McFadden R^2: 0.225
## Likelihood ratio test : chisq = 1260 (p.value = <2e-16)
Attempt 1: intercept interaction
My first idea is to interact the generic variables with an intercept, which is
the same as forcing your missing $\beta_{train}$ to equal $0$.
sm.mlogit$car <- ifelse(sm.mlogit$alt == "train", 0, 1)
head(sm.mlogit)
## ID choice tt cost id alt car
## 1.train 1 TRUE 103 36 1 train 0
## 1.car 1 FALSE 90 65 1 car 1
## 2.train 7 TRUE 80 42 2 train 0
## 2.car 7 FALSE 72 140 2 car 1
## 3.train 8 FALSE 100 22 3 train 0
## 3.car 8 TRUE 80 24 3 car 1
mnl2 <- mlogit(choice ~ tt + I(cost*car), data = sm.mlogit)
summary(mnl2)
##
## Call:
## mlogit(formula = choice ~ tt + I(cost * car), data = sm.mlogit,
## method = "nr", print.level = 0)
##
## Frequencies of alternatives:
## car train
## 0.684 0.316
##
## nr method
## 6 iterations, 0h:0m:0s
## g'(-H)^-1g = 1.29E-06
## successive function values within tolerance limits
##
## Coefficients :
## Estimate Std. Error t-value Pr(>|t|)
## train:(intercept) 1.01e+00 7.58e-02 13.30 <2e-16 ***
## tt 7.21e-05 4.72e-04 0.15 0.88
## I(cost * car) 2.84e-02 1.04e-03 27.42 <2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Log-Likelihood: -2230
## McFadden R^2: 0.205
## Likelihood ratio test : chisq = 1150 (p.value = <2e-16)