# Singularity issues in multinomial model using R

I am trying to develop a mode choice model (4 modes: hov, transit, bike, walk) and below are two approaches I am using. I am having problems in both

• Approach 1

Mode choice as a function of price (cost of using the mode)

price: generic variable
trans1: choice variable (0,1)
Dataset: work
Command:

> mode.choice <- mlogit(trans1 ~ price, work)

Error: Error in solve.default(H, g[!fixed]) :
Lapack routine dgesv: system is exactly singular


P.S: Unlike previous posts, I don’t have NA’s in my dataset.

• Approach 2

Mode choice as a function of price and some alternative specific variables

price: Generic Variable
trans1: choice variable (0,1)
hh1, hh2, hh3: alternative specific variables
Dataset: work
Command:

> mode.choice <- mlogit(trans1 ~ price | hh1 + hh2 + hh3, work)

Error: Error in solve.default(H, g[!fixed]) :
Lapack routine dgesv: system is exactly singular


I have tried different variables in both approaches but the singularity issue persists

Help on any of these approaches would be greatly appreciated.

• How is price coded in R (numeric or factor)? Did you check if any of your response categories didn't occur as a unique combination of your predictors? See also this related thread. – chl Jul 19 '12 at 9:08
• Highly probable that you have some perfectly correlated variables in the model. Thus intermediate matrix turns to be singular. – Paul Jul 19 '12 at 9:28
• Did you set up your estimation matrix using the mlogit.data() command? If so, did you make sure that price is indeed varying across alternatives? – gregmacfarlane Jul 19 '12 at 16:32
• @chl: thanks for your comment. Price is coded as numeric and without including price in the equation for approach 2, i would get this error :Error in if (abs(x - oldx) < ftol) { : missing value where TRUE/FALSE needed. Actually, I am trying to translate a code from nlogit to R. In the nlogit code,there is a separate utility function (with different sets of alternative specific variables) for each of the modes. In R, I am finding it difficult to do that as all the variables I give are either taken as generic or alternative specific to all the modes but not some of them. – Transporter Jul 19 '12 at 18:41
• If price doesn't vary across alternatives, you should call it as mlogit(trans1 ~ 1 | price) – gregmacfarlane Jul 19 '12 at 20:49

This expands on the comment by @gmacfarlane above. I assume that when you say 'generic variable' you mean a covariate that varys between individuals but not between alternative choices offered to the same individual.

You have the individual and alternative specific variables entered backwards in the formula statement. For the 2nd approach, do you intend for there to be a single coefficient affecting all the alternatives similarly? If so,

mode.choice <- mlogit(trans1 ~ hh1 + hh2 + hh3 | price, work)


is what you want. Alternatively you may want to have a model where each alternative specific covariate affects the alternatives differently. Then,

mode.choice <- mlogit(trans1 ~ 1 | price | hh1 + hh2 + hh3, work)


is what you want. To be complete here, if you just want the effects of price with different coefficients for each outcome (Your approach 1, and gmacfarlane's suggestion) then

mode.choice <- mlogit(trans1 ~ 1 | price, work)


is your ticket. Read the package mlogit vignette carefully, especially section 1.2.

You have singularity issues for both because your matrix is singular (surprise). This means that you have very strong correlations or equal values for different lines and or columns.

Given what you are trying to model this makes sense. I assume that the prices for transport in many lines are the same (especially in the first model) for many observations. For instance: A bus ticket will probably cost the same for everybody that makes the decision to take the bus or not (and definitely the same for those that decide to walk) resulting in a singular matrix if you have more that one person deciding to take the bus or not.

You need to transform your price variable to an ordered factor (with functions like cut,cut2 and as.factor) that will give you a model that can produce results. Also note atiretoo's notes on notation (I usually use multinom in the nnet package).