Multinomial Logit Choice Modeling Guide
Multinomial Logit Choice Modeling Guide
Warren F. Kuhfeld
SAS
Contents
Introduction 74
Preliminaries 76
Experimental Design Terminology . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76
Efficiency of an Experimental Design . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77
Efficiency of a Choice Design . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77
Customizing the Multinomial Logit Output . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79
Orthogonal Coding, Efficiency, Balance, and Orthogonality . . . . . . . . . . . . . . . . . . . . . . . 80
Candy Example 83
The Multinomial Logit Model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83
The Input Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85
Fitting the Multinomial Logit Model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87
Multinomial Logit Model Results . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88
Fitting the Multinomial Logit Model, All Levels . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90
Probability of Choice . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92
Food Product Example with Asymmetry and Availability Cross Effects 192
The Multinomial Logit Model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 192
Set Up . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 193
Designing the Choice Experiment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 194
When You Have a Long Time to Search for an Efficient Design . . . . . . . . . . . . . . . . . . . . . 198
Examining the Design . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 200
Designing the Choice Experiment, More Choice Sets . . . . . . . . . . . . . . . . . . . . . . . . . . 202
72 TS-677E Multinomial Logit, Discrete Choice Modeling
References 370
Index 386
74 TS-677E Multinomial Logit, Discrete Choice Modeling
We use the %MktRuns autocall macro to suggest design sizes. See page 360 for documentation. The
%MktRuns macro has been revised since the 2001 book.
We use the %MktEx autocall macro to generate most of our experimental designs. It is easier to use and
usually produces better results than the methods suggested in earlier reports. See page 327 for documen-
tation. The %MktEx macro is new with the 2002 book.
We use the %MktEval autocall macro to evaluate our designs. See page 325 for documentation. The
%MktEval macro has been revised since the 2001 book.
We use the %ChoicEff autocall macro to generate certain specialized choice designs. See page 288 for
documentation.
We use the autocall macros %MktRoll, %MktMerge, and %MktAllo to prepare the data and design for
analysis. See pages 356, 353, and 303 for documentation.
We use PROC TRANSREG to do all of our design coding.
We use the %PhChoice autocall macro to customize our printed output. This macro uses PROC TEM-
PLATE and ODS (Output Delivery System) to customize the output from PROC PHREG, which fits the
multinomial logit model. See page 364 for documentation.
The %MktBal macro can be used to make perfectly balanced designs. See page 305 for documentation.
The %MktBal macro is new with the 2002 book.
The %MktBlock macro can be used to block a linear or choice design. See page 307 for documentation.
The %MktBlock macro is new with the 2002 book.
The %MktDes experimental design macro, which was heavily used in previous reports, is called by the
%MktEx macro, and it can still be called directly. See page 307 for documentation.
The %MktDups macro can be used to search for duplicate runs or choice sets. See page 319 for documen-
tation. The %MktDups macro is new with the 2002 book.
The %MktLab macro can be used to assign different variable names, labels and levels to experimental
designs and to add an intercept. See page 345 for documentation. The %MktLab macro is new with the
2002 book.
The %MktOrth macro can be used to list orthogonal experimental designs that the %MktEx macro can
produce. See page 354 for documentation. The %MktOrth macro is new with the 2002 book.
Introduction 75
All of these macros are distributed with Version 9.0 of SAS as autocall macros (see page 287 for more information
on autocall macros). Note however, that Version 9.0 was finished before the macros were finalized and this book
finished. Hence there are a few differences between the macros used in this book and those shipped with Version
9.0 of SAS. If you are running version 9.0 or any earlier version of SAS, get the latest macros from the web or by
writing [Link]@[Link]. This report and the macros are available from the Technical Support web site
at [Link] [Link] . This information is provided by SAS as a service
to its users. It is provided “as is.” There are no warranties, expressed or implied, as to merchantability or fitness
for a particular purpose regarding the accuracy of the materials or code contained herein.
Several examples are discussed.
The candy example is a first, very simple example that discusses the multinomial logit model, the input
data, analysis, results, and computing probability of choice.
The fabric softener example is a small, somewhat more realistic example that discusses designing the
choice experiment, randomization, generating the questionnaire, entering and processing the data, analysis,
results, probability of choice, and custom questionnaires.
The first vacation example is a larger, symmetric example that discusses designing the choice experi-
ment, blocks, randomization, generating the questionnaire, entering and processing the data, coding, and
alternative-specific effects.
The second vacation example is a larger, asymmetric example that discusses designing the choice experi-
ment, blocks, blocking an existing design, interactions, generating the questionnaire, generating artificial
data, reading, processing, and analyzing the data, aggregating the data to save time and memory.
The brand choice example is a small example that discusses the processing of aggregate data, the mother
logit model, and the likelihood function.
The food product example is a medium sized example that discusses asymmetry, coding, checking the
design to ensure that all effects are estimable, availability cross effects, interactions, overnight design
searches, modeling subject attributes, and designs when balance is of primary importance.
The drug allocation example is a small example that discusses data processing for studies where respon-
dents potentially make multiple choices.
The chair example is a purely generic-attributes study, and it uses the %ChoicEff macro to create exper-
imental designs.
The last example sections contains miscellaneous examples including improving an existing design, aug-
menting a design with some choice sets are fixed in advance, and partial profiles.
This document would not be possible without the help of Randy Tobias who contributed to the discussion of
experimental design and Ying So who contributed to the discussion of analysis. Randy Tobias wrote PROC
FACTEX and PROC OPTEX. Ying So wrote PROC PHREG. Warren F. Kuhfeld wrote PROC TRANSREG and
the macros.
All of the sample data sets are artificially generated.
76 TS-677E Multinomial Logit, Discrete Choice Modeling
Preliminaries
This section defines some design terms that we will use later and shows how to customize the multinomial logit
output listing. Impatient readers may skip ahead to the candy example on page 83 and refer back to this section
as needed.
The term “orthogonal array,” as it is sometimes used in practice, is imprecise. It is correctly used to refer to
designs that are both orthogonal and balanced, and hence optimal. The term is sometimes also used to refer to
designs that are orthogonal but not balanced, and hence not 100% efficient and sometimes not even optimal. A
design is balanced when each level occurs equally often within each factor, which that means the intercept is
orthogonal to each effect. Imbalance is a generalized form of nonorthogonality, hence it increases the variances
of the parameter estimates and decreases efficiency.
= 100 N 1
trace ((X0 X) 1 )=p
A-efficiency
D
p
G-efficiency = 100 p=N
D
These efficiencies measure the goodness of the design relative to hypothetical orthogonal designs that may not
exist, so they are not useful as absolute measures of design efficiency. Instead, they should be used relatively,
to compare one design to another for the same situation. Efficiencies that are not near 100 may be perfectly
satisfactory. Throughout this report, we will use the %MktEx macro to find good, efficient experimental designs.
@ 2
= =1 N =1 exp(x0 )
n
k
j
m
j j j j j j
( =1 exp(x0 ))2
m
j j j
=1 j j j j
where
78 TS-677E Multinomial Logit, Discrete Choice Modeling
exp(( =1 f x0 ) )
m
`( ) = n j j j
=1
k
( =1 exp(x0 ))
m
j j
N
m– brands
n – choice sets
N– people
We will often create experimental designs for choice models using efficiency criteria for linear models. Consider
an extremely simple example of three brands and two prices. We could use linear model theory to create a design
for a full-profile conjoint study. The full-profile conjoint design has two factors, one for brand and one for price.
For the same brands and prices, we could instead use linear model theory to create a linear design from which
we will construct a choice design to use in a discrete choice study. The linear design for a pricing study with
three brands has three factors (Brand 1 Price, Brand 2 Price, and Brand 3 Price) and one row for each choice set.
More generally, the linear design has one factor for each attribute of each alternative (or brand), and brand is not
a factor in the linear design. Each brand is a “bin” into which its factors are collected.
Full-Profile
Linear Design
Conjoint Design
Used to Make a Choice Design
Brand Price
Brand 1 Brand 2 Brand3
1 1.99
Price Price Price
1 2.99
1.99 1.99 1.99
2 1.99
1.99 2.99 2.99
2 2.99
2.99 1.99 2.99
3 1.99
2.99 2.99 1.99
3 2.99
Before we fit the choice model, we will construct a choice design from the linear design and code the choice
design. See the three tables below.
Linear Design Choice Design Choice Design Coding
Brand 1 Brand 2 Brand 3
1 2 3 Brand Price Brand 1 Brand 2 Brand 3 Price Price Price
1.99 1.99 1.99 1 1.99 1 0 0 1.99 0 0
2 1.99 0 1 0 0 1.99 0
3 1.99 0 0 1 0 0 1.99
1.99 2.99 2.99 1 1.99 1 0 0 1.99 0 0
2 2.99 0 1 0 0 2.99 0
3 2.99 0 0 1 0 0 2.99
2.99 1.99 2.99 1 2.99 1 0 0 2.99 0 0
2 1.99 0 1 0 0 1.99 0
3 2.99 0 0 1 0 0 2.99
2.99 2.99 1.99 1 2.99 1 0 0 2.99 0 0
2 2.99 0 1 0 0 2.99 0
3 1.99 0 0 1 0 0 1.99
The linear design has one row per choice set. The choice design has three rows for each choice set. The linear
design and the choice design contain different arrangements of the exact same information. In the linear design,
brand is a bin into which its factors are collected (in this case one factor per brand). In the choice design, brand
and price are both factors, because the design has been rearranged from one row per choice set to one row per
alternative per choice set. For this problem, with only one attribute per brand, the first row of the choice design
matrix corresponds to the first value in the linear design matrix, Brand 1 at $1.99. The second row of the choice
design matrix corresponds to the second value in the linear design matrix, Brand 2 at $1.99. The third row of the
choice design matrix corresponds to the third value in the linear design matrix, Brand 3 at $1.99, and so on.
Preliminaries 79
We will go through how to construct linear and choice designs many times in the examples. For now, just notice
that the conjoint design is different from the linear design, which is different from the choice design. They aren’t
even the same size! Also note that we cannot use linear efficiency criteria to directly construct the choice design
bypassing the linear design step.
We make a good design for a linear model by picking x’s that minimize functions of (X0 X) 1. In the choice
model, ideally we would like to minimize functions of
" " ##
=1 exp(x0 )x x0 ( =1 exp(x0 )x )( =1 exp(x0 )x )0 1
V ( ^) = =1 N
m m m
n j j j j j j j j j j
k
=1 exp(x0 )
m
j j
( =1 exp(x0 ))2
m
j j
We cannot do this unless we know , and if we knew , we would not need to do the experiment. (However, in
the chair example on pages 252 267, we will see how to make an efficient choice design when we are willing to
make assumptions about .)
Certain assumptions must be made before applying ordinary general-linear-model theory to problems in mar-
keting research. The usual goal in linear modeling is to estimate parameters and test hypotheses about those
parameters. Typically, independence and normality are assumed. In full-profile conjoint analysis, each subject
rates all products and separate ordinary-least-squares analyses are run for each subject. This is not a standard
general linear model; in particular, observations are not independent and normality cannot be assumed. Discrete
choice models, which are nonlinear, are even more removed from the general linear model.
Marketing researchers have always made the critical assumption that designs that are good for general linear
models are also good designs for conjoint analysis and discrete choice models. We also make this assumption.
We will assume that an efficient design for a linear model is a good design for the multinomial logit model
used in discrete choice studies. We assume that if we create the linear design (one row per choice set and all
of the attributes of all of the alternatives comprise that row), and if we strive for linear-model efficiency (near
balance and orthogonality), then we will have a good design for measuring the utility of each alternative and the
contributions of the factors to that utility. When we construct choice designs in this way, our designs will have
two nice properties. 1) Each attribute level will occur equally often (or at least nearly equally often) for each
attribute of each alternative across all choice sets. 2) Each attribute will be independent of every other attribute
(or at least nearly independent), both those in the current alternative and those in all of the other alternatives. The
design techniques discussed in this book that are based on the assumption that linear design efficiency is a good
surrogate for choice design goodness have been used quite successfully in the field for many years.
In most of the examples, we will use the %MktEx macro to create a good linear design, from which we will
construct our choice design. This seems to be a good safe strategy. It is safe in the sense that you have enough
choice sets and collect enough information so that very complex models, including models with alternative-
specific effects, availability effects, and cross effects, can be fit. However, it is good to remember that when you
run the %MktEx macro and you get an efficiency value, it corresponds to the linear design, not the choice design.
It is a surrogate for the criterion of interest, the efficiency of the choice design, which is unknowable unless you
know the parameters.
The macro uses PROC TEMPLATE and ODS (Output Delivery System) to customize the output from PROC
PHREG. Running this code edits the templates and stores copies in sasuser. These changes will remain in
effect until you delete them, so typically, you only have to run this macro once. Note that these changes assume
that each effect in the choice model has a variable label associated with it, so there is no need to print variable
names. If you are coding with PROC TRANSREG, this will usually be the case. To return to the default output
from PROC PHREG, run the following macro.
%phchoice(off)
= 100 N 1
trace ((X0 X) )=p
A-efficiency 1
D
When computing D-efficiency or A-efficiency, we code X so that when the design is orthogonal and balanced.
X0 X = ND I where I is a p p identity matrix. When our design is orthogonal and balanced, (X0 X) 1 = N1 I,
D
and trace ((X0 X) 1 )=p = j(X0 X) 1 j1=p = 1=ND . In this case, the two denominator terms cancel and efficiency
is 100%. As the average variance increases, efficiency decreases.
Here are the orthogonal codes for two-level through five-level factors.
Two-Level Three-Level Four-Level Five-Level
a 1.00 a 1.22 -0.71 a 1.41 -0.82 -0.58 a 1.58 -0.91 -0.65 -0.50
b -1.00 b 0 1.41 b 0 1.63 -0.58 b 0 1.83 -0.65 -0.50
c -1.22 -0.71 c 0 0 1.73 c 0 0 1.94 -0.50
d -1.41 -0.82 -0.58 d 0 0 0 2.00
e -1.58 -0.91 -0.65 -0.50
Notice that the sum of squares for the coding of the two-level factor is 2; for all of the columns of the three-level
factor, the sums of squares are 3; for the four-level factor, the sums of squares are all 4; and for the five-level
factor, the sums of squares are all 5. Also notice that each column within a factor is orthogonal to all of the
other columns the sum of cross products is zero. For example, in the last two columns of the five-level factor,
0:65 0:5 + 0:65 0:5 + 1:94 :05 + 0 2 + 0:65 0:5 = 0. Finally notice that the codings for
each level form a contrast the ith level versus all of the preceding levels and the last level.
This example shows the coding of a 2 6 full-factorial design in 12 runs using a coding function that requires
that the factors levels are consecutive positive integers beginning with one and ending with m for an m-level
factor. Note that the IML operator # performs ordinary (scalar) multiplication, and ## performs exponentiation.
Preliminaries 81
start orthogcode(x);
levels = max(x);
xstar = shape(x, levels - 1, nrow(x))‘;
j = shape(1 : (levels - 1), nrow(x), levels - 1);
r = sqrt(levels # (x / (x + 1))) # (j = xstar) -
sqrt(levels / (j # (j + 1))) # (j > xstar | xstar = levels);
return(r);
finish;
design = (1:2)‘ @ j(6, 1, 1) || {1, 1} @ (1:6)‘;
x = j(12, 1, 1) || orthogcode(design[,1]) || orthogcode(design[,2]);
print design[format=1.] ’ ’ x[format=5.2 colname={’Int’ ’Two’ ’Six’}];
X
DESIGN Int Two Six
XPX
12 0 0 0 0 0 0
0 12 0 0 0 0 0
0 0 12 0 0 0 0
0 0 0 12 0 0 0
0 0 0 0 12 0 0
0 0 0 0 0 12 0
0 0 0 0 0 0 12
INV
0.083 0 0 0 0 0 0
0 0.083 0 0 0 0 0
0 0 0.083 0 0 0 0
0 0 0 0.083 0 0 0
0 0 0 0 0.083 0 0
0 0 0 0 0 0.083 0
0 0 0 0 0 0 0.083
82 TS-677E Multinomial Logit, Discrete Choice Modeling
D_EFF A_EFF
With this orthogonal and balanced design, X0 X =N D I = 12I, which means (X0 X) 1 = N
1
DI = 1
12 I, and
D-efficiency = 100%.
With a nonorthogonal design, for example with the first 10 rows of the 2 6 full-factorial design, D-efficiency
and A-efficiency are less than 100%.
design = design[1:10,];
x = j(10, 1, 1) || orthogcode(design[,1]) || orthogcode(design[,2]);
inv = inv(x‘ * x);
d_eff = 100 / (nrow(x) # det(inv) ## (1 / ncol(inv)));
a_eff = 100 / (nrow(x) # trace(inv) / ncol(inv));
print ’D-efficiency =’ d_eff[format=6.2]
’ A-efficiency =’ a_eff[format=6.2];
quit;
D_EFF A_EFF
In this case, j(X0 X) 1 j1=p and trace ((X0 X) 1 )=p are multiplied in the denominator of the efficiency formulas
1 . If an orthogonal and balanced design were available for this problem, then (X0 X) 1 would equal
by N1D = 10
1 I = 1 I. Since an orthogonal and balanced design is not possible (6 does not divide 10), both D-efficiency
ND 10
and A-efficiency will be less than 100%, even with the optimal design. A main-effects, orthogonal and balanced
design, with a variance matrix equal to N1D I, is the standard by which 100% efficiency is gauged, even when
we know such a design cannot exist. The standard is the average variance for the maximally efficient potentially
hypothetical design, which is knowable, not the average variance for the optimal design, which for many practical
problems we have no way of knowing.
For our purposes in this report, we will never consider an experimental design with fewer runs than a saturated
design. A saturated design has as many runs as there are parameters. The number of parameters in a main-
effects model is 1 (for the intercept) plus the sum of the numbers of levels of all of the factors, minus the number
of factors. Equivalently, since there are m 1 parameters in an m-level factor, the number of parameters is
1 + Pkj=1 (mj 1) for k factors, each with mj levels.
If a main-effects design is orthogonal and balanced, then the design must be at least as large as the saturated
design and the number of runs must be divisible by the number of levels of all the factors and by the products of
the number of levels of all pairs of factors. For example, a 2 2 3 3 3 design cannot be orthogonal and
balanced unless the number of runs is divisible by 2 (twice because there are two 2’s), 3 (three times because
there are three 3’s), 2 2 = 4 (once, because there is one pair of 2’s), 2 3 = 6 (six times, two 2’s times three
3’s), and 3 3 = 9 (three times, three pairs of 3’s). If the design is orthogonal and balanced, then all of the
divisions will work without a remainder. However, all of the divisions working is a necessary but not sufficient
condition for the existence of an orthogonal and balanced design. For example, 45 is divisible by 3 and 3 3 = 9,
but an orthogonal and balanced saturated design 322 (22 three-level factors) in 45 runs does not exist.
Candy Example 83
Candy Example
We begin with a very simple example. In this example, we will discuss the multinomial logit model, data input
and processing, analysis, results, interpretation, and probability of choice. In this example, each of ten subjects
was presented with eight different chocolate candies and asked to choose one. The eight candies consist of the
23 combinations of dark or milk chocolate, soft or chewy center, and nuts or no nuts. Each subject saw all eight
candies and made one choice. Experimental choice data such as these are typically analyzed with a multinomial
logit model.
p(c jC ) = P
exp(U (c )) = P exp(x )
i i
=1 exp(U (c )) =1 exp(x )
i m m
j j j j
where xi is a vector of alternative attributes and is a vector of unknown parameters. U (ci ) = xi is the utility
for alternative ci , which is a linear function of the attributes. The probability that an individual will choose one
of the m alternatives, ci , from choice set C is the exponential of the utility of the alternative divided by the sum
of all of the exponentiated utilities.
There are m = 8 attribute vectors in this example, one for each alternative. Let x = (Dark/Milk, Soft/Chewy,
Nuts/No Nuts) where Dark/Milk = (1 = Dark, 0 = Milk), Soft/Chewy = (1 = Soft, 0 = Chewy), Nuts/No Nuts =
(1 = Nuts, 0 = No Nuts). The eight attribute vectors are
Say, hypothetically that 0 = (4 2 1): That is, the part-worth utility for dark chocolate is 4, the part-
worth utility for soft center is -2, and the part-worth utility for nuts is 1. The utility for each of the combinations,
xi , would be as follows.
P
=1 exp(x ), is exp(0) + exp(1) + exp( 2) + exp( 1) +
m
The denominator of the probability formula, j j
exp(4) + exp(5)
P + exp(2) + exp(3) = 234 :707. The probability that each alternative is chosen,
exp(x )= =1 exp(x ), is
i
m
j j
This plot shows the function exp( 2) to exp(5), scaled into the range zero to one, the range of probability values.
For the small negative utilities, the probability of choice is essentially zero. As utility increases beyond two, the
function starts rapidly increasing.
In this example, the chosen alternatives are x5 , x6 , x7 , x5 , x2 , x6 , x2 , x6 , x6 , x6 . Alternative x2 was chosen 2
times, x5 was chosen 2 times, x6 was chosen 5 times, and x7 was chosen 1 time. The choice model likelihood
for these data is the product of ten terms, one for each choice set for each subject. Each term consists of the
probability that the chosen alternative is chosen. For each choice set, the utilities for all of the alternatives enter
into the denominator, and the utility for the chosen alternative enters into the numerator. The choice model
likelihood for these data is
hP exp(x6 ) i hP exp(x6 ) i
=1 exp(x ) =1 exp(x )
8 8
j j j j
data chocs;
input Subj c Dark Soft Nuts @@;
Set = 1;
datalines;
1 2 0 0 0 1 2 0 0 1 1 2 0 1 0 1 2 0 1 1
1 1 1 0 0 1 2 1 0 1 1 2 1 1 0 1 2 1 1 1
2 2 0 0 0 2 2 0 0 1 2 2 0 1 0 2 2 0 1 1
2 2 1 0 0 2 1 1 0 1 2 2 1 1 0 2 2 1 1 1
3 2 0 0 0 3 2 0 0 1 3 2 0 1 0 3 2 0 1 1
3 2 1 0 0 3 2 1 0 1 3 1 1 1 0 3 2 1 1 1
4 2 0 0 0 4 2 0 0 1 4 2 0 1 0 4 2 0 1 1
4 1 1 0 0 4 2 1 0 1 4 2 1 1 0 4 2 1 1 1
5 2 0 0 0 5 1 0 0 1 5 2 0 1 0 5 2 0 1 1
5 2 1 0 0 5 2 1 0 1 5 2 1 1 0 5 2 1 1 1
6 2 0 0 0 6 2 0 0 1 6 2 0 1 0 6 2 0 1 1
6 2 1 0 0 6 1 1 0 1 6 2 1 1 0 6 2 1 1 1
7 2 0 0 0 7 1 0 0 1 7 2 0 1 0 7 2 0 1 1
7 2 1 0 0 7 2 1 0 1 7 2 1 1 0 7 2 1 1 1
8 2 0 0 0 8 2 0 0 1 8 2 0 1 0 8 2 0 1 1
8 2 1 0 0 8 1 1 0 1 8 2 1 1 0 8 2 1 1 1
9 2 0 0 0 9 2 0 0 1 9 2 0 1 0 9 2 0 1 1
9 2 1 0 0 9 1 1 0 1 9 2 1 1 0 9 2 1 1 1
10 2 0 0 0 10 2 0 0 1 10 2 0 1 0 10 2 0 1 1
10 2 1 0 0 10 1 1 0 1 10 2 1 1 0 10 2 1 1 1
;
proc print data=chocs noobs;
where subj <= 2;
var subj set c dark soft nuts;
run;
1 1 2 0 0 0
1 1 2 0 0 1
1 1 2 0 1 0
1 1 2 0 1 1
1 1 1 1 0 0
1 1 2 1 0 1
1 1 2 1 1 0
1 1 2 1 1 1
2 1 2 0 0 0
2 1 2 0 0 1
2 1 2 0 1 0
2 1 2 0 1 1
2 1 2 1 0 0
2 1 1 1 0 1
2 1 2 1 1 0
2 1 2 1 1 1
Candy Example 87
These next steps illustrate a more typical form of data entry. The experimental design is stored in a separate data
set from the choices and is merged with the choices as the data are read, which produces the same results as the
preceding steps.
title ’Choice of Chocolate Candies’;
those who survive past the end of a medical experiment) are censored. The exact event time is not known, but
it is known to have occurred after the censored time. In a discrete choice study, first choice occurs at time one,
and all subsequent choices (second choice, third choice, and so on) are unobserved or censored. The survival and
choice models are the same. To fit the multinomial logit model, use PROC PHREG as follows.
proc phreg data=chocs outest=betas;
strata subj set;
model c*c(2) = dark soft nuts / ties=breslow;
label dark = ’Dark Chocolate’ soft = ’Soft Center’
nuts = ’With Nuts’;
run;
The data= option specifies the input data set. The outest= option requests an output data set called BETAS
with the parameter estimates. The strata statement specifies that each combination of the variables Set and
Subj forms a set from which a choice was made. Each term in the likelihood function is a stratum. There is
one term or stratum per choice set per subject, and each is composed of information about the chosen and all the
unchosen alternatives.
In the left side of the model statement, you specify the variables that indicate which alternatives were chosen
and unchosen. While this could be two different variables, we will use one variable c to provide both pieces of in-
formation. The response variable c has values 1 (chosen or first choice) and 2 (unchosen or subsequent choices).
The first c of the c*c(2) in the model statement specifies that c indicates which alternative was chosen. The
second c specifies that c indicates which alternatives were not chosen, and (2) means that observations with
values of 2 were not chosen. When c is set up such that 1 indicates the chosen alternative and 2 indicates the un-
chosen alternatives, always specify c*c(2) on the left of the equal sign in the model statement. The attribute
variables are specified after the equal sign. Specify ties=breslow after a slash to explicitly specify the like-
lihood function for the multinomial logit model. (Do not specify any other ties= options; ties=breslow
specifies the most efficient and always appropriate way to fit the multinomial logit model.) The label statement
is added since we are using a template that assumes each variable has a label.
Note that the c*c(n) syntax allows second choice (c=2) and subsequent choices (c=3, c=4, ...) to be entered.
Just enter in parentheses one plus the number of choices actually made. For example, with first and second choice
data specify c*c(3). Note however that some experts believe that second and subsequent choice data are much
less reliable than first choice data.
Model Information
1 1 1 8 1 7
2 2 1 8 1 7
3 3 1 8 1 7
4 4 1 8 1 7
5 5 1 8 1 7
6 6 1 8 1 7
7 7 1 8 1 7
8 8 1 8 1 7
9 9 1 8 1 7
10 10 1 8 1 7
---------------------------------------------------------------------------
Total 80 10 70
Convergence Status
Without With
Criterion Covariates Covariates
Parameter Standard
DF Estimate Error Chi-Square Pr > ChiSq
The first table, ’Model Information’, contains the input data set name, dependent variable name, censoring infor-
mation, and tie handling option.
The ’Summary of Subjects, Sets, and Chosen and Unchosen Alternatives’ table is printed by default and should
be used to check the data entry. In general, there are as many strata as there are combinations of the Subj
and Set variables. In this case, there are ten strata. Each stratum must be composed of m alternatives. In this
case, there are eight alternatives. The number of chosen alternatives should be 1, and the number of unchosen
alternatives is m 1 (in this case 7). Always check the summary table to ensure that the data are arrayed
correctly.
90 TS-677E Multinomial Logit, Discrete Choice Modeling
The next table, ’Convergence Status’, shows that the iterative algorithm successfully converged. The next tables,
’Model Fit Statistics’ and ’Testing Global Null Hypothesis: BETA=0’ contain the overall fit of the model. The -2
LOG L statistic under ’With Covariates’ is 28.727 and the Chi-Square statistic is 12.8618 with 3 df (p=0.0049),
which is used to test the null hypothesis that the attributes do not influence choice. At common alpha levels
such as 0.05 and 0.01, we would reject the null hypothesis of no relationship between choice and the attributes.
Note that 41.589 (-2 LOG L Without Covariates, which is -2 LOG L for a model with no explanatory variables)
minus 28.727 (-2 LOG L With Covariates, which is -2 LOG L for a model with all explanatory variables) equals
12.8618 (Model Chi-Square, which is used to test the effects of the explanatory variables).
Next is the ’Multinomial Logit Parameter Estimates’ table. For each effect, it contains the maximum likelihood
parameter estimate, its estimated standard error (the square root of the corresponding diagonal element of the
estimated covariance matrix), the Wald Chi-Square statistic (the square of the parameter estimate divided by its
standard error), the df of the Wald Chi-Square statistic (1 unless the corresponding parameter is redundant or
infinite, in which case the value is 0), and the p-value of the Chi-Squared statistic with respect to a chi-squared
distribution with one df. The parameter estimate with the smallest p-value is for soft center. Since the parameter
estimate is negative, chewy is the more preferred level. Dark is preferred over milk, and nuts over no nuts,
however only the p-value for Soft is less than 0.05.
Model Information
1 1 1 8 1 7
2 2 1 8 1 7
3 3 1 8 1 7
4 4 1 8 1 7
5 5 1 8 1 7
6 6 1 8 1 7
7 7 1 8 1 7
8 8 1 8 1 7
9 9 1 8 1 7
10 10 1 8 1 7
---------------------------------------------------------------------------
Total 80 10 70
Convergence Status
Without With
Criterion Covariates Covariates
Parameter Standard
DF Estimate Error Chi-Square Pr > ChiSq
Now the zero coefficients for the reference levels, milk, chewy, and no nuts are printed. The part-worth utility for
Milk Chocolate is a structural zero, and the part-worth utility for Dark Chocolate is larger at 1.38629. Similarly,
the part-worth utility for Chewy Center is a structural zero, and the part-worth utility for Soft Center is smaller
at -2.19722. Finally, the part-worth utility for No Nuts is a structural zero, and the part-worth utility for Nuts is
larger at 0.84730.
92 TS-677E Multinomial Logit, Discrete Choice Modeling
Probability of Choice
The parameter estimates are used next to construct the estimated probability that each alternative will be chosen.
The DATA step program uses the following formula to create the choice probabilities.
p(c jC ) = P
exp(x ) i
=1 exp(x )
i m
j j
data p;
retain sum 0;
set combos end=eof;
* On the first pass through the DATA step (_n_ is the pass
number), get the regression coefficients in B1-B3.
Note that they are automatically retained so that they
can be used in all passes through the DATA step.;
if _n_ = 1 then
set betas(rename=(dark=b1 soft=b2 nuts=b3));
keep dark soft nuts p;
array x[3] dark soft nuts;
array b[3] b1-b3;
* For each combination, create x * b;
p = 0;
do j = 1 to 3;
p = p + x[j] * b[j];
end;
* Exponentiate x * b and sum them up;
p = exp(p);
sum = sum + p;
proc format;
value df 1 = ’Dark’ 0 = ’Milk’;
value sf 1 = ’Soft’ 0 = ’Chewy’;
value nf 1 = ’Nuts’ 0 = ’No Nuts’;
run;
* Divide each exp(x * b) by sum exp(x * b);
data p;
set p;
p = p / (&sum);
format dark df. soft sf. nuts nf.;
run;
proc sort;
by descending p;
run;
proc print;
run;
Candy Example 93
The three most preferred alternatives are Dark/Chewy/Nuts, Dark/Chewy/No Nuts, and Milk/Chewy/Nuts.
94 TS-677E Multinomial Logit, Discrete Choice Modeling
Set Up
The study involves four fictitious fabric softeners Sploosh, Plumbbob, Platter, and Moosey. Each choice set
consists of each of these four brands and a constant alternative Another. Each of the brands is available at three
prices, $1.49, $1.99, and $2.49. Another is only offered at $1.99. There are 50 subjects, each of which will see
the same choice sets. We can use the %MktRuns autocall macro to help us choose the number of choice sets. All
of the autocall macros used in this report are documented starting on page 287. To use this macro, you specify
the number of levels for each of the factors. With four brands each with three prices, you specify four 3’s (or
3 ** 4).
title ’Choice of Fabric Softener’;
%mktruns( 3 3 3 3 )
The output first tells us that we specified a design with four factors, each with three levels. The next table reports
the size of the saturated design, which is the number of parameters in the linear design, and suggests design sizes.
Design Summary
Number of
Levels Frequency
3 4
Saturated = 9
Full Factorial = 81
9 * 0
18 * 0
12 6 9
15 6 9
10 10 3 9
11 10 3 9
13 10 3 9
14 10 3 9
16 10 3 9
17 10 3 9
n Design Reference
9 3 ** 4 Fractional-factorial
18 2 ** 1 3 ** 7 Taguchi, 1987
18 3 ** 6 6 ** 1 Taguchi, 1987
The output from this macro tells us that the saturated design has nine runs and the full-factorial design has 81
runs. It also tells us that 9 and 18 are optimal design sizes with zero violations. The macro tells us that in nine
runs, an orthogonal design with 4 three-level factors is available, and in 18 runs, two orthogonal and balanced
designs are available: one with a two-level factor and 7 three-level factors, and one with 6 three-level factors
and a six-level factor. There are zero violations with these designs because these sizes can be divided by 3 and
3 3 = 9. Twelve and 15 are also reported as potential design sizes, but each has 6 violations. Six times
(the 4(4 1)=2 = 6 pairs of the four threes) 12 and 15 cannot be divided by 3 3 = 9. Ideally, we would
like to have a manageable number of choice sets for people to evaluate and a design that is both orthogonal and
balanced. When violations are reported, orthogonal and balanced designs are not possible. While orthogonality
and balance are not required, they are nice properties to have. With 4 three-level factors, the number of choice
sets in all orthogonal and balanced designs must be divisible by 3 3 = 9.
Nine choice sets is a bit small. Furthermore, there are no error df. We set the number of choice sets to 18 since it
is small enough for each person to see all choice sets, large enough to have reasonable error df, and an orthogonal
and balanced design is available. It is important to remember however that the concept of number of parameters
and error df discussed here applies to the linear design and not to the choice design. We could use the nine-run
design for a discrete choice model and have error df in the choice model. If we were to instead use this design
for a full-profile conjoint (not recommended), there would be no error df.
To make the code easier to modify for future use, the number of choice sets and alternatives are stored in macro
variables and the prices are put into a format. Our design, in raw form, will have values for price of 1, 2, and
3. We will use a format to assign the actual prices: $1.49, $1.99, and $2.49. The format also creates a price of
$1.99 for missing, which will be used for the constant alternative.
%let n = 18; /* n choice sets */
%let m = 5; /* m alternative including constant */
%let mm1 = %eval(&m - 1); /* m - 1 */
The syntax ’n m’ means m factors each at n levels. This example has four factors, x1 through x4, all with
three levels. A design with 18 runs is requested. The n= option specifies the number of runs. These are all the
options that are needed for a simple problem such as this one. However, throughout this report, random number
seeds are explicitly specified with the seed= option so that the results will be reproducible. Here is the macro
By specifying a random number seed, results should be reproducible within a SAS release for a particular operating system. However,
due to machine differences, some results may not be exactly reproducible on other machines. For most orthogonal and balanced designs,
the results should be reproducible. When computerized searches are done, it is likely that you will not get the same design as the one in the
book, although you would expect the efficiency differences to be slight.
96 TS-677E Multinomial Logit, Discrete Choice Modeling
Current Best
Design Row,Col D-Efficiency D-Efficiency Notes
----------------------------------------------------------
1 Start 100.0000 100.0000 Tab
1 End 100.0000
x1 3 1 2 3
x2 3 1 2 3
x3 3 1 2 3
x4 3 1 2 3
Average
Prediction
Design Standard
Number D-Efficiency A-Efficiency G-Efficiency Error
------------------------------------------------------------------------
1 100.0000 100.0000 100.0000 0.7071 p
Obs x1 x2 x3 x4
1 1 1 1 1
2 1 1 2 3
3 1 2 1 3
4 1 2 3 2
5 1 3 2 2
6 1 3 3 1
7 2 1 1 2
8 2 1 3 3
9 2 2 2 2
Fabric Softener Example 97
10 2 2 3 1
11 2 3 1 3
12 2 3 2 1
13 3 1 2 1
14 3 1 3 2
15 3 2 1 1
16 3 2 2 3
17 3 3 1 2
18 3 3 3 3
The macro found a perfect, orthogonal and balanced, 100% efficient design consisting of 4 three-level factors,
x1-x4. The levels are the integers 1 to 3. For this problem, the macro generated the design directly. For other
problems, the macro may have to use a computerized search. See page 123 for more information on how the
%MktEx macro works.
x1 x2 x3 x4
x1 1 0 0 0
x2 0 1 0 0
x3 0 0 1 0
x4 0 0 0 1
Frequencies
x1 6 6 6
x2 6 6 6
x3 6 6 6
x4 6 6 6
x1 x2 2 2 2 2 2 2 2 2 2
x1 x3 2 2 2 2 2 2 2 2 2
x1 x4 2 2 2 2 2 2 2 2 2
x2 x3 2 2 2 2 2 2 2 2 2
x2 x4 2 2 2 2 2 2 2 2 2
x3 x4 2 2 2 2 2 2 2 2 2
N-Way 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
98 TS-677E Multinomial Logit, Discrete Choice Modeling
The first table shows the canonical correlations between pairs of coded factors. A canonical correlation is the
maximum correlation between linear combinations of the coded factors. All zeros off the diagonal show that
this design is orthogonal for main effects. If any off-diagonal canonical correlations had been greater than 0.316
(r2 > 0:1), the macro would have listed them in a separate table. The last title line tells you that none of them
was this large. For nonorthogonal designs and designs with interactions, the canonical-correlation matrix is not
a substitute for looking at the variance matrix (with examine=v, discussed on pages 126, 162, and 336). It
just provides a quick and more-compact picture of the correlations between the factors. The variance matrix is
sensitive to the actual model specified and the coding. The canonical-correlation matrix just tells you if there is
some correlation between the main effects. In this case, there are no correlations.
The macro also prints one-way, two-way and n-way frequencies. The equal one-way frequencies show you that
this design is balanced. The equal two-way frequencies show you that this design is orthogonal. The n-way
frequencies, all equal to one, show you that there are no duplicate profiles. This is a perfect design for a main-
effects model. However, there are other 100% efficient designs for this problem with duplicate observations.
In the last part of the output, the N-Way frequencies may contain some 2’s for those designs. You can specify
options=nodups to ensure that there are no duplicates.
The %MktEval macro produces a very compact summary of the design, hence some information, for example
the levels to which the frequencies correspond, is not shown. You can use the print=freqs option to get a
less compact and more detailed display.
%mkteval(data=design, print=freqs);
Effects Frequency x1 x2 x3 x4
x1 6 1 . . .
6 2 . . .
6 3 . . .
x2 6 . 1 . .
6 . 2 . .
6 . 3 . .
.
.
.
x1 x2 2 1 1 . .
2 1 2 . .
2 1 3 . .
2 2 1 . .
2 2 2 . .
2 2 3 . .
2 3 1 . .
2 3 2 . .
2 3 3 . .
.
.
.
Fabric Softener Example 99
x3 x4 2 . . 1 1
2 . . 1 2
2 . . 1 3
2 . . 2 1
2 . . 2 2
2 . . 2 3
2 . . 3 1
2 . . 3 2
2 . . 3 3
N-Way 1 1 1 1 1
1 1 1 2 3
1 1 2 1 3
1 1 2 3 2
1 1 3 2 2
1 1 3 3 1
1 2 1 1 2
1 2 1 3 3
1 2 2 2 2
1 2 2 3 1
1 2 3 1 3
1 2 3 2 1
1 3 1 2 1
1 3 1 3 2
1 3 2 1 1
1 3 2 2 3
1 3 3 1 2
1 3 3 3 3
title2;
Subject: _________
In practice, data collection may be much more elaborate than this. It may involve art work, photographs, and the
choice sets may be presented and data may be collected over the web. However the choice sets are presented and
the data are collected, the essential ingredients remain the same. Subjects are shown sets of alternatives and are
asked to make a choice, then they go on to the next set.
Here is how the KEY data set is created. The Brand factor levels and the Price linear design factors are stored
in the KEY data set.
title2 ’Key Data Set’;
data key;
input Brand $ Price $;
datalines;
Sploosh x1
Plumbbob x2
Platter x3
Moosey x4
Another .
;
title2;
1 Sploosh x1
2 Plumbbob x2
3 Platter x3
4 Moosey x4
5 Another
Note that the value of Price for alternative Another in the KEY data set is blank (character missing). The period
in the in-stream data set is simply a placeholder, used with list input to read both character and numeric missing
data. A period is not stored with the data. Next, we use the %MktRoll macro to process the design.
%mktroll(design=[Link], key=key, alt=brand, out=rolled)
The %MktRoll step processes the design=[Link] linear design data set using the rules specified in
the key=key data set, naming the alt=brand variable as the alternative name variable, and creating an output
SAS data set called ROLLED, which contains the choice design. The input design=[Link] data set
has 18 observations, one per choice set, and the output out=rolled data set has 5 18 = 90 observations,
one for each alternative of each choice set. Here are the first three observations of the linear design data set.
title2 ’Linear Design (First 3 Sets)’;
title2;
Obs x1 x2 x3 x4
These observations define the first three choice sets. Here are those same observations, arrayed for analysis in
the choice design data set.
title2 ’Choice Design (First 3 Sets)’;
title2;
1 1 Sploosh $2.49
2 1 Plumbbob $1.99
3 1 Platter $1.99
4 1 Moosey $2.49
5 1 Another $1.99
6 2 Sploosh $1.49
7 2 Plumbbob $2.49
8 2 Platter $1.99
9 2 Moosey $1.99
10 2 Another $1.99
11 3 Sploosh $1.49
12 3 Plumbbob $1.99
13 3 Platter $1.99
14 3 Moosey $1.49
15 3 Another $1.99
The choice design data set has a choice set variable Set, an alternative name variable Brand, and a price
variable Price. The prices come from the linear design, and the price for Another is a constant $1.99. Recall
that the prices are assigned by the following format.
proc format; /* create a format for the price */
value price 1 = ’$1.49’ 2 = ’$1.99’ 3 = ’$2.49’ . = ’$1.99’;
run;
The next step merges the choice data with the choice design using the %MktMerge macro.
%mktmerge(design=rolled, data=results, out=res2,
nsets=&n, nalts=&m, setvars=choose1-choose&n)
This step reads the design=rolled choice design and the data=results data set and creates the
out=res2 output data set. The data are from an experiment with nsets=&n choice sets, nalts=&m al-
ternatives, with variables setvars=choose1-choose&n containing the numbers of the chosen alternatives.
Here are the first 15 observations.
title2 ’Choice Design and Data (First 3 Sets)’;
title2;
Fabric Softener Example 105
1 1 1 Sploosh 3 2
2 1 1 Plumbbob 2 2
3 1 1 Platter 2 1
4 1 1 Moosey 3 2
5 1 1 Another . 2
6 1 2 Sploosh 1 2
7 1 2 Plumbbob 3 2
8 1 2 Platter 2 1
9 1 2 Moosey 2 2
10 1 2 Another . 2
11 1 3 Sploosh 1 2
12 1 3 Plumbbob 2 2
13 1 3 Platter 2 2
14 1 3 Moosey 1 1
15 1 3 Another . 2
The data set contains the subject ID variable Subj from the data=results data set, the Set, Brand, and
Price variables from the design=rolled data set, and the variable c, which indicates which alternative was
chosen. The variable c indicates the chosen alternatives: 1 for first choice and 2 for second or subsequent choice.
This subject chose the third alternative, Platter, for each of the first two choice sets, and Moosey for the third.
This data set has 4500 observations: 50 subjects times 18 choice sets times 5 alternatives.
Since we did not specify a format, we see in the design the raw design values for Price: 1, 2, 3 and missing
for the constant alternative. If we were going to treat Price as a categorical variable for analysis, this would
be fine. We would simply assign our price format to Price and designate it as a class variable. However, in
this analysis we are going to treat price as quantitative and use the actual prices in the analysis. Hence, we must
convert our design values of 1, 2, 3, and . to 1.49, 1.99, 2.49, and 1.99. We cannot do this by simply assigning
a format. Formats create character strings that are printed in place of the original value. We need to convert a
numeric variable from one set of numbers to another. We could use if and assignment statements. We could
also use the %MktLab macro, which is used in later examples. However, instead we will use the put function
to write the formatted value into a character string, then we read it back using a dollar format and the input
function. For example, the expression put(price, price.) converts a number, say 2, into a string (in this
case ’$1.99’), then the input function reads the string and converts it to a numeric 1.99. This step also assigns
a label to the variable Price.
data res3; /* Create a numeric actual price */
set res2;
price = input(put(price, price.), dollar5.);
label price = ’Price’;
run;
Binary Coding
One more thing must be done to these data before they can be analyzed. A binary or zero-one design matrix must
be coded for the brand effect. This can be done with PROC TRANSREG.
proc transreg design=5000 data=res3 nozeroconstant norestoremissing;
model class(brand / zero=none order=data)
identity(price) / lprefix=0;
output out=coded(drop=_type_ _name_ intercept);
id subj set c;
run;
106 TS-677E Multinomial Logit, Discrete Choice Modeling
The design option specifies that no model is fit; the procedure is just being used to code a design. When
design is specified, dependent variables are not required. Optionally, design can be followed by “=n” where
n is the number of observations to process at one time. By default, PROC TRANSREG codes all observations
in one big group. For very large data sets, this can consume large amounts of memory and time. Processing
blocks of smaller numbers of observations is more efficient. The option design=5000 processes observations
in blocks of 5000. For smaller computers, try something like design=1000.
The nozeroconstant and norestoremissing options are not necessary for this example but are included
here because sometimes they are very helpful in coding choice models. The nozeroconstant option specifies
that if the coding creates a constant variable, it should not be zeroed. The nozeroconstant option should
always be specified when you specify design=n because the last group of observations may be small and may
contain constant variables. The nozeroconstant option is also important if you do something like coding by
subj set because sometimes an attribute is constant within a choice set. The norestoremissing option
specifies that missing values should not be restored when the out= data set is created. By default, the coded
class variable contains a row of missing values for observations in which the class variable is missing. When
you specify the norestoremissing option, these observations contain a row of zeros instead. This option
is useful when there is a constant alternative indicated by missing values. Both of these options, like almost all
options in PROC TRANSREG, can be abbreviated to three characters (noz and nor).
The model statement names the variables to code and provides information about how they should be coded.
The specification class(brand / ...) specifies that the variable Brand is a classification variable and
requests a binary coding. The zero=none option creates binary variables for all categories. In contrast, by
default, a binary variable is not created for the last category the parameter for the last category is a structural
zero. The zero=none option is used when there are no structural zeros or when you want to see the structural
zeros in the multinomial logit parameter estimates table. The order=data option sorts the levels into the order
they were first encountered in the data set. The specification identity(price) specifies that Price is a
quantitative factor that should be analyzed as is (not expanded into dummy variables).
The lprefix=0 option specifies that when labels are created for the binary variables, zero characters of the
original variable name should be used as a prefix. This means that the labels are created only from the level
values. For example, ’Sploosh’ and ’Plumbbob’ are created as labels not ’Brand Sploosh’ and
’Brand Plumbbob’.
An output statement names the output data set and drops variables that are not needed. These variables do
not have to be dropped. However, since they are variable names that are often found in special data set types,
PROC PHREG prints warnings when it finds them. Dropping the variables prevents the warnings. Finally, the
id statement names the additional variables that we want copied from the input to the output data set. The next
steps print the first three coded choice sets.
proc print data=coded(obs=15) label;
title2 ’First 15 Observations of Analysis Data Set’;
id subj set c;
run;
title2;
1 1 2 1 0 0 0 0 2.49 Sploosh
1 1 2 0 1 0 0 0 1.99 Plumbbob
1 1 1 0 0 1 0 0 1.99 Platter
1 1 2 0 0 0 1 0 2.49 Moosey
1 1 2 0 0 0 0 1 1.99 Another
Fabric Softener Example 107
1 2 2 1 0 0 0 0 1.49 Sploosh
1 2 2 0 1 0 0 0 2.49 Plumbbob
1 2 1 0 0 1 0 0 1.99 Platter
1 2 2 0 0 0 1 0 1.99 Moosey
1 2 2 0 0 0 0 1 1.99 Another
1 3 2 1 0 0 0 0 1.49 Sploosh
1 3 2 0 1 0 0 0 1.99 Plumbbob
1 3 2 0 0 1 0 0 1.99 Platter
1 3 1 0 0 0 1 0 1.49 Moosey
1 3 2 0 0 0 0 1 1.99 Another
title2;
The brief option requests a brief summary for the strata. As with the candy example, c*c(2) designates the
chosen and unchosen alternatives in the model statement. We specify the &- trgind macro variable for the
model statement independent variable list. PROC TRANSREG automatically creates this macro variable. It
contains the list of coded independent variables generated by the procedure. This is so you do not have to figure
out what names TRANSREG created and specify them. In this case, PROC TRANSREG sets &- trgind to
contain the following list.
BrandSploosh BrandPlumbbob BrandPlatter BrandMoosey BrandAnother Price
The ties=breslow option specifies a PROC PHREG model that has the same likelihood as the multinomial
logit model for discrete choice. The strata statement specifies that the combinations of Set and Subj indicate
the choice sets. This data set has 4500 observations consisting of 18 50 = 900 strata and five observations per
stratum.
Each subject rated 18 choice sets, but the multinomial logit model assumes each stratum is independent. That
is, the multinomial logit model assumes each person makes only one choice. The option of collecting only one
datum from each subject is too expensive to consider for many problems, so multiple choices are collected from
each subject, and the repeated measures aspect of the problem is ignored. This practice is typical, and it usually
works well.
Model Information
1 900 5 1 4
Convergence Status
Without With
Criterion Covariates Covariates
Parameter Standard
DF Estimate Error Chi-Square Pr > ChiSq
The procedure output begins with information about the data set, variables, and options. This is followed by
information about the 900 strata. Since the brief option was specified, this table contains one row for each
stratum pattern. In contrast, the default table would have 900 rows, one for each choice set and subject com-
bination. Each subject and choice set combination consists of a total of five observations, one that was chosen
and four that were not chosen. This pattern was observed 900 times. This table provides a check on data entry.
Unless we have an availability or allocation study (page 226) or a nonconstant number of alternatives in different
choice sets, we would expect to see one pattern of results where one of the m alternatives was chosen for each
choice set. If you do not observe this for a study like this, there was probably a mistake in the data entry or
processing.
The most to least preferred brands are: Platter, Moosey, Another, Plumbbob, and Sploosh. Increases in
price have a negative utility. For example, the predicted utility of Platter brand at $1.99 is xi which is
(0 0 1 0 0 $1:99) ( 1:11 0:16 1:95 0:79 0 4:26)0 = 1:95 + 1:99 4:26 = 6:53.
Since Price was analyzed as a quantitative factor, we can see for example that the utility of Platter at $1.89,
which was not in any choice set, is 1:95 + 1:89 4:26 = 6:10, which is a $0:10 4:26 = 0:43 increase in
utility.
Probability of Choice
These next steps compute the expected probability that each alternative is chosen within each choice set. This
code could easily be modified to compute expected market share for hypothetical marketplaces that do not di-
rectly correspond to the choice sets. Note however, that a term like “expected market share,” while widely used,
is a misnomer. Without purchase volume data, it is unlikely that these numbers would mirror true market share.
First, PROC SCORE is used to compute the predicted utility for each alternative.
proc score data=coded(where=(subj=1) drop=c)
score=betas type=parms out=p;
var &_trgind;
run;
The data set to be scored is named with the data= option, and the coefficients are specified in the option
score=beta. Note that we only need to read all of the choice sets once, since the parameter estimates were
computed in an aggregate analysis. This is why we specified where=(subj=1). We do not need xj ^ for each
of the different subjects. We dropped the variable c from the CODED data set since this name will be used by
PROC SCORE for the results (xj ^ ). The option type=parms specifies that the score= data set contains the
parameters in - TYPE- = ’PARMS’ observations. The output data set with the predicted utilities is named
P. Scoring is based on the coded variables from PROC TRANSREG, whose names are contained in the macro
variable &- trgind. The next step exponentiates xj ^ .
data p2;
set p;
p = exp(c);
run;
Here are the results for the first three choice sets.
proc print data=p(obs=15);
title2 ’Choice Probabilities for the First 3 Choice Sets’;
run;
title2;
Custom Questionnaires
In this part of the example, a custom questionnaire is printed for each person. Previously, each subject saw the
same questionnaire, with the same choice sets, each containing the same alternatives, with everything in the same
order. In this example, the order of the choice sets and all alternatives within choice sets are randomized for each
subject. Randomizing avoids any systematic effects due to the order of the alternatives and choice sets. The
constant alternative is always printed last. If you have no interest in custom questionnaires, you can skip ahead
to page 116.
First, the macro variable &forms is created. It contains the number of separate questionnaires (or forms or
subjects, in this case 50). We can use the %MktEx macro to create a data set with one observation for each
alternative of each choice set for each person. The specification %mktex(&forms &n &mm1, n=&forms
* &n * &mm1) is %mktex(50 18 4, n=50 * 18 * 4) and creates a 50 18 4 full-factorial design.
Note that the n= specification allows expressions. The macro %MktLab is then used to assign the variable names
Form, Set, and Alt instead of the default x1 - x3. The data set is sorted by Form. Within Form, the choice
sets are sorted into a random order, and within choice set, the alternatives are sorted into a random order. The 72
observations for each choice set contain 18 blocks of 4 observations one block per choice set in a random order
and the 4 alternatives within each choice set, again in a random order. Note that we store these in a permanent
SAS data set so they will be available after the data are collected.
Fabric Softener Example 111
*---Random Sort---;
proc sort out=[Link](drop=r:); by form r1 r2; run;
proc print data=[Link](obs=16); run;
1 1 4 4
2 1 4 2
3 1 4 3
4 1 4 1
5 1 8 4
6 1 8 2
7 1 8 1
8 1 8 3
9 1 7 4
10 1 7 3
11 1 7 2
12 1 7 1
13 1 14 4
14 1 14 1
15 1 14 3
16 1 14 2
112 TS-677E Multinomial Logit, Discrete Choice Modeling
The data set is transposed, so the resulting data set contains 50 18 = 900 observations, one per subject per
choice set. The alternatives are in the variables Col1-Col4. The first 18 observations, which contain the
ordering of the choice sets for the first subject, are shown next.
proc transpose data=[Link] out=[Link](drop=_name_);
by form notsorted set;
run;
proc print data=[Link](obs=18);
run;
1 1 4 4 2 3 1
2 1 8 4 2 1 3
3 1 7 4 3 2 1
4 1 14 4 1 3 2
5 1 9 2 1 4 3
6 1 11 4 1 2 3
7 1 17 3 2 4 1
8 1 1 4 1 2 3
9 1 12 1 3 2 4
10 1 13 2 1 4 3
11 1 18 3 1 4 2
12 1 3 3 1 4 2
13 1 2 3 4 2 1
14 1 5 3 4 1 2
15 1 15 1 3 4 2
16 1 6 3 2 1 4
17 1 16 2 1 4 3
18 1 10 4 1 3 2
data _null_;
array brands[&mm1] $ _temporary_
(’Sploosh’ ’Plumbbob’ ’Platter’ ’Moosey’);
array x[&mm1] x1-x&mm1;
array c[&mm1] col1-col&mm1;
format x1-x&mm1 price.;
file print linesleft=ll;
Fabric Softener Example 113
do frms = 1 to &forms;
do choice = 1 to &n;
if choice = 1 or ll < 12 then do;
put _page_;
put @60 ’Subject: ’ frms //;
end;
put choice 2. ’) Circle your choice of ’
’one of the following fabric softeners:’ /;
set [Link];
set [Link] point=set;
do brnds = 1 to &mm1;
put ’ ’ brnds 1. ’) ’ brands[c[brnds]] ’brand at ’
x[c[brnds]] +(-1) ’.’ /;
end;
put ’ 5) Another brand at $1.99.’ /;
end;
end;
stop;
run;
The loop do frms = 1 to &forms creates the 50 questionnaires. The loop do choice = 1 to &n
creates the alternatives within each choice set. On the first choice set and when there is not enough room
for the next choice set, we skip to a new page (put - page- ) and print the subject (forms) number. The
data set [Link] is read and the Set variable is used to read the relevant observation from
[Link] using the point= option in the set statement. The order of the alternatives is in the
c array and variables col1-col&mm1 from the [Link] data set. In the first observation of
[Link], Set=16, Col1=2, Col2=3, Col3=1, and Col4=4. The first brand, is c[brnds] =
c[1] = col1 = 2, so brands[c[brnds]] = brands[c[1]] = brands[2] = ’Plumbbob’,
and the price, from observation Set=16 of [Link], is x[c[brnds]] = x[2] = $1.99. The
second brand, is c[brnds] = c[2] = col2 = 3, so brands[c[brnds]] = brands[c[2]] =
brands[3] = ’Platter’, and the price, from observation Set=16 of [Link], is x[c[brnds]]
= x[3] = $1.49.
In the interest of space, only the first two choice sets are printed. Note that the subject number is printed on the
form. This information is needed to restore all data to the original order.
Subject: 1
proc sort;
by subj set;
run;
Fabric Softener Example 115
The actual choice number, stored in Choose, indexes the alternative numbers from [Link] to
restore the original alternative orders. For example, for the first subject, the first choice was 5, which is the
Another alternative. The second choice was 3. The data set [Link] shows in the second observation
that this choice of 3 corresponds to the first alternative (in the third column variable, Col3 = 1) of choice set
Set= 8. This DATA step writes out the data after the original order has been restored. It matches the data on
page 102.
data _null_;
set res3;
by subj;
if [Link] then do;
if mod(subj, 3) eq 1 then put;
put subj 4. +1 @@;
end;
put choose 1. @@;
run;
The data can be combined with the design and analyzed as in the previous example.
116 TS-677E Multinomial Logit, Discrete Choice Modeling
Vacation Example
This example illustrates the design and analysis for a larger problem. We will discuss designing a choice experi-
ment, evaluating the design, generating the questionnaire, processing the data, binary coding, generic attributes,
quantitative price effects, quadratic price effects, effects coding, alternative-specific effects, analysis, and inter-
pretation of the results.
A researcher is interested in studying choice of vacation destinations. There are five destinations (alternatives)
of interest: Hawaii, Alaska, Mexico, California, and Maine. Here are two summaries of the design, with factors
grouped by attribute and grouped by destination.
Each alternative is composed of three factors: package cost ($999, $1,249, $1,499), scenery (mountains, lake,
beach), and accommodations (cabin, bed & breakfast, and hotel). There are five destinations, each with three
attributes, for a total of 15 factors. This problem requires a design with 15 three-level factors, denoted 315 . Each
row of the design matrix contains the description of the five alternatives in one choice set. Note that the levels do
not have to be the same for all destinations. For example, the cost for Hawaii and Alaska could be different from
the other destinations. However, for this example, each destination will have the same attributes.
Set Up
We can use the %MktRuns autocall macro to suggest design sizes. (All of the autocall macros used in this report
are documented starting on page 287.) To use this macro, you specify the number of levels for each of the factors.
With 15 attributes each with three prices, you specify fifteen 3’s (3 3 3 3 3 3 3 3 3 3 3 3 3 3 3) or
you can use the more compact syntax of 3 ** 15.
title ’Vacation Example’;
%mktruns( 3 ** 15 )
The output tells us the size of the saturated design, which is the number of parameters in the linear design, and
suggests design sizes.
Vacation Example
Design Summary
Number of
Levels Frequency
3 15
Vacation Example
Saturated = 31
Full Factorial = 14,348,907
36 0
45 0
54 * 0
63 0
72 * 0
33 105 9
39 105 9
42 105 9
48 105 9
51 105 9
Vacation Example
n Design Reference
54 2 ** 1 3 ** 25 Taguchi, 1987
54 3 ** 24 6 ** 1 Hedayat, Sloane, and Stufken, 1999
54 3 ** 18 18 ** 1 Hedayat, Sloane, and Stufken, 1999
118 TS-677E Multinomial Logit, Discrete Choice Modeling
72 2 ** 23 3 ** 24 Dey, 1985
72 2 ** 20 3 ** 24 4 ** 1 Wang, 1996
72 2 ** 16 3 ** 25 Wang, 1996
72 2 ** 14 3 ** 24 6 ** 1 Wang, 1996
72 2 ** 13 3 ** 25 4 ** 1 Wang, 1996
72 2 ** 12 3 ** 24 12 ** 1 Hedayat, Sloane, and Stufken, 1999
72 2 ** 11 3 ** 24 4 ** 1 6 ** 1 Wang, 1996
72 3 ** 25 8 ** 1 Hedayat, Sloane, and Stufken, 1999
72 3 ** 24 24 ** 1 Hedayat, Sloane, and Stufken, 1999
In this design, there are 15 (3 1) + 1 = 31 parameters, so at least 31 choice sets must be created. With
all three-level factors, the number of choice sets in all orthogonal and balanced designs must be divisible by
3 3 = 9. Hence, optimal designs for this problem have at least 36 choice sets (the smallest number 31 and
divisible by 9) and the number of choice sets must be a multiple of 9. Note however, that zero violations does
not imply that a 100% efficient design exists. It just means that 100% efficiency is not precluded by unequal
frequencies. In fact. the %MktEx orthogonal design catalogue does not include orthogonal designs for this
problem in 36, 45, and 63 runs (because they do not exist).
Thirty-six would be a good design size (2 blocks of size 18) as would 54 (3 blocks of size 18). Fifty-four would
probably be the best choice, and that is what we would recommend for this study. However, we will instead
create an efficient experimental design with 36 choice sets using the %MktEx macro. In practice, with more
difficult designs, an orthogonal design is not available, and using 36 choice sets will allow us to see an example
of using the %mkt family of macros to get nonorthogonal designs.
We can see what orthogonal designs with three-level factors are available in 36 runs as follows. The macro
%MktOrth creates a data set with information about the orthogonal designs that the %MktEx macro knows how
to make. This macro produces a data set called MKTDESLEV that contains variables n, the number of runs;
Design, a description of the design; and Reference, one of the (sometimes many) references for the design.
In addition, there are variables: x1, the number of 1-level factors (which is always zero); x2, the number of
2-level factors; x3, the number of 3-level factors; and so on. We can sort this data set, excluding all but the
36-run designs, such that designs with the most three-level factors are printed first.
%mktorth;
Vacation Example
1 36 2 ** 4 3 ** 13 Taguchi, 1987
2 36 3 ** 13 4 ** 1 Dey, 1985
3 36 2 ** 11 3 ** 12 Taguchi, 1987
4 36 2 ** 2 3 ** 12 6 ** 1 Wang and Wu, 1991
5 36 3 ** 12 12 ** 1 Wang and Wu, 1991
6 36 2 ** 1 3 ** 8 6 ** 2 Zhang, Lu, and Pang, 1999
7 36 3 ** 7 6 ** 3 Finney, 1982
8 36 2 ** 13 3 ** 4 Suen, 1989
9 36 2 ** 4 3 ** 3 6 ** 1 Hedayat, Sloane, and Stufken, 1999
10 36 2 ** 20 3 ** 2 Hedayat, Sloane, and Stufken, 1999
11 36 2 ** 11 3 ** 2 6 ** 1 Hedayat, Sloane, and Stufken, 1999
12 36 2 ** 2 3 ** 2 6 ** 2 Hedayat, Sloane, and Stufken, 1999
13 36 2 ** 27 3 ** 1 Hedayat, Sloane, and Stufken, 1999
14 36 2 ** 18 3 ** 1 6 ** 1 Hedayat, Sloane, and Stufken, 1999
15 36 2 ** 9 3 ** 1 6 ** 2 Hedayat, Sloane, and Stufken, 1999
16 36 2 ** 35 Hadamard
17 36 2 ** 13 9 ** 1 Suen, 1989
18 36 2 ** 2 18 ** 1 Hedayat, Sloane, and Stufken, 1999
19 36 2 ** 1 6 ** 3 SAS Procedure OPTEX
There are 13 two-level factors available in 36 runs, and we need 15, so we would expect to make a pretty good
nonorthogonal design.
Vacation Example
Current Best
Design Row,Col D-Efficiency D-Efficiency Notes
----------------------------------------------------------
1 Start 82.2172 82.2172 Can
1 End 82.2172
.
.
.
.
.
.
.
.
.
Vacation Example
Current Best
Design Row,Col D-Efficiency D-Efficiency Notes
----------------------------------------------------------
0 Initial 98.8933 98.8933 Ini
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
Vacation Example
Current Best
Design Row,Col D-Efficiency D-Efficiency Notes
----------------------------------------------------------
0 Initial 98.9438 98.9438 Ini
.
.
.
Vacation Example
x1 3 1 2 3
x2 3 1 2 3
x3 3 1 2 3
x4 3 1 2 3
x5 3 1 2 3
x6 3 1 2 3
x7 3 1 2 3
x8 3 1 2 3
x9 3 1 2 3
x10 3 1 2 3
x11 3 1 2 3
x12 3 1 2 3
x13 3 1 2 3
x14 3 1 2 3
x15 3 1 2 3
Vacation Example
Average
Prediction
Design Standard
Number D-Efficiency A-Efficiency G-Efficiency Error
------------------------------------------------------------------------
1 98.9437 97.9592 98.9743 0.9428
The %MktEx macro used 5.24 minutes and found a design that is almost 99% efficient. (Differences in the fourth
decimal place between the iteration history and the final table, in this case 98.9438 versus 98.9437, are due to
rounding error and differences in ridging strategies between the macro and PROC OPTEX and are nothing to
worry about.)
Vacation Example 123
In the first attempt at coordinate exchange (Design 2), the macro found a design that is 98.0624% efficient
(Design 2, End). In design 3 and subsequent designs, the macro uses this same approach, but different random
initializations of the remaining two columns. In design 5, the %MktEx macro finds a design that is 98.8933%
efficient. Designs 12 through 21 use a purely random initialization and simulated annealing and are not as good
as previous designs. During these iterations, the macro is considering exchanging every level of every factor with
all of the other levels, one level of one factor at a time.
At this point, the %MktEx macro determines that the combination of tabled and random initialization is working
best and tries more iterations using that approach. It starts by printing the initial (Ini) best efficiency of 98.8933.
In designs 43, 62, 84, 124, and 149, it finds a design that is 98.9438% efficient. After iteration 149, the macro
stops since it keeps finding the same design over and over. This does not necessarily mean the macro found the
optimal design; it means it found a very attractive (perhaps local) optimum, and it is unlikely it will do better
using this approach.
Next, the %MktEx macro tries to improve the best design it found previously. Using the previous best design
as an initialization (Pre), and random mutations of the initialization Mut) and simulated annealing (Ann), the
macro uses the coordinate-exchange algorithm to try to find a better design. This step is important because the
best design that the macro found may be an intermediate design and not be the final design at the end of an
iteration. Sometimes the iterations deliberately make the designs less efficient, and sometimes, the macro never
finds a design as efficient or more efficient again. Hence it is worthwhile to see if the best design found so far
can be improved. In this case the macro fails to improve the design. At the end, PROC OPTEX is called to print
the levels of each factor and the final D-efficiency.
Random mutations add random noise to the initial design before iterations start (levels are randomly changed).
This may eliminate the perfect balance that will often be in the initial design. By default, random mutations are
used with designs with fully random initializations and in the design refinement step; orthogonal initial designs
are not mutated.
Simulated annealing allows the design to get worse occasionally but with decreasing probability as the number
of swaps increases. For design 1, for the first level of the first factor, by default, the macro may execute a swap
(say change a 2 to a 1), that makes the design worse, with probability 0.05. As more and more swaps occur,
this probability decreases so at the end of the processing of design 1, swaps that decrease efficiency are hardly
ever done. For design 2, this same process is repeated, again starting by default with an annealing probability of
0.05. This often helps the algorithm overcome local efficiency maxima. To envision, this, imagine that you are
standing on a molehill next to a mountain. The only way you can start going up the mountain is to first step down
off the molehill. Once you are on the mountain, you may occasionally hit a dead end, where all you can do is step
down and look for a better place to continue going up. Simulated annealing, by occasionally stepping down the
efficiency function, often allows the macro to go farther up it than it would otherwise. The simulated annealing is
why you will sometimes see designs getting worse in the iteration history. Recall however, that the macro keeps
track of the best design, not the final design in each step. By default, annealing is used with designs with fully
random initializations and in the design refinement step; simulated annealing is not used with orthogonal initial
designs.
For this example, the %MktEx macro ran in less than 6 minutes. If an orthogonal design had been available, run
time would have been a few seconds. If the fully random initialization method had been the best method, run
time might have been on the order of 20 to 45 minutes. Since the tabled initialization worked best, run time was
on the order of several minutes. While it is possible to construct huge problems that will take much longer, for
any design that most marketing researchers are likely to encounter, run time should be less than one hour. One
of the macro options, maxtime=, ensures this.
x1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
x2 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0
x3 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0
x4 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0
x5 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0
x6 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0
x7 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0
x8 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0
x9 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0
x10 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
x11 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0
x12 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0
x13 0 0 0 0 0 0 0 0 0 0 0 0 1 0.25 0.25 0
x14 0 0 0 0 0 0 0 0 0 0 0 0 0.25 1 0.25 0
x15 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0.25 1 0
x16 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
Vacation Example
Summary of Frequencies
There are 0 Canonical Correlations Greater Than 0.316
* - Indicates Unequal Frequencies
Frequencies
x1 12 12 12
x2 12 12 12
x3 12 12 12
x4 12 12 12
x5 12 12 12
x6 12 12 12
x7 12 12 12
x8 12 12 12
x9 12 12 12
x10 12 12 12
x11 12 12 12
x12 12 12 12
x13 12 12 12
x14 12 12 12
x15 12 12 12
x16 18 18
x1 x2 4 4 4 4 4 4 4 4 4
x1 x3 4 4 4 4 4 4 4 4 4
x1 x4 4 4 4 4 4 4 4 4 4
x1 x5 4 4 4 4 4 4 4 4 4
x1 x6 4 4 4 4 4 4 4 4 4
x1 x7 4 4 4 4 4 4 4 4 4
x1 x8 4 4 4 4 4 4 4 4 4
x1 x9 4 4 4 4 4 4 4 4 4
x1 x10 4 4 4 4 4 4 4 4 4
x1 x11 4 4 4 4 4 4 4 4 4
x1 x12 4 4 4 4 4 4 4 4 4
x1 x13 4 4 4 4 4 4 4 4 4
x1 x14 4 4 4 4 4 4 4 4 4
x1 x14 4 4 4 4 4 4 4 4 4
x1 x15 4 4 4 4 4 4 4 4 4
x1 x16 6 6 6 6 6 6
126 TS-677E Multinomial Logit, Discrete Choice Modeling
.
.
.
* x13 x14 3 6 3 6 3 3 3 3 6
* x13 x15 6 3 3 3 6 3 3 3 6
x13 x16 6 6 6 6 6 6
* x14 x15 3 6 3 6 3 3 3 3 6
x14 x16 6 6 6 6 6 6
x15 x16 6 6 6 6 6 6
N-Way 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
This design looks great! The factors x1-x13 form an orthogonal design, x14 and x15 are slightly correlated
with each other and with x13. The blocking factor x16 is orthogonal to all the other factors. All of the factors
are perfectly balanced. The N-Way frequencies show that each choice set appears once.
What if there had been some larger canonical correlations? Would this be a problem? That depends. You have
to decide this for yourself based on your particular study. You do not want large correlations between your most
important factors. If you have high correlations between the wrong factors, you can swap them with other factors
with the same number of levels, or try to make a new design with a different seed, or change the number of
choice sets, and so on. While this design looks great, we should make one minor adjustment based on these
results. Since our correlations are in the factors we originally planned to make price factors, we should change
our plans slightly and use those factors for less important attributes like scenery.
You can run the %MktEx macro to provide additional information about a design, for example asking to examine
the information matrix (i) and its inverse (v), which is the covariance matrix of the parameter estimates. You
hope to see that all of the off-diagonal elements of the variance matrix, the covariances, are small relative to the
variances on the diagonal. When options=check is specified, the macro evaluates an initial design instead of
generating a design. The option init=randomized names the design to evaluate, and the examine= option
displays the information and variance matrices. The blocking variable was dropped.
%mktex(3 ** 15, n=&n * &blocks, init=randomized(drop=x16),
options=check, examine=i v)
Here is a small part of the output.
Vacation Example
Average
Prediction
Design Standard
Number D-Efficiency A-Efficiency G-Efficiency Error
------------------------------------------------------------------------
1 98.9099 97.8947 98.9418 0.9280
Vacation Example 127
Information Matrix
Intercept x11 x12 x21 x22 x31 x32 x41 x42 x51 x52
Intercept 36 0 0 0 0 0 0 0 0 0 0
x11 0 36 -0 -0 0 0 -0 0 -0 0 0
x12 0 -0 36 0 -0 -0 0 0 -0 0 -0
x21 0 -0 0 36 0 -0 -0 0 0 0 -0
x22 0 0 -0 0 36 0 -0 -0 -0 0 -0
x31 0 0 -0 -0 0 36 -0 -0 0 0 0
x32 0 -0 0 -0 -0 -0 36 0 0 0 -0
x41 0 0 0 0 -0 -0 0 36 -0 -0 -0
x42 0 -0 -0 0 -0 0 0 -0 36 0 -0
x51 0 0 0 0 0 0 0 -0 0 36 -0
.
.
.
Information Matrix
x112 36 -0 -0 0 0 0 -0 -0 -0
x121 -0 36 -0 -0 -0 -0 -0 0 0
x122 -0 -0 36 -0 0 -0 -0 -0 -0
x131 0 -0 -0 36 -0 -5 -8 9 -0
x132 0 -0 0 -0 36 8 -5 -0 -9
x141 0 -0 -0 -5 8 36 -0 -5 -8
x142 -0 -0 -0 -8 -5 -0 36 -8 5
x151 -0 0 -0 9 -0 -5 -8 36 -0
x152 -0 0 -0 -0 -9 -8 5 -0 36
Variance Matrix
Variance Matrix
This design still looks good. The D-efficiency for the design excluding the blocking factor is 98.9099%. We
can see that the nonorthogonality between x13-x15 make their variances larger than the other factors (0.0309
versus 0.0278).
This variance matrix is a little hard to look at. All of the 0.0000 and -0.0000’s tend to obscure the nonzeros. We
can use ODS along with PROC FORMAT and PROC PRINT to make a better display. The variance matrix is
excluded from the printed output and instead is output to a SAS data set. The persist options are used since
the ODS statements need to persist through the macro steps until the macro reaches the PROC OPTEX step. In
Version 9.0 and previous SAS versions, the match- all option must be specified with persist on the ods
output statement. PROC FORMAT is used to construct a format so that the values within rounding error of
zero print as ’0’. PROC PRINT is called to print the results. The label statement gives the row ID variable,
rowname a null header.
ods exclude ’variance matrix’(persist);
ods output ’variance matrix’(persist match_all)=v;
%mktex(3 ** 15, n=&n * &blocks, init=randomized(drop=x16),
options=check, examine=v)
proc format;
value zer -1e-8 - 1e-8 = ’ 0 ’;
run;
Vacation Example
Intercept 0.0278 0 0 0 0 0 0 0
x11 0 0.0278 0 0 0 0 0 0
x12 0 0 0.0278 0 0 0 0 0
x21 0 0 0 0.0278 0 0 0 0
x22 0 0 0 0 0.0278 0 0 0
x31 0 0 0 0 0 0.0278 0 0
x32 0 0 0 0 0 0 0.0278 0
x41 0 0 0 0 0 0 0 0.0278
.
.
.
x112 0 0 0 0 0 0 0
x121 0 0 0 0 0 0 0
x122 0.0278 0 0 0 0 0 0
x131 0 0.0309 0 0.0031 0.0053 -0.0062 0
x132 0 0 0.0309 -0.0053 0.0031 0 0.0062
x141 0 0.0031 -0.0053 0.0309 0 0.0031 0.0053
x142 0 0.0053 0.0031 0 0.0309 0.0053 -0.0031
x151 0 -0.0062 0 0.0031 0.0053 0.0309 0
x152 0 0 0.0062 0.0053 -0.0031 0 0.0309
Vacation Example 129
These next steps use the %MktLab macro to reassign the variable names, store the design in a permanent SAS
data set, [Link], and then use the %MktEx macro to check the results. The vars= option
provides the new variable names: the first variable (originally x1) becomes x1 (still), ..., the fifth variable (orig-
inally x5) becomes x5 (still), the sixth variable (originally x6) becomes x11, ... the tenth variable (originally
x10) becomes x15, the eleventh through fifteenth original variables become x6, x9, x7, x8, x10, and finally
the last variable becomes Block. We made the correlated variables correspond to the least important attributes
in different alternatives (in this case the scenery factors for Alaska, Mexico, and Maine).
%mktlab(data=randomized, vars=x1-x5 x11-x15 x6 x9 x7 x8 x10 Block,
out=[Link])
%mkteval(blocks=block)
Here is the output from the %MktLab macro, which shows the correspondence between the original and new
variable names.
Variable Mapping:
x1 : x1
x2 : x2
x3 : x3
x4 : x4
x5 : x5
x6 : x11
x7 : x12
x8 : x13
x9 : x14
x10 : x15
x11 : x6
x12 : x9
x13 : x7
x14 : x8
x15 : x10
x16 : Block
Vacation Example
Canonical Correlations Between the Factors
There are 0 Canonical Correlations Greater Than 0.316
Block 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
x1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0
x2 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0
x3 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0
x4 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0
x5 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0
x11 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0
x12 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0
x13 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0
x14 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
x15 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0
x6 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0
x9 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0
x7 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0.25 0.25
x8 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 1 0.25
x10 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0.25 1
130 TS-677E Multinomial Logit, Discrete Choice Modeling
Vacation Example
Summary of Frequencies
There are 0 Canonical Correlations Greater Than 0.316
* - Indicates Unequal Frequencies
Frequencies
Block 18 18
x1 12 12 12
x2 12 12 12
x3 12 12 12
x4 12 12 12
x5 12 12 12
x11 12 12 12
x12 12 12 12
x13 12 12 12
x14 12 12 12
x15 12 12 12
x6 12 12 12
x9 12 12 12
x7 12 12 12
x8 12 12 12
x10 12 12 12
Block x1 6 6 6 6 6 6
Block x2 6 6 6 6 6 6
Block x3 6 6 6 6 6 6
Block x4 6 6 6 6 6 6
Block x5 6 6 6 6 6 6
Block x11 6 6 6 6 6 6
Block x12 6 6 6 6 6 6
Block x13 6 6 6 6 6 6
Block x14 6 6 6 6 6 6
Block x15 6 6 6 6 6 6
Block x6 6 6 6 6 6 6
Block x9 6 6 6 6 6 6
Block x7 6 6 6 6 6 6
Block x8 6 6 6 6 6 6
Block x10 6 6 6 6 6 6
x1 x2 4 4 4 4 4 4 4 4 4
x1 x3 4 4 4 4 4 4 4 4 4
x1 x4 4 4 4 4 4 4 4 4 4
.
.
.
x9 x7 4 4 4 4 4 4 4 4 4
x9 x8 4 4 4 4 4 4 4 4 4
x9 x10 4 4 4 4 4 4 4 4 4
* x7 x8 3 3 6 6 3 3 3 6 3
* x7 x10 6 3 3 3 3 6 3 6 3
* x8 x10 3 3 6 3 6 3 6 3 3
N-Way 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
Vacation Example 131
data _null_;
array dests[&mm1] $ 10 _temporary_ (’Hawaii’ ’Alaska’ ’Mexico’
’California’ ’Maine’);
array prices[3] $ 5 _temporary_ (’$999’ ’$1249’ ’$1499’);
array scenes[3] $ 13 _temporary_
(’the Mountains’ ’a Lake’ ’the Beach’);
array lodging[3] $ 15 _temporary_
(’Cabin’ ’Bed & Breakfast’ ’Hotel’);
array x[15];
file print linesleft=ll;
set [Link];
by block;
In practice, data collection may be much more elaborate than this. It may involve art work, photographs, and the
choice sets may be presented and data may be collected over the web. However the choice sets are presented and
the data collected, the essential ingredients remain the same. Subjects are shown sets of alternatives and asked to
make a choice, then they go on to the next set.
Vacation Example 133
data key;
input Place $ 1-10 (Lodge Scene Price) ($);
datalines;
Hawaii x1 x6 x11
Alaska x2 x7 x12
Mexico x3 x8 x13
California x4 x9 x14
Maine x5 x10 x15
Home . . .
;
Vacation Example
1 2 3 1 3 1 2 2 1 3 3 2 3 2 2 2
1 3 2 3 1 3 1 2 1 1 3 1 2 1 1 1
Vacation Example
1 1 Hawaii 2 2 2
2 1 Alaska 3 2 3
3 1 Mexico 1 1 2
4 1 California 3 3 2
5 1 Maine 1 3 2
6 1 Home . . .
7 2 Hawaii 3 1 1
8 2 Alaska 2 2 2
9 2 Mexico 3 1 1
10 2 California 1 1 1
11 2 Maine 3 3 1
12 2 Home . . .
The next steps assign formats, convert the variable Price to contain actual prices, and recode the constant
alternative.
proc format;
value price 1 = ’ 999’ 2 = ’1249’
3 = ’1499’ 0 = ’ 0’;
value scene 1 = ’Mountains’ 2 = ’Lake’
3 = ’Beach’ 0 = ’Home’;
value lodge 1 = ’Cabin’ 2 = ’Bed & Breakfast’
3 = ’Hotel’ 0 = ’Home’;
run;
data rolled2;
set rolled;
if place = ’Home’ then do; lodge = 0; scene = 0; price = 0; end;
price = input(put(price, price.), 5.);
format scene scene. lodge lodge.;
run;
Vacation Example
It is not necessary to recode the missing values for the constant alternative. In practice, we usually will not do
this step. However, for this first analysis, we will want all nonmissing values of the attributes so we can see all
levels in the final printed output. We also recode Price so that for a later analysis, we can analyze Price as
a quantitative effect. For example, the expression put(price, price.) converts a number, say 2, into a
string (in this case ’1249’), then the input function reads the string and converts it to a numeric 1249. Next, we
use the macro %MktMerge to combine the data and design and create the variable c, indicating whether each
alternative was a first choice or a subsequent choice.
%mktmerge(design=rolled2, data=results, out=res2, blocks=form,
nsets=&n, nalts=&m, setvars=choose1-choose&n)
Vacation Example
Binary Coding
One more thing must be done to these data before they can be analyzed. The binary design matrix is coded for
each effect. This can be done with PROC TRANSREG.
proc transreg design=5000 data=res2 nozeroconstant norestoremissing;
model class(place / zero=none order=data)
class(price scene lodge / zero=none order=formatted) /
lprefix=0;
output out=coded(drop=_type_ _name_ intercept);
id subj set form c;
run;
The design option specifies that no model is fit; the procedure is just being used to code a design. When
design is specified, dependent variables are not required. Optionally, design can be followed by “=n” where
n is the number of observations to process at one time. By default, PROC TRANSREG codes all observations
in one big group. For very large data sets, this can consume large amounts of memory and time. Processing
blocks of smaller numbers of observations is more efficient. The option design=5000 processes observations
in blocks of 5000. For smaller computers, try something like design=1000.
The nozeroconstant and norestoremissing options are not necessary for this example but are included
here because sometimes they are very helpful in coding choice models. The nozeroconstant option specifies
that if the coding creates a constant variable, it should not be zeroed. The nozeroconstant option should
always be specified when you specify design=n because the last group of observations may be small and may
contain constant variables. The nozeroconstant option is also important if you do something like coding by
subj set because sometimes an attribute is constant within a choice set. The norestoremissing option
specifies that missing values should not be restored when the out= data set is created. By default, the coded
class variable contains a row of missing values for observations in which the class variable is missing. When
you specify the norestoremissing option, these observations contain a row of zeros instead. This option
is useful when there is a constant alternative indicated by missing values. Both of these options, like almost all
options in PROC TRANSREG, can be abbreviated to three characters (noz and nor).
The model statement names the variables to code and provides information about how they should be coded.
The specification class(place / ...) specifies that the variable Place is a classification variable and
requests a binary coding. The zero=none option creates binary variables for all categories. The order=data
option sorts the levels into the order they were first encountered in the data set. It is specified so ’Home’
will be the last destination in the analysis, as it is in the data set. The class(price scene lodge /
...) specification names the variables Price, Scene, and Lodge as categorical variables and creates binary
variables for all of the levels of all of the variables. The levels are sorted into order based on their formatted
values. The lprefix=0 option specifies that when labels are created for the binary variables, zero characters
of the original variable name should be used as a prefix. This means that the labels are created only from the
level values. For example, ’Mountains’ and ’Bed & Breakfast’ are created as labels not ’Scene
Mountains’ and ’Lodge Bed & Breakfast’.
An output statement names the output data set and drops variables that are not needed. These variables do
not have to be dropped. However, since they are variable names that are often found in special data set types,
PROC PHREG prints warnings when it finds them. Dropping the variables prevents the warnings. Finally, the
id statement names the additional variables that we want copied from the input to the output data set. The next
steps print the first coded choice set.
proc print data=coded(obs=6);
id place;
var subj set form c price scene lodge;
run;
proc print data=coded(obs=6) label;
var pl:;
run;
Vacation Example 137
Vacation Example
Vacation Example
1 1 0 0 0 0 0 Hawaii
2 0 1 0 0 0 0 Alaska
3 0 0 1 0 0 0 Mexico
4 0 0 0 1 0 0 California
5 0 0 0 0 1 0 Maine
6 0 0 0 0 0 1 Home
Vacation Example
Hawaii 0 0 1 0 Lake
Alaska 0 0 1 0 Lake
Mexico 0 0 0 1 Mountains
California 1 0 0 0 Beach
Maine 1 0 0 0 Beach
Home 0 1 0 0 Home
Vacation Example
Bed &
Place Breakfast Cabin Home Hotel Lodge 0 999 1249 1499 Price
The coded design consists of binary variables for destinations Hawaii Home, scenery Beach Mountains,
lodging Bed & Breakfast Hotel, and price 0 1499. For example, in the last printed panel of the first choice
set, the Bed & Breakfast column has a 1 for Hawaii since Hawaii has B & B lodging in this choice set. The Bed
& Breakfast column has a 0 for Alaska since Alaska does not have B & B lodging in this choice set. These binary
variables will form the independent variables in the analysis.
Note that we are fitting a model with generic attributes. Generic attributes are assumed to be the same for all
alternatives. For example, our model is structured so that the part-worth utility for being on a lake will be the same
for Hawaii, Alaska, and all of the other destinations. Similarly, the part-worth utilities for the different prices will
not depend on the destinations. In contrast, on page 146, using the same data, we will code alternative-specific
effects where the part-worth utilities are allowed by the model to be different for each of the destinations.
PROC PHREG is run in the usual way to fit the choice model.
proc phreg data=coded brief;
model c*c(2) = &_trgind / ties=breslow;
strata subj set;
run;
We specify the &- trgind macro variable for the model statement independent variable list. PROC TRANS-
REG automatically creates this macro variable. It contains the list of coded independent variables generated by
the procedure. This is so you do not have to figure out what names TRANSREG created and specify them. In
this case, PROC TRANSREG sets &- trgind to contain the following list.
PlaceHawaii PlaceAlaska PlaceMexico PlaceCalifornia PlaceMaine PlaceHome
Price0 Price999 Price1249 Price1499 SceneBeach SceneHome SceneLake
SceneMountains LodgeBed___Breakfast LodgeCabin LodgeHome LodgeHotel
The analysis is stratified by subject and choice set. Each stratum consists of a set of alternatives from which a
subject made one choice. In this example, each stratum consists of six alternatives, one of which was chosen
and five of which were not chosen. (Recall that we used %phchoice(on)on page 79 to customize the output
from PROC PHREG.) The full table of the strata would be quite large with one line for each of the 3600 strata,
so the brief option was specified on the PROC PHREG statement. This option produces a brief summary of
the strata. In this case, we see there were 3600 choice sets that all fit one response pattern. Each consisted of 6
alternatives, 1 of which was chosen and 5 of which were not chosen. There should be one pattern for all choice
sets in an example like this one the number of alternatives, number of chosen alternatives, and the number not
chosen should be constant.
Vacation Example
Model Information
1 3600 6 1 5
Convergence Status
Without With
Criterion Covariates Covariates
Parameter Standard
DF Estimate Error Chi-Square Pr > ChiSq
The destinations, from most preferred to least preferred, are Hawaii, Mexico, California, Maine, Alaska, and then
stay at home. The utility for lower price is greater than the utility for higher price. The beach is preferred over a
lake, which is preferred over the mountains. A bed & breakfast is preferred over a hotel, which is preferred over a
cabin. Notice that the coefficients for the constant alternative (home and zero price) are all zero. Also notice that
for each factor, destination, price, scenery and accommodations, the coefficient for the last level is always zero.
This will always occur when we code with zero=none. The last level of each factor is a reference level, and
the other coefficients will have values relative to this zero. For example, all of the coefficients for the destination
are positive relative to the zero for staying at home. For scenery, all of the coefficients are positive relative to the
zero for the mountains. For accommodations, the coefficient for cabin is less than the zero for hotel, which is less
than the coefficient for bed & breakfast. In some sense, each class variable in a choice model with a constant
alternative has two reference levels or two levels that will always have a zero coefficient: the level corresponding
to the constant alternative and the level corresponding to the last level. At first, it is reassuring to run the model
with all levels represented to see that all the right levels get zeroed. Later, we will see ways to eliminate these
levels from the output.
140 TS-677E Multinomial Logit, Discrete Choice Modeling
Alternatively, you could run PROC TRANSREG again with the new coding. We use this latter approach, because
it is easier, and it will allow us to illustrate other options. In the previous analysis, there were a number of
structural-zero parameter estimates in the results due to the usage of the zero=none option in the PROC
TRANSREG coding. This is a good thing, particularly for a first attempt at the analysis. It is good to specify
zero=none and check the results and make sure you have the right pattern of zeros and nonzeros. Later, you
can run again excluding some of the structural zeros. This time, we will explicitly specify the ’Home’ level in
the zero= option as the reference level so it will be omitted from the &- trgind variable list. The first class
specification specifies zero=’Home’ since there is one variable. The second class specification specifies
zero=’Home’ ’Home’ specifying the reference level for each of the two variables. The variable Price is
designated as an identity variable. The identity transformation is the no-transformation option, which
is used for variables that need to enter the model with no further manipulations. The identity variables are
simply copied into the output data set and added to the &- trgind variable list. The statement label price
= ’Price’ is specified to explicitly set a label for the identity variable price. This is because we explicitly
modified PROC PHREG output using %phchoice(on)so that the rows of the parameter estimate table would
be labeled only with variable labels not variable names. A label for Price must be explicitly specified in order
for the output to contain a label for the price effect.
proc transreg design data=res2 nozeroconstant norestoremissing;
model class(place / zero=’Home’ order=data) identity(price)
class(scene lodge / zero=’Home’ ’Home’ order=formatted) /
lprefix=0;
output out=coded(drop=_type_ _name_ intercept);
label price = ’Price’;
id subj set form c;
run;
Vacation Example
Model Information
1 3600 6 1 5
Vacation Example 141
Convergence Status
Without With
Criterion Covariates Covariates
Parameter Standard
DF Estimate Error Chi-Square Pr > ChiSq
The results of the two different analyses are similar. The coefficients for the destinations all increase by a non-
constant amount (approximately 10.65) but the pattern is the same. There is still a negative effect for price. Also,
the fit of this model is slightly worse, Chi-Square = 6454.9702 , compared to the previous value of 6535.3316
(bigger values mean better fit), because price has one fewer parameter.
data res3;
set res2;
PriceL = price;
if price then pricel = (price - 1249) / 250;
run;
Vacation Example
Model Information
1 3600 6 1 5
Convergence Status
Without With
Criterion Covariates Covariates
Parameter Standard
DF Estimate Error Chi-Square Pr > ChiSq
The fit is exactly the same as when price was treated as qualitative, Chi-Square = 6535.3316. This is because
both models are the same except for the different but equivalent 2 df codings of price. The coefficients for
the destinations in the two models differ by a constant 1.23293. The coefficients for the factors after price are
unchanged. The part-worth utility for $999 is 1:75950 (999 1249)=250+0:52657 ((999 1249)=250)2 =
2:28607, the part-worth utility for $1249 is 1:75950 (1249 1249)=250+0:52657 ((1249 1249)=250)2 =
0, and the part-worth utility for $1499 is 1:75950 (1499 1249)=250+0:52657 ((1499 1249)=250)2 =
1:23293, which differ from the coefficients when price was treated as qualitative, by a constant -1.23293.
Effects Coding
In the previous analyses, binary (1, 0) codings were used for the variables. The next analysis illustrates effects
(1, 0, -1) coding. The two codings differ in how the final reference level is coded. In binary coding, the reference
level is coded with zeros. In effects coding, the reference level is coded with minus ones.
In this example, we will use a binary coding for the destinations and effects codings for the attributes.
PROC TRANSREG can be used for effects coding. The effects option used inside the parentheses after
class asks for a (0, 1, -1) coding. The zero= option specifies the levels that receive the -1’s. PROC PHREG
is run with almost the same variable list as before, except now the variables for the reference levels, those whose
parameters are structural zeros are omitted. Refer back to the parameter estimates table on page 139, a few select
lines of which are reproduced next:
144 TS-677E Multinomial Logit, Discrete Choice Modeling
Parameter Standard
DF Estimate Error Chi-Square Pr > ChiSq
Home 0 0 . . .
0 0 0 . . .
1499 0 0 . . .
Home 0 0 . . .
Mountains 0 0 . . .
Home 0 0 . . .
Hotel 0 0 . . .
Notice that the coefficients for the constant alternative (home and zero price) are all zero. Also notice that for
each factor, destination, price, scenery and accommodations, the coefficient for the last level is always zero. In
some sense, each class variable in a choice model with a constant alternative has two reference levels or two
levels that will always have a zero coefficient: the level corresponding to the constant alternative and the level
corresponding to the last level. In some of the preceding examples, we eliminated the ’Home’ levels by specifying
zero=Home. Now we will see how to eliminate all of the structural zeros from the parameter estimate table.
First, for each classification variable, we change the level for the constant alternative to missing. (Recall that
they were originally missing and we only made them nonmissing to deliberately produce the zero coefficients.)
This will cause PROC TRANSREG to ignore those levels when constructing dummy variables. When you use
this strategy, you must specify the norestoremissing option in the PROC TRANSREG statement. During
the first stage of design matrix creation, PROC TRANSREG puts zeros in the dummy variables for observations
with missing class levels. At the end, it replaces the zeros with missings, “restoring the missing values.” When
the norestoremissing option is specified, missing values are not restored and we get zeros in the dummy
variables for missing class levels. The DATA step if statements recode the constant levels to missing. Next, in
PROC TRANSREG, the reference levels ’Mountains’ and ’Hotel’ are listed in the zero= option in the class
specification.
data res4;
set res3;
if scene = 0 then scene = .;
if lodge = 0 then lodge = .;
run;
The coded data and design matrix are printed for the first choice set. The coded design matrix begins with five
binary columns for the destinations, ’Hawaii’ through ’Maine’. There is not a column for the stay-at-home
destination and the row for stay at home has all zeros in the coded variables. Next is the linear price effect,
’Price 1’, consisting of 0, 1, and -1. It is followed by the quadratic price effect, ’Price 2’, which is
’Price 1’ squared. Next are the scenery terms, effects coded. ’Beach’ and ’Lake’ have values of 0 and
1; -1’s in the fourth row for the reference level, ’Mountains’; and zeros in the last row for the stay-at-home
alternative. Next are the lodging terms, effects coded. ’Bed & Breakfast’ and ’Cabin’ have values of 0
and 1; -1’s in the first, third and fourth row for the reference level, ’Hotel’; and zeros in the last row for the
stay-at-home alternative.
proc print data=coded(obs=6) label;
run;
Vacation Example
1 1 0 0 0 0 0 0 0 1 1
2 0 1 0 0 0 1 1 0 1 -1
3 0 0 1 0 0 0 0 -1 -1 0
4 0 0 0 1 0 0 0 1 0 -1
5 0 0 0 0 1 0 0 1 0 0
6 0 0 0 0 0 0 0 0 0 0
Vacation Example
Model Information
1 3600 6 1 5
146 TS-677E Multinomial Logit, Discrete Choice Modeling
Convergence Status
Without With
Criterion Covariates Covariates
Parameter Standard
DF Estimate Error Chi-Square Pr > ChiSq
It is instructive to compare the results of this analysis to the previous analysis on page 142. First, the model fit and
chi-square statistics are the same indicating the models are equivalent. The coefficients for the destinations differ
by a constant 0.41724, the price coefficients are the same, the scenery coefficients differ by a constant -0.70855,
and the lodging coefficients differ by a constant 0.29131. Notice that 0:41724 + 0 + 0:70855 + 0:29131 = 0,
so the utility for each alternative is unchanged by the different but equivalent codings.
Alternative-Specific Effects
In all of the analyses presented so far in this example, we have assumed that the effects for price, scenery,
and accommodations are generic or constant across the different destinations. Equivalently, we assumed that
destination does not interact with the attributes. Next, we show a model with alternative-specific effects that
does not make this assumption. Our new model allows for different price, scenery and lodging effects for each
destination. The coding can be done with PROC TRANSREG and its syntax for interactions. Before we do the
coding, let’s go back to the design preparation stage and redo it in a more normal fashion so reference levels will
be omitted from the analysis.
Vacation Example 147
We start by creating the data set KEY. This step differs from the one we saw on page 133 only in that now we
have a missing value for Place for the constant alternative.
data key;
input Place $ 1-10 (Lodge Scene Price) ($);
datalines;
Hawaii x1 x6 x11
Alaska x2 x7 x12
Mexico x3 x8 x13
California x4 x9 x14
Maine x5 x10 x15
. . . .
;
Next, we use the %MktRoll macro to process the design and the %MktMerge macro to merge the design and
data.
%mktroll(design=[Link], key=key, alt=place, out=rolled)
Vacation Example
Notice that the attributes for the constant alternative are all missing. Next, we code with PROC TRANSREG.
Since we are using missing values for the constant alternative, we must specify the norestoremissing
option in the PROC TRANSREG statement. First, we specify the variable Place as a class variable. Next,
we interact Place with all of the attributes, Price, Scene, and Lodge, to create the alternative-specific
effects.
proc transreg design=5000 data=res2 nozeroconstant norestoremissing;
model class(place / zero=none order=data)
class(place * price place * scene place * lodge /
zero=none order=formatted) / lprefix=0 sep=’ ’ ’, ’;
output out=coded(drop=_type_ _name_ intercept);
id subj set form c;
run;
proc print data=coded(obs=6) label noobs;
run;
The coded design matrix consists of:
five binary columns, ’Hawaii’ through ’Maine’, for the five destinations,
fifteen binary columns (5 destinations times 3 prices), ’Alaska, 999’ through ’Mexico, 1499’,
for the alternative-specific price effects,
fifteen binary columns (5 destinations times 3 sceneries), ’Alaska, Beach’ through ’Mexico,
Mountains’, for the alternative-specific scenery effects,
fifteen binary columns (5 destinations times 3 lodgings), ’Alaska, Bed & Breakfast’ through
’Mexico, Hotel’, for the alternative-specific lodging effects.
The entire sixth row of the coded design matrix, the stay-at-home alternative, consists of zeros.
Vacation Example
1 0 0 0 0 0 0 0
0 1 0 0 0 0 0 1
0 0 1 0 0 0 0 0
0 0 0 1 0 0 0 0
0 0 0 0 1 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 1 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 1 0 0 0 0 0 0 0
0 0 0 0 0 0 0 1 0
0 0 0 0 0 0 0 0 0
Vacation Example 149
0 0 0 0 0 0 0 0 0
0 0 0 0 1 0 0 0 0
0 1 0 0 0 0 0 0 0
0 0 0 0 0 0 1 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 1 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 1
0 0 0 0 0 0 0 0 0
0 0 0 1 0 0 0 0 0
0 0 0 0 0 0 0 0 0
Alaska, California,
Bed & Alaska, Alaska, Bed & California, California,
Breakfast Cabin Hotel Breakfast Cabin Hotel
0 0 0 0 0 0
0 0 1 0 0 0
0 0 0 0 0 0
0 0 0 0 0 1
0 0 0 0 0 0
0 0 0 0 0 0
1 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 1 0
0 0 0 0 0 0 0 0 0
0 0 0 0 1 0 0 0 0
0 0 0 0 0 0 0 0 0
Vacation Example
Model Information
1 3600 6 1 5
Convergence Status
Without With
Criterion Covariates Covariates
Parameter Standard
DF Estimate Error Chi-Square Pr > ChiSq
There are zero coefficients for the reference alternative. Do we need this more complicated model instead of the
simpler model? To answer this, first look at the coefficients. Are they similar across different destinations? In
this case, they seem to be. This suggests that the simpler model may be sufficient.
More formally, the two models can be statistically compared. You can test the null hypothesis that the two
models are not significantly different by comparing their likelihoods. The difference between two 2 log(LC )’s
(the number reported under ’With Covariates’ in the output) has a chi-square distribution. We can get the df for
the test by subtracting the two df for the two likelihoods. The difference 6560:5318 6535:3316 = 25:2002 is
distributed 2 with 35 11 = 24 df (p < 0:395). This more complicated model does not account for significantly
more variance than the simpler model.
152 TS-677E Multinomial Logit, Discrete Choice Modeling
This example is a modification of the previous example. Now, all alternatives do not have the same factors, and
all factors do not have the same numbers of levels. There are still five destinations of interest: Hawaii, Alaska,
Mexico, California, and Maine. Each alternative is composed of three factors like before: package cost, scenery,
and accommodations, only now they do not all have the same levels, and the Hawaii and Mexico alternatives
are composed of one additional attribute. For Hawaii and Alaska, the costs are $1,249, $1,499, and $1,749; for
California, the prices are $999, $1,249, $1,499, and $1,749; and for Mexico and Maine, the prices are $999,
$1,249, and $1,499. Scenery (mountains, lake, beach) and accommodations (cabin, bed & breakfast, and hotel)
are the same as before. The Mexico trip now has the option of a side trip to sites of archaeological significance,
via bus, for an additional cost of $100. The Hawaii trip has the option of a side trip to an active volcano, via
helicopter, for an additional cost of $200. This is typical of the problems that marketing researchers face. We
have lots of factors and asymmetry each alternative is not composed of the same factors, and the factors do not
all have the same numbers of levels.
%mktruns( 3 ** 14 4 2 2 )
The output tells us the size of the saturated design, which is the number of parameters in the linear design, and
suggests design sizes.
Design Summary
Number of
Levels Frequency
2 2
3 14
4 1
Saturated = 34
Full Factorial = 76,527,504
72 * 0
144 0
36 2 8
108 2 8
54 18 4 8 12
90 18 4 8 12
126 18 4 8 12
45 48 2 4 6 8 12
63 48 2 4 6 8 12
81 48 2 4 6 8 12
n Design Reference
72 2 ** 20 3 ** 24 4 ** 1 Wang, 1996
72 2 ** 13 3 ** 25 4 ** 1 Wang, 1996
72 2 ** 11 3 ** 24 4 ** 1 6 ** 1 Wang, 1996
We need at least 34 choice sets, as shown by ’(Saturated=34)’ in the listing. Any size that is a multiple of 72
would be optimal. We would recommend 72 choice sets, four blocks of size 18. However, like the previous
vacation example, we will use fewer choice sets so that we can illustrate getting an efficient but nonorthogonal
design. A design with 36 choice sets is pretty good. Thirty-six is not divisible by 8 = 2 4, so we cannot have
equal frequencies in the California price and Mexico and Hawaii side trip combinations. This should not pose
any problem. This leaves only 2 error df for the linear model, but in the choice model, we will have adequate
error df.
x1 3 1 2 3
x2 3 1 2 3
x3 3 1 2 3
x4 3 1 2 3
x5 3 1 2 3
x6 3 1 2 3
x7 3 1 2 3
x8 3 1 2 3
x9 3 1 2 3
x10 3 1 2 3
x11 3 1 2 3
x12 3 1 2 3
x13 3 1 2 3
x14 4 1 2 3 4
x15 3 1 2 3
x16 2 1 2
x17 2 1 2
Vacation Example, with Alternative-Specific Attributes 155
Average
Prediction
Design Standard
Number D-Efficiency A-Efficiency G-Efficiency Error
------------------------------------------------------------------------
1 98.8874 97.5943 97.4925 0.9718
x1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
x2 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
x3 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0
x4 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0
x5 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0
x6 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0
x7 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0
x8 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0
x9 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0
x10 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0
x11 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
x12 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0
x13 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0.25 0 0
x14 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0.33 0.33
x15 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0 1 0 0
x16 0 0 0 0 0 0 0 0 0 0 0 0 0 0.33 0 1 0
x17 0 0 0 0 0 0 0 0 0 0 0 0 0 0.33 0 0 1
The macro found a very nice, almost orthogonal and almost 99% efficient design in 5.5 minutes. However, we
will not use this design. Instead, we will make a larger design with interactions.
If we want interactions to be estimable, we will need more choice sets. The number of parameters is 1 for the
intercept, 14 (3 1)+(4 1)+2 (2 1) = 33 for main effects, and 4 (3 1) (3 1)+(4 1) (3 1) = 22
for interactions for a total of 1 + 33 + 22 = 56 parameters. This means we need at least 56 choice sets, and
ideally for this design with 2, 3, and 4 level factors, we would like the number of sets to be divisible by 2 2,
2 3, 2 4, 3 3, and 3 4. Sixty is divisible by 2, 3, 4, 6, and 12 so is a reasonable design size. Sixty choice
sets could be divided into three blocks of size 20, four blocks of size 15, or five blocks of size 12. Seventy-two
choice sets would be better, since unlike 60, 72 can be divided by 9. Unfortunately, 72 would require one more
block.
We can also run the %MktRuns macro to help us choose the number of choice sets. However, the %MktRuns
does not have a special syntax for interactions, you have to specify the main effects and interactions of two factors
as if it were a single factor. For example, for the interaction of 2 three-level factors, you specify 9 in the list.
For the interaction of a three-level factor and a four-level factor, you specify 12 in the list. Do not specify ’3 3
9’ or ’3 4 12’; just specify ’3’ and ’12’. In this example, we specify four 9’s for the four accommodation/price
interactions involving only three-level factors, one 12 for the California accommodation/price interaction, five
3’s for scenery, and two 2’s for the side trips. We also specified a keyword option max= to consider only the 45
design sizes from the minimum of 56 up to 100.
title ’Vacation Example with Asymmetry’;
%mktruns(9 9 9 9 12 3 3 3 3 3 2 2, max=45)
Design Summary
Number of
Levels Frequency
2 2
3 5
9 4
12 1
Saturated = 56
Full Factorial = 76,527,504
72 30 27 81 108
81 33 2 4 6 12 18 24 36 108
90 39 4 12 24 27 36 81 108
96 57 9 18 27 36 81 108
60 59 9 18 24 27 36 81 108
63 59 2 4 6 12 18 24 27 36 81 108
84 59 9 18 24 27 36 81 108
99 59 2 4 6 12 18 24 27 36 81 108
66 61 4 9 12 18 24 27 36 81 108
78 61 4 9 12 18 24 27 36 81 108
Vacation Example, with Alternative-Specific Attributes 157
We see that 72 cannot be divided by 27 = 9 3 so for example the Maine accommodation/price combinations
cannot occur with equal frequency with each of the three-level factors. We see that 72 cannot be divided by
81 = 9 9 so for example the Mexico accommodation/price combinations cannot occur with equal frequency
with each of the Hawaii accommodation/price combinations. We see that 72 cannot be divided by 108 = 9 12
so for example the California accommodation/price combinations cannot occur with equal frequency with each
of the Maine accommodation/price combinations. With interactions, there are many higher-order opportunities
for nonorthogonality. However, usually we will not be overly concerned about potential unequal frequencies on
combinations of attributes in different alternatives.
The smallest number of runs in the table is 60. While 72 is better in that it can be divided by more numbers,
either 72 or 60 should work fine. We will pick the larger number and run the %MktEx macro again with n=72
specified.
%mktex(3 ** 13 4 3 2 2, n=72, seed=7654321,
interact=x1*x11 x2*x12 x3*x13 x4*x14 x5*x15)
The macro printed these notes to the log.
NOTE: Performing 20 searches of 243 candidates, full-factorial=76,527,504.
NOTE: Generating the tabled design, n=72.
The candidate-set search is using a fractional-factorial candidate set with 35 = 243 candidates. The two-level
factors in the candidate set are made from three-level factors by coding down. Coding down replaces an m-level
factor with a factor with fewer than m levels, for example a two-level factor could be created from a three-level
factor: ((123) ) (121)). The four-level factor in the candidate set is made from 2 three-level factors and coding
down. ((1 2 3) (1 2 3) ) (1 2 3 4 5 6 7 8 9) ) (1 2 3 4 1 2 3 4 1)). The tabled design used for the partial
initialization in the coordinate-exchange steps has 72 runs. Here are some of the results.
Current Best
Design Row,Col D-Efficiency D-Efficiency Notes
----------------------------------------------------------
1 Start 85.1188 85.1188 Can
1 End 85.1188
NOTE: Quitting the algorithm search step after 10.40 minutes and 16 designs.
Current Best
Design Row,Col D-Efficiency D-Efficiency Notes
----------------------------------------------------------
0 Initial 89.8765 89.8765 Ini
NOTE: Quitting the design search step after 20.95 minutes and 14 designs.
Current Best
Design Row,Col D-Efficiency D-Efficiency Notes
----------------------------------------------------------
0 Initial 89.8765 89.8765 Ini
NOTE: Quitting the refinenent step after 6.33 minutes and 4 designs.
x1 3 1 2 3
x2 3 1 2 3
x3 3 1 2 3
x4 3 1 2 3
x5 3 1 2 3
x6 3 1 2 3
x7 3 1 2 3
x8 3 1 2 3
x9 3 1 2 3
x10 3 1 2 3
x11 3 1 2 3
x12 3 1 2 3
x13 3 1 2 3
x14 4 1 2 3 4
x15 3 1 2 3
x16 2 1 2
x17 2 1 2
160 TS-677E Multinomial Logit, Discrete Choice Modeling
Average
Prediction
Design Standard
Number D-Efficiency A-Efficiency G-Efficiency Error
------------------------------------------------------------------------
1 89.8765 80.0119 95.5854 0.8819
The algorithm search history shows that the candidate-set approach (Can) used in design 1 found a design that
was 85.1188% efficient. The macro makes no attempt to improve on this design, unless there are restriction on
the design, until the end in the design refinement step, and only if it is the best design found.
Designs 2 through 111 used the coordinate-exchange algorithm with a tabled design initialization (Tab). This
process found a design that was 85.7682% efficient. For this problem, the tabled design initialization initializes
all 72 rows; For other problems, when the number of runs in the design is greater than the number of runs in
the nearest tabled design, the remaining rows would be randomly initialized. The tabled design initialization
usually works very well when all but at most a very few rows and columns are left uninitialized and there are
no interactions or restrictions. That is not the case in this problem, and when the algorithm switches to a fully
random initialization in design 12, it immediately does better. In design 13, the macro finds a design with
89.8765% efficiency. After 16 iterations, the macro quit because the run time for the algorithm search exceeded
10 minutes (which is the default first value of the maxtime= option). The macro only checks the elapsed time
after it finishes making a design. This is why huge problems with restrictions can take much longer.
The algorithm search phase picked the coordinate-exchange algorithm with a random initialization and random
mutations and simulated annealing as the algorithm to use in the next step, the design search step. The design
search history is initialized with the best design (D-efficiency = 89.8765) found so far. The design search phase
starts out with the initial design (Ini) found in the algorithm search phase. Usually, you will see improvement
in the design search phase, however, in this case you do not. After 14 iterations, the macro quit because the run
time for the algorithm search exceeded 20 minutes (which is the default second value of the maxtime= option).
The final set of iterations tries to improve the best design found so far. Random mutations (Ran), simulated
annealing (Ann), and level exchanges are used on the previous best (Pre) design. The random mutations are
responsible for making the efficiency of the starting design worse than the previous best efficiency. After 4
iterations, the macro quit because the run time for the algorithm search exceeded 5 minutes (which is the default
third value of the maxtime= option).
All together, the macro used 37.78 minutes, which is more than the sum of the three reported times, because not
all of the macro’s calculations (most notably time spent in PROC FACTEX and OPTEX) are timed. Run time
was just slightly more than the 10 + 20 + 5 = 35 maximum time specified by maxtime=. Recall that the macro
stated that it ran 20 OPTEX iterations on 243 candidates. This will be very fast. If the full-factorial design had
been smaller (a few thousand runs) the macro may have done more iterations using PROC OPTEX. This could
have brought the run time up closer to an hour. When the full-factorial design is too big to search, and the macro
uses a fractional-factorial design, it does not spend much time using OPTEX, because PROC OPTEX is probably
not going to be the best approach. When the full-factorial design is manageable, the macro will spend more time
in OPTEX, because there is a good chance that it will be the best approach. The macro picks the number of
OPTEX iterations based on the size of the candidate set and the value of the maxtime= option.
x1 x2 x3 x4 x5 x6 x7 x8 x9
Frequencies
* x1 25 23 24
* x2 22 24 26
* x3 21 26 25
* x4 24 22 26
x5 24 24 24
* x6 22 24 26
* x7 26 23 23
* x8 24 25 23
* x9 26 23 23
* x10 23 25 24
x11 24 24 24
* x12 23 24 25
* x13 23 24 25
* x14 19 16 18 19
* x15 22 25 25
* x16 34 38
* x17 38 34
162 TS-677E Multinomial Logit, Discrete Choice Modeling
* x1 x2 7 8 10 6 9 8 9 7 8
* x1 x3 8 8 9 8 8 7 5 10 9
* x1 x4 10 5 10 6 9 8 8 8 8
* x1 x5 10 7 8 7 8 8 7 9 8
* x1 x6 8 8 9 7 7 9 7 9 8
* x1 x7 9 10 6 8 6 9 9 7 8
* x1 x8 8 9 8 8 7 8 8 9 7
* x1 x9 9 8 8 7 8 8 10 7 7
* x1 x10 8 8 9 9 8 6 6 9 9
* x1 x11 8 8 9 7 8 8 9 8 7
* x1 x12 7 8 10 8 8 7 8 8 8
* x1 x13 8 9 8 7 7 9 8 8 8
* x1 x14 7 6 6 6 5 4 7 7 7 6 5 6
* x1 x15 6 9 10 8 6 9 8 10 6
* x1 x16 12 13 10 13 12 12
* x1 x17 13 12 12 11 13 11
* x12 x13 8 7 8 6 9 9 9 8 8
* x12 x14 7 6 5 5 6 4 7 7 6 6 6 7
* x12 x15 7 7 9 6 10 8 9 8 8
* x12 x16 10 13 11 13 13 12
* x12 x17 12 11 12 12 14 11
* x13 x14 7 4 5 7 7 4 7 6 5 8 6 6
* x13 x15 8 7 8 9 7 8 5 11 9
* x13 x16 10 13 13 11 11 14
* x13 x17 12 11 13 11 13 12
* x14 x15 5 7 7 5 4 7 4 7 7 8 7 4
* x14 x16 9 10 7 9 9 9 9 10
* x14 x17 10 9 9 7 9 9 10 9
* x15 x16 11 11 13 12 10 15
* x15 x17 11 11 13 12 14 11
* x16 x17 19 15 19 19
.
.
.
N-Way 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
We can the %MktEx macro to check the design and print the information matrix and variance matrix.
%mktex(3 ** 13 4 3 2 2, n=72, examine=i v, options=check, init=randomized,
interact=x1*x11 x2*x12 x3*x13 x4*x14 x5*x15)
In the interest of space, the results from this step are not shown.
This step took 8.45 seconds. Here are some of the results including the one-way frequencies within blocks. They
should be examined to ensure that each level is well represented in each block. The design is nearly balanced in
most of the factors and blocks. Perfect balance is impossible for the three level factors.
Block x1 x2 x3 x4 x5 x6 x7 x8
Block 18 18 18 18
* x1 25 24 23
* x2 22 24 26
* x3 25 26 21
* x4 22 26 24
x5 24 24 24
* x6 24 26 22
* x7 23 26 23
* x8 24 25 23
* x9 23 23 26
* x10 23 25 24
x11 24 24 24
* x12 24 23 25
* x13 23 24 25
* x14 18 16 19 19
* x15 22 25 25
* x16 34 38
* x17 34 38
164 TS-677E Multinomial Logit, Discrete Choice Modeling
* Block x1 6 6 6 6 6 6 7 6 5 6 6 6
* Block x2 7 6 5 5 6 7 5 7 6 5 5 8
* Block x3 7 6 5 6 6 6 7 7 4 5 7 6
* Block x4 6 6 6 5 7 6 5 7 6 6 6 6
* Block x5 7 5 6 5 7 6 6 6 6 6 6 6
* Block x6 6 7 5 5 7 6 6 6 6 7 6 5
* Block x7 4 7 7 6 6 6 7 6 5 6 7 5
* Block x8 6 6 6 6 6 6 5 7 6 7 6 5
* Block x9 6 6 6 5 6 7 6 5 7 6 6 6
* Block x10 6 6 6 5 7 6 5 6 7 7 6 5
* Block x11 6 6 6 6 6 6 5 6 7 7 6 5
* Block x12 6 6 6 7 5 6 5 7 6 6 5 7
* Block x13 7 5 6 5 7 6 5 6 7 6 6 6
* Block x14 4 4 6 4 4 4 4 6 5 4 5 4 5 4 4 5
* Block x15 5 7 6 6 5 7 6 6 6 5 7 6
* Block x16 7 11 8 10 9 9 10 8
* Block x17 8 10 9 9 9 9 8 10
.
.
.
N-Way 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
title;
options ls=80 ps=60 nonumber nodate;
data _null_;
array dests[&mm1] $ 10 _temporary_ (’Hawaii’ ’Alaska’ ’Mexico’
’California’ ’Maine’);
array scenes[3] $ 13 _temporary_
(’the Mountains’ ’a Lake’ ’the Beach’);
array lodging[3] $ 15 _temporary_
(’Cabin’ ’Bed & Breakfast’ ’Hotel’);
array x[15];
array p[&mm1];
length price $ 6;
file print linesleft=ll;
set [Link];
by block;
In practice, data collection may be much more elaborate than this. It may involve art work, photographs, and the
choice sets may be presented and data may be collected over the web. However the choice sets are presented and
the data collected, the essential ingredients remain the same. Subjects are shown sets of alternatives and asked to
make a choice, and then they go on to the next set.
data results;
input Subj Form (choose1-choose&n) (1.) @@;
datalines;
1 1 431313344341313133 2 2 314113115514415413 3 3 331313331143431411
4 4 431133311134311143 5 1 431151131141311333 6 2 111113113514335111
7 3 341513331311451134 8 4 431113211334311511 9 1 411121131141311153
.
.
.
;
The analysis proceeds in a fashion similar to before. Formats and the key to processing the design are created.
proc format;
value price 1 = ’ 999’ 2 = ’1249’ 3 = ’1499’ 4 = ’1749’;
value scene 1 = ’Mountains’ 2 = ’Lake’ 3 = ’Beach’;
value lodge 1 = ’Cabin’ 2 = ’Bed & Breakfast’ 3 = ’Hotel’;
value side 1 = ’Side Trip’ 2 = ’No’;
run;
data key;
input Place $ 1-10 (Lodge Scene Price Side) ($);
datalines;
Hawaii x1 x6 x11 x16
Alaska x2 x7 x12 .
Mexico x3 x8 x13 x17
California x4 x9 x14 .
Maine x5 x10 x15 .
. . . . .
;
168 TS-677E Multinomial Logit, Discrete Choice Modeling
For analysis, the design will have five attributes. Place is the alternative name. Lodge, Scene, Price and
Side are created from the design using the indicated factors. See page 133 for more information on creating
the design key. Notice that Side only applies to some of the alternatives and hence has missing values for the
others. Processing the design and merging it with the data are similar to what was done on pages 133 and 135.
One difference is now there are asymmetries in Price. For Hawaii’s price, x11, we need to change 1, 2, and
3 to $1249, $1499, and $1749. For Alaska’s price, x12, we need to change 1, 2, and 3 to $1249, $1499, and
$1749. For Mexico’s price, x13, we need to change 1, 2, and 3 to $999, $1249, and $1499. For California’s
price, x14, we need to change 1, 2, 3, and 4 to $999, $1249, $1499, and $1749. For Maine’s price, x11, we
need to change 1, 2, and 3 to $999, $1249, and $1499. We can simplify the problem by adding 1 to x11 and
x12, which are the factors that start at $1249 instead of $999. This will allow us to use a common format to set
the price. See page 211 for an example of handling more complicated asymmetries.
data temp;
set [Link];
x11 + 1;
x12 + 1;
run;
Indicator variables and labels are created using PROC TRANSREG like before.
proc transreg design=5000 data=res2 nozeroconstant norestoremissing;
model class(place / zero=none order=data)
class(price scene lodge / zero=none order=formatted)
class(place * side / zero=’ ’ ’No’ separators=’’ ’ ’) /
lprefix=0;
output out=coded(drop=_type_ _name_ intercept);
id subj set form c;
run;
proc print data=coded(obs=6) label;
run;
The design=5000 option specifies that no model is fit; the procedure is just being used to code a design
in blocks of 5000 observations at a time. The nozeroconstant option specifies that if the coding creates
a constant variable, it should not be zeroed. The norestoremissing option specifies that missing values
should not be restored when the out= data set is created. The model statement names the variables to code and
provides information about how they should be coded. The specification class(place / ...) specifies
that the variable Place is a classification variable and requests a binary coding. The zero=none option
creates binary variables for all categories. The order=data option sorts the levels into the order they were
first encountered in the data set. Similarly, the variables Price, Scene, and Lodge are classification variables.
The specification class(place * side / ...) creates alternative-specific side trip effects. The option
zero=’ ’ ’No’ specifies that dummy variables should be created for all levels of Place except blank, and
all levels of Side except ’No’. The specification zero=’ ’ is almost the same as zero=none. The zero=’
’ specification names a missing level as the reference level creating dummy variables for all nonmissing levels
of the class variables, just like zero=none. The difference is zero=none applies to all of the variables
named in the class specification. When you want zero=none to apply to only some variables, then you must
use zero=’ ’, as in zero=’ ’ ’No’ instead. In this case, zero=none applies to the first variable and
zero=’No’ applies to the second. With zero=’ ’, TRANSREG prints the following warning, which can be
safely ignored.
WARNING: Reference level ZERO=’’ was not found for variable Place.
The separators=” ’ ’ option (separators= quote quote space quote space quote) allows you to specify
two label component separators for the main effect and interaction terms, respectively. By specifying a blank for
the second value, we request labels for the side trip effects like ’Mexico Side Trip’ instead of the default
’Mexico * Side Trip’. This option is explained in more detail on page 177.
The lprefix=0 option specifies that when labels are created for the binary variables, zero characters of the
original variable name should be used as a prefix. This means that the labels are created only from the level
values. An output statement names the output data set and drops variables that are not needed. Finally, the id
statement names the additional variables that we want copied from the input to the output data set.
Obs Hawaii Alaska Mexico California Maine 999 1249 1499 1749 Beach Lake
1 1 0 0 0 0 0 0 0 1 1 0
2 0 1 0 0 0 0 1 0 0 0 1
3 0 0 1 0 0 0 1 0 0 0 1
4 0 0 0 1 0 1 0 0 0 1 0
5 0 0 0 0 1 0 0 1 0 1 0
6 0 0 0 0 0 0 0 0 0 0 0
170 TS-677E Multinomial Logit, Discrete Choice Modeling
1 0 0 1 0 0 0 0 0 0
2 0 0 1 0 0 0 0 0 0
3 0 0 1 0 0 0 0 0 1
4 0 1 0 0 0 0 0 0 0
5 0 0 1 0 0 0 0 0 0
6 0 0 0 0 0 0 0 0 0
The PROC PHREG specification is the same as we have used before. (Recall that we used %phchoice(on)on
page 79 to customize the output from PROC PHREG.)
proc phreg data=coded brief;
model c*c(2) = &_trgind / ties=breslow;
strata subj set;
run;
Here are the results.
Model Information
1 7200 6 1 5
Convergence Status
Without With
Criterion Covariates Covariates
Parameter Standard
DF Estimate Error Chi-Square Pr > ChiSq
You would not expect the part-worth utilities to match those that were used to generate the data, but you would
expect a similar ordering within each factor, and in fact that does occur. These data can also be analyzed with
quantitative price effects and destination by attribute interactions, as in the previous vacation example.
freq statement. Now, instead of analyzing a data set with 43,200 observations and 7200 strata, we analyze a
data set with at most 2 6 72 = 864 observations and 72 strata. For each of the 6 alternatives and 72 choice
sets, there are typically 2 observations in the aggregate data set: one that contains the number of times it was
chosen and one that contains the number of times it was not chosen. When one of those counts is zero, there will
be one observation. In this case, the aggregate data set has 726 observations.
proc summary data=coded nway;
class form set c &_trgind;
output out=agg(drop=_type_);
run;
Model Information
proc format;
value brand 1 = ’Brand 1’ 2 = ’Brand 2’ 3 = ’Brand 3’
4 = ’Brand 4’ 5 = ’Other’;
run;
data price;
array p[&m] p1-p&m; /* Prices for the Brands */
array f[&m] f1-f&m; /* Frequency of Choice */
Price = p[brand];
1 1 1 1 3.99 Brand 1
2 1 1 2 5.99 Brand 2
3 1 1 2 3.99 Brand 3
4 1 1 2 5.99 Brand 4
5 1 1 2 4.99 Other
6 2 1 1 3.99 Brand 1
7 2 1 2 5.99 Brand 2
8 2 1 2 3.99 Brand 3
9 2 1 2 5.99 Brand 4
10 2 1 2 4.99 Other
11 3 1 1 3.99 Brand 1
12 3 1 2 5.99 Brand 2
13 3 1 2 3.99 Brand 3
14 3 1 2 5.99 Brand 4
15 3 1 2 4.99 Other
Brand Choice Example with Aggregate Data 175
Note that the data set also contains the variables p1-p5 which contain the prices of each of the alternatives.
These variables, which are used in constructing the cross effects, will be discussed in more detail on page 179.
proc print data=price(obs=5);
run;
title2;
176 TS-677E Multinomial Logit, Discrete Choice Modeling
Here are the results. (Recall that we used %phchoice(on)on page 79 to customize the output from PROC
PHREG.)
Model Information
1 800 5 1 4
Convergence Status
Without With
Criterion Covariates Covariates
Parameter Standard
DF Estimate Error Chi-Square Pr > ChiSq
title2;
1 1 1 1 Brand 1 3.99 1 0 0 0
2 1 1 2 Brand 2 5.99 0 1 0 0
3 1 1 2 Brand 3 3.99 0 0 1 0
4 1 1 2 Brand 4 5.99 0 0 0 1
5 1 1 2 Other 4.99 0 0 0 0
6 2 1 1 Brand 1 3.99 1 0 0 0
7 2 1 2 Brand 2 5.99 0 1 0 0
8 2 1 2 Brand 3 3.99 0 0 1 0
9 2 1 2 Brand 4 5.99 0 0 0 1
10 2 1 2 Other 4.99 0 0 0 0
178 TS-677E Multinomial Logit, Discrete Choice Modeling
Model Information
1 800 5 1 4
Convergence Status
Without With
Criterion Covariates Covariates
Parameter Standard
DF Estimate Error Chi-Square Pr > ChiSq
The likelihood for this model is essentially the same as for the simpler, common-price-slope model fit previously,
2 log(LC ) = 2425:214 compared to 2424.812. You can test the null hypothesis that the two models are not
significantly different by comparing their likelihoods. The difference between two 2 log(LC )’s (the number
reported under ’With Covariates’ in the output) has a chi-square distribution. We can get the df for the test by
subtracting the two df for the two likelihoods. The difference 2425:214 2424:812 = 0:402 is distributed 2
with 8 5 = 3 df and is not statistically significant.
The input consists of Set, Subj, Brand, Price, and a choice time variable c. In addition, it contains five
variables p1 through p5. The first observation of the Price variable shows us that the first alternative costs
$3.99; p1 contains the cost of alternative 1, $3.99, which is the same for all alternatives. It does not matter which
alternative you are looking at, p1 shows that alternative 1 costs $3.99. Similarly, the second observation of the
Price variable shows us that the second alternative costs $5.99; p2 contains the cost of alternative 2, $5.99,
which is the same for all alternatives. There is one price variable, p1 through p5, for each of the five alternatives.
In all of the previous examples, we have used models that were coded so that the utility of an alternative only
depended on the attributes of that alternative. For example, the utility of Brand 1 would only depend on the Brand
1 name and its price. In contrast, p1-p5 contain information about each of the other alternatives’ attributes. We
will construct cross effects using the interaction of p1-p5 and the Brand variable. In a model with cross effects,
the utility for an alternative depends on both that alternative’s attributes and the other alternatives’ attributes. The
IIA (independence from irrelevant alternatives) property states that utility only depends on an alternative’s own
attributes. Cross effects add other alternative’s attributes to the model, so they can be used to test for violations
of IIA. (See pages 185, 192, 379, and 383 for other discussions of IIA.) Here is the PROC TRANSREG code for
180 TS-677E Multinomial Logit, Discrete Choice Modeling
1 1 1 1 Brand 1 3.99
2 1 1 2 Brand 2 5.99
3 1 1 2 Brand 3 3.99
4 1 1 2 Brand 4 5.99
5 1 1 2 Other 4.99
The effects ’Brand 1’ through ’Other’ in the next output are the binary brand effect variables. They indi-
cate the brand for each alternative. The effects ’Brand 1 Price’ through ’Other Price’ are alternative-
specific price effects. They indicate the price for each alternative. All ten of these variables are independent
variables in the analysis, and their names are part of the &- trgind macro variable list, as are all of the cross
effects that are described next.
Brand Choice Example with Aggregate Data 181
The effects ’Brand 1 on Brand 1’ through ’Brand 1 on Other’ in the next output are the first five
cross effects.
They represent the effect of Brand 1 at its price on the utility of each alternative. The label ’Brand n on
Brand m’ is read as ’the effect of Brand n at its price on the utility of Brand m.’ For the first choice set, these
first five cross effects consist entirely of zeros and $3.99’s, where $3.99 is the price of Brand 1 in this choice set.
The nonzero value is constant across all of the alternatives in each choice set since Brand 1 has only one price
in each choice set. Notice the ’Brand 1 on Brand 1’ term, which is the effect of Brand 1 at its price on
the utility of Brand 1. Also notice the ’Brand 1 Price’ effect, which is shown in the previous output. The
description ’the effect of Brand 1 at its price on the utility of Brand 1’ is just a convoluted way of describing
the Brand 1 price effect. The ’Brand 1 on Brand 1’ cross effect is the same as the Brand 1 price effect,
hence when we do the analysis, we will see that the coefficient for the ’Brand 1 on Brand 1’ cross effect
is zero.
The effects ’Brand 2 on Brand 1’ through ’Brand 2 on Other’ in the next output are the next five
cross effects.
They represent the effect of Brand 2 at its price on the utility of each alternative. For the first choice set, these
five cross effects consist entirely of zeros and $5.99’s, where $5.99 is the price of Brand 2 in this choice set. The
nonzero value is constant across all of the alternatives in each choice set since Brand 2 has only one price in each
choice set. Notice the ’Brand 2 on Brand 2’ term, which is the effect of Brand 2 at its price on the utility
of Brand 2. The description “the effect of Brand 2 at its price on the utility of Brand 2” is just a convoluted way
of describing the Brand 2 price effect. The ’Brand 2 on Brand 2’ cross effect is the same as the Brand
2 price effect, hence when we do the analysis, we will see that the coefficient for the ’Brand 2 on Brand
2’ cross effect is zero.
The effects ’Brand 3 on Brand 1’ through ’Brand 3 on Other’ in the next output are the next five
cross effects.
They represent the effect of Brand 3 at its price on the utility of each alternative. For the first choice set, these
five cross effects consist entirely of zeros and $3.99’s, where $3.99 is the price of Brand 3 in this choice set.
Notice that the ’Brand 3 on Brand 3’ term is the same as the Brand 3 price effect, hence when we do the
analysis, we will see that the coefficient for the ’Brand 3 on Brand 3’ cross effect is zero.
Here are the remaining cross effects. They follow the same pattern that was described for the previous cross
effects.
We have been describing variables by their labels. While it is not necessary to look at it, the &- trgind macro
variable name list that PROC TRANSREG creates for this problem is as follows:
%put &_trgind;
BrandBrand_1 BrandBrand_2 BrandBrand_3 BrandBrand_4 BrandOther
BrandBrand_1Price BrandBrand_2Price BrandBrand_3Price BrandBrand_4Price
BrandOtherPrice p1BrandBrand_1 p1BrandBrand_2 p1BrandBrand_3 p1BrandBrand_4
p1BrandOther p2BrandBrand_1 p2BrandBrand_2 p2BrandBrand_3 p2BrandBrand_4
p2BrandOther p3BrandBrand_1 p3BrandBrand_2 p3BrandBrand_3 p3BrandBrand_4
p3BrandOther p4BrandBrand_1 p4BrandBrand_2 p4BrandBrand_3 p4BrandBrand_4
p4BrandOther p5BrandBrand_1 p5BrandBrand_2 p5BrandBrand_3 p5BrandBrand_4
p5BrandOther
The analysis proceeds in exactly the same manner as before.
proc phreg data=coded brief;
model c*c(2) = &_trgind / ties=breslow;
strata subj set;
run;
Brand Choice Example, Multinomial Logit Model
Discrete Choice with Cross Effects, Mother Logit
Model Information
1 800 5 1 4
Convergence Status
Without With
Criterion Covariates Covariates
Parameter Standard
DF Estimate Error Chi-Square Pr > ChiSq
four nonzero brand effects and a zero for the constant alternative
four nonzero alternative-specific price effects and a zero for the constant alternative
5 5 = 25 cross effects, the number of alternatives squared, but only (5 1) (5 2) = 12 of them are
nonzero (four brands not counting Other affecting each of the remaining three brands).
There are three cross effects for the effect of Brand 1 on Brands 2, 3, and 4.
There are three cross effects for the effect of Brand 2 on Brands 1, 3, and 4.
There are three cross effects for the effect of Brand 3 on Brands 1, 2, and 4.
There are three cross effects for the effect of Brand 4 on Brands 1, 2, and 3.
All coefficients for the constant (other) alternative are zero as are the cross effects of a brand on itself.
Brand Choice Example with Aggregate Data 185
The mother logit model is used to test for violations of IIA (independence from irrelevant alternatives). IIA means
the odds of choosing alternative ci over cj do not depend on the other alternatives in the choice set. Ideally, this
more general model will not significantly explain more variation in choice than the restricted models. Also, if IIA
is satisfied, few if any of the cross-effect terms should be significantly different from zero. (See pages 179, 192,
379, and 383 for other discussions of IIA.) In this case, it appears that IIA is not satisfied (the data are artificial),
so the more general mother logit model is needed. The chi-square statistic is 2424:812 2349:325 = 75:487
with 20 8 = 12 df (p < 0:0001).
You could eliminate some of the zero parameters by changing zero=none to zero=’Other’ and eliminating
p5 (p&m) from the model.
proc transreg design data=price nozeroconstant norestoremissing;
model class(brand / zero=’Other’ separators=’’ ’ ’) | identity(price)
identity(p1-p4) * class(brand / zero=’Other’ separators=’’ ’ on ’) /
lprefix=0;
output out=coded(drop=_type_ _name_ intercept);
label price = ’Price’
p1 = ’Brand 1’ p2 = ’Brand 2’ p3 = ’Brand 3’
p4 = ’Brand 4’;
id subj set c;
run;
You could also eliminate the brand by price effects and instead capture brand by price effects as the cross effect
of a variable on itself.
proc transreg design data=price nozeroconstant norestoremissing;
model class(brand / zero=’Other’ separators=’’ ’ ’)
identity(p1-p4) * class(brand / zero=’Other’ separators=’’ ’ on ’) /
lprefix=0;
output out=coded(drop=_type_ _name_ intercept);
label price = ’Price’
p1 = ’Brand 1’ p2 = ’Brand 2’ p3 = ’Brand 3’
p4 = ’Brand 4’;
id subj set c;
run;
In both cases, the analysis (not shown) would be run in the usual manner. Except for the elimination of zero
terms, and in the second case, the change to capture the price effects in the cross effects, the results are identical.
proc format;
value brand 1 = ’Brand 1’ 2 = ’Brand 2’ 3 = ’Brand 3’
4 = ’Brand 4’ 5 = ’Other’;
run;
data price2;
array p[&m] p1-p&m; /* Prices for the Brands */
array f[&m] f1-f&m; /* Frequency of Choice */
186 TS-677E Multinomial Logit, Discrete Choice Modeling
Price = p[brand];
end;
1 1 1 4 3.99 Brand 1
2 1 2 96 3.99 Brand 1
3 1 1 29 5.99 Brand 2
4 1 2 71 5.99 Brand 2
5 1 1 16 3.99 Brand 3
6 1 2 84 3.99 Brand 3
7 1 1 42 5.99 Brand 4
8 1 2 58 5.99 Brand 4
9 1 1 9 4.99 Other
10 1 2 91 4.99 Other
This data set has 5 brands times 2 observations times 8 choice sets for a total of 80 observations, compared to
100 5 8 = 4000 using the standard method. Two observations are created for each alternative within each
choice set. The first contains the number of people who chose the alternative, and the second contains the number
of people who did not choose the alternative.
Brand Choice Example with Aggregate Data 187
title2;
These steps produced the following results.
Model Information
Convergence Status
Without With
Criterion Covariates Covariates
Parameter Standard
DF Estimate Error Chi-Square Pr > ChiSq
The summary table is small with eight rows, one row per choice set. Each row represents 100 chosen alternatives
and 400 unchosen. The ’Analysis of Maximum Likelihood Estimates’ table exactly matches the one produced
by the standard analysis. The -2 LOG L statistics are different than before: 9793.486 now compared to 2425.214
previously. This is because the data are arrayed in this example so that the partial likelihood of the proportional
hazards model fit by PROC PHREG with the ties=breslow option is now proportional to not identical
to the likelihood for the choice model. However, the Model Chi-Square statistics, df, and p-values are the
same as before. The two corresponding pairs of -2 LOG L’s differ by a constant 9943:373 2575:101 =
9793:486 2425:214 = 7368:272 = 2 800 log(100). Since the 2 is the -2 LOG L without covariates minus
-2 LOG L with covariates, the constants cancel and the 2 test is correct for both methods.
The technique of aggregating the data and using a frequency variable can be used for other models as well, for
example with brand by price effects.
proc transreg design data=price2 nozeroconstant norestoremissing;
model class(brand / zero=none separators=’’ ’ ’) |
identity(price) / lprefix=0;
output out=coded(drop=_type_ _name_ intercept);
label price = ’Price’;
id freq set c;
run;
This step produced the following results. The only thing that changes from the analysis with one stratum for each
subject and choice set combination is the likelihood.
Model Information
Convergence Status
Without With
Criterion Covariates Covariates
Parameter Standard
DF Estimate Error Chi-Square Pr > ChiSq
Previously, with one stratum per choice set within subject, we compared these models as follows: “The difference
2425:214 2424:812 = 0:402 is distributed 2 with 8 5 = 3 df and is not statistically significant.” The
difference between two 2 log(LC )’s equals the difference between two 2 log(LB )’s, since the constant terms
(800 log(100)) cancel, 9793:486 9793:084 = 2425:214 2424:812 = 0:402.
The joint likelihood for all eight choice sets is the product of the likelihoods
Y
8
L =
C LC
k
k =1
Brand Choice Example with Aggregate Data 191
L = N L = 100100L
C
k
N B
k
B
k
Y
8
L =
B L =N
B
k
8N
L = 100
C
800
L
C
k =1
The two likelihoods are not exactly the same, because each choice set is designated as a separate stratum, instead
of each choice set within each subject.
The log likelihood for the choice model is
log(L ) = 1212:607
C
and 2 log(LC ) = 2425:214, which matches the earlier output. However, it is usually not necessary to obtain
this value.
192 TS-677E Multinomial Logit, Discrete Choice Modeling
Assuming that the ei follow an extreme value type I distribution, the conditional probabilities P (ijCa ) can be
found using the multinomial logit (MNL) formulation of McFadden (1974)
P
P (ijC ) = exp(V )=
a i j 2 a exp(V )
C j
One of the consequences of the MNL formulation is the property of independence from irrelevant alternatives
(IIA). Under the assumption of IIA, all cross effects are assumed to be equal, so that if a brand gains in utility, it
draws share from all other brands in proportion to their current shares. Departures from IIA exist when certain
subsets of brands are in more direct competition and tend to draw a disproportionate amount of share from each
other than from other members in the category.
IIA is frequently described using a transportation example. Say you have three alternatives for getting to work:
bicycle, car, or a blue bus. If a fourth alternative became available, a red bus, then according to IIA the red bus
should draw riders from the other alternatives in proportion to their current usage. However, in this case, IIA
would be violated, and instead the red bus would draw more riders from the blue bus than from car drivers and
bicycle riders.
Food Product Example with Asymmetry and Availability Cross Effects 193
The mother logit formulation of McFadden (1974) can be used to capture departures from IIA. In a mother logit
model, the utility for brand i is a function of both the attributes of brand i and the attributes of other brands. The
effect of one brand’s attributes on another is termed a cross effect. In the case of designs in which only subsets
Ca of the full shelf set C appear, the effect of the presence/absence of one brand on the utility of another is
termed an availability cross effect. (See pages 179, 185, 379, and 383 for other discussions of IIA.)
Set Up
In the frozen entrée example, there are five alternatives: the client’s brand, the client’s line extension, a national
branded competitor, a regional brand and a private label brand. Several regional and private labels can be tested
in each market, then aggregated for the final model. Note that the line extension is treated as a separate alternative
rather than as a level of the client brand. This enables us to model the source of volume for the new entry and
to quantify any cannibalization that occurs. Each brand is shown at either two or three price points. Additional
price points are included so that quadratic models of price elasticity can be tested. The indicator for the presence
or absence of a brand in the shelf set is coded using one level of the Price variable. The layout of factors and
levels is given in the following table.
In addition to intercepts and main effects, we also require that all two-way interactions within alternatives be
estimable: x2*x3, x2*x4, x3*x4 for the line extension and x6*x7 for private labels. This will enable us
to test for different price elasticities by form (stove-top versus microwaveable) and to see if the promotion works
better combined with a low price or with different forms. Using a linear model for x1-x8, the total number of
parameters including the intercept, all main effects, and two-way interactions with brand is 25. This assumes that
price is treated as qualitative. The actual number of parameters in the choice model is larger than this because of
the inclusion of cross effects. Using indicator variables to code availability, the systematic component of utility
for brand i can be expressed as:
P P P
V =a +
i i k
(b x ) +
ik ik j 6= z (d +
i j ij l
(g x ))
ijl jl
where
The xik and xjl could be expanded to include interaction and polynomial terms. In an availability-cross-effects
design, each brand is present in only a fraction of the choice sets. The size of this fraction or subdesign is
a function of the number of levels of the alternative-specific variable that is used to code availability (usually
price). For instance, if price has three valid levels and a fourth zero level to indicate absence, then the brand
will appear in only three out of four runs. Following Lazari and Anderson (1994), the size of each subdesign
determines how many model equations can be written for each brand in the discrete choice model. If Xi is
the subdesign matrix corresponding to Vi , then each Xi must be full rank to ensure that the choice set design
provides estimates for all parameters.
To create the design, a full-factorial candidate set is generated consisting of 3456 runs. It is then reduced to 2776
runs that contain between two and four brands so that the respondent is never required to compare more than four
brands at a time. In the model specification, we designate all variables as classification variables and require that
all main effects and two-way interactions within brands be estimable. The number of runs calculations are based
on the number of parameters that we wish to estimate in the various subdesigns Xi of X. Assuming that there is a
None alternative used as a reference level, the numbers of parameters required for various alternatives are shown
in the next table along with the sizes of the subdesigns (rounded down) for various numbers of runs. Parameters
for quadratic price models are given in parentheses. Note that the effect of private label being in a microwaveable
or stove-top form (stove/micro cross effect) is an explicit parameter under the client line extension.
Parameters
Client Private
Effect Client Line Extension Regional Label Competitor
intercept 1 1 1 1 1
availability cross effects 4 4 4 4 4
direct price effect 1 (2) 1 (2) 1 1 1
price cross effects 4 (8) 4 (8) 4 4 4
stove versus microwave - 1 - 1 -
stove/micro cross effects - 1 - - -
shelf-talker - 1 - - -
price*stove/microwave - 1 (2) - 1 -
price*shelf-talker - 1 (2) - - -
stove/micro*shelf-talker - 1 - - -
Subdesign size
22 runs 16 16 14 14 14
26 runs 19 19 17 17 17
32 runs 24 24 21 21 21
The subdesign sizes are computed by taking the floor of the number of runs from the marginal times the expected
proportion of runs in which the alternative will appear. For example, for the client brand which has three prices
and not available and 22 runs, oor(22 3=4) = 16; for the competitor and 32 runs, oor(32 2=3) = 21. The
number of runs chosen was n=26. This number provides adequate degrees of freedom for the linear price model
and will also allow estimation of direct quadratic price effects. To estimate quadratic cross effects for price would
require 32 runs at the very least. Although the technique of using two-way interactions between nominal level
variables will usually guarantee that all direct and cross effects are estimable, it is sometimes necessary and good
practice to check the ranks of the subdesigns for more complex models (Lazari and Anderson 1994).
We will use the %MktEx autocall macro to create the design. (All of the autocall macros used in this report are
documented starting on page 287.) To recap, we want to make the design 23 33 42 in 26 runs, and we want the
following interactions to be estimable: x2*x3 x2*x4 x3*x4 x6*x7. Furthermore, there are restrictions
on the design. Each of the price variables, x1, x2, x5, x6, and x8, has one level the maximum level
that indicates the alternative is not available in the choice set. We use this to create choice sets with 2, 3, or
4 alternatives available. If (x1 < 4) then the first alternative is available, if (x2 < 4) then the second
alternative is available, if (x5 < 3) then the third alternative is available, and so on. A Boolean term such as
(x1 < 4) is one when true and zero otherwise. Hence,
((x1 < 4) + (x2 < 4) + (x5 < 3) + (x6 < 3) + (x8 < 3))
is the number of available alternatives. This is simply the sum of some 1’s if available and 0’s if not available.
We impose restrictions with the %MktEx macro by writing a macro, with IML statements, that quantifies the
badness of each run (or in this case, each choice set). We do this so bad = 0 is good and values larger than zero
are increasingly worse. We write our restrictions using an IML row vector x that contains the levels (integers
beginning with 1) of each of the factors in the ith choice set, the one the macro is currently seeking to improve.
The jth factor is x[j]. or we may also use the factor names (for example, x1, x2). (See page 280 for other
examples of restrictions.)
We must use IML logical operators, which are not as rich as DATA step operators:
= equals not: EQ
^ = or : = not equals not: NE
< less than not: LT
<= less than or equal to not: LE
> greater than not: GT
>= greater than or equal to not: GE
& and not: AND
j or not: OR
^ or : not not: NOT
To restrict the design, we must specify restrictions=macro-name, in this case restrictions=bad, that
names the macro that quantifies badness. The first statement counts up the number of available alternatives. The
second sets the actual badness values. If bad (the number available) is less than two or greater than 4, then the
Boolean expression ((bad < 2) | (bad > 4)) is true or 1. When the expression is true, then bad gets set
to the absolute difference between the number available and 3. Hence, zero available corresponds to bad = 3,
one available corresponds to bad = 2, two through four available corresponds to bad = 0, and five available
corresponds to bad = 2. We could just set bad to zero when everything is fine and one otherwise, but it is
better to help the macro by letting it know that when it switches from zero available to one available, it is going
in the right direction. Here is the code.
title ’Consumer Food Product Example’;
%macro bad;
bad = (x1 < 4) + (x2 < 4) + (x5 < 3) + (x6 < 3) + (x8 < 3);
bad = abs(bad - 3) * ((bad < 2) | (bad > 4));
%mend;
The tabled design initialization part of the coordinate-exchange algorithm iterations will be initialized with the
first 26 rows of a 27 run fractional-factorial design. This design has 13 three-level factors, ten of which are used
to make 23 33 42 . The initial design will be unbalanced and one row short of orthogonal, so we would expect
that other methods would be better for this problem. The macro also tells us that it is performing 60 PROC
OPTEX searches of 2776 candidates, and that the full-factorial design has 3456 runs. The macro is searching
the full-factorial design minus the excluded choice sets. Since the full-factorial design is not too large (less than
5000), and since there is not tabled design that is very good for this problem, this is the kind of problem where
we would expect the PROC OPTEX algorithm to work best. The macro chose 60 OPTEX iterations. In the
fabric softener example, the macro did not try any OPTEX iterations, because it knew it could directly make a
100% efficient design. In the vacation examples, it ran the default minimum of 20 OPTEX iterations because the
macro’s heuristics concluded that OPTEX would probably not be the best approach for those problems. In this
example, the macro’s heuristics tried more iterations since this is the kind of example where OPTEX works best.
Here is some of the output.
Current Best
Design Row,Col D-Efficiency D-Efficiency Notes
----------------------------------------------------------
1 Start 84.3176 Can
1 2 1 84.3176 84.3176 Conforms
1 End 84.3176
.
.
.
.
.
.
Current Best
Design Row,Col D-Efficiency D-Efficiency Notes
----------------------------------------------------------
0 Initial 84.3176 84.3176 Ini
Current Best
Design Row,Col D-Efficiency D-Efficiency Notes
----------------------------------------------------------
0 Initial 85.4271 85.4271 Ini
.
.
.
x1 4 1 2 3 4
x2 4 1 2 3 4
x3 2 1 2
x4 2 1 2
x5 3 1 2 3
x6 3 1 2 3
x7 2 1 2
x8 3 1 2 3
198 TS-677E Multinomial Logit, Discrete Choice Modeling
Average
Prediction
Design Standard
Number D-Efficiency A-Efficiency G-Efficiency Error
------------------------------------------------------------------------
1 85.4271 72.0480 98.0611 0.9806
Design 1 (Can), which was created by the candidate-set search (using PROC OPTEX), had D-efficiency or
84.3176, and the macro confirms that the design conforms to our restrictions. The tabled, unbalanced, and
random initializations do not work as well. For each design, the macro iteration history states the D-efficiency
for the initial design (49.1839 in design 2), the D-efficiency when the restrictions are met (77.7982, Conforms),
and the D-efficiency for the final design (79.6170). The fully random initialization tends to work a little better
than the tabled initialization for this problem, but not as well as PROC OPTEX. At the end of the algorithm
search phase, the macro decides to use PROC OPTEX and performs 600 more searches, and it finds a design
with 85.4271% D-efficiency. The design refinement step fails to improve on the best design. This step took 15
minutes.
As we will see in the next section, it turns out that this is a very good design for this example. Usually, for this
problem, we see final D-efficiencies less than 85.3. How did we happen to find a design this good? We just got
lucky. The random number seed that happened to go into the second OPTEX run, which was a function of all of
the random numbers generated previously by both OPTEX and the coordinate-exchange algorithm, was a really
good one.
subsequent iterations will give you slight improvements but with a cost of much greater run times. Next, we will
construct a plot of this table.
data; input n e; datalines;
1 83.8959
2 83.9890
3 84.3763
6 84.7548
84 85.1561
1535 85.3298
9576 85.3985
;
proc gplot;
title h=1 ’Consumer Food Product Example’;
title2 h=1 ’Maximum D-Efficiency Found Over Time’;
plot e * n / vaxis=axis1;
symbol i=join;
axis1 order=(0 to 90 by 10);
run; quit;
title2;
The plot of maximum D-efficiency as a function of PROC OPTEX run number clearly shows that the gain in
efficiency that comes from a large number of iterations is very slight.
If you have a lot of time to search for a good design, you can specify some of the time and maximum number
of iteration parameters. Sometimes you will get lucky and find a better design. In this next example, max-
time=300 300 60 was specified. This give the macro up to 300 minutes for the algorithm search step, 300
minutes for the design search step, and 60 minutes for the refinement step. The option maxiter= increases
the number iterations to 10000 for each of the three steps (or the maximum time). With this specification, you
would expect the macro to run overnight. See the macro documentation (starting on page 327) for more iteration
options. Note that you must increase the number of iterations and the maximum amount of time if you want the
macro to run longer. With this specification, the macro performs 1800 OPTEX iterations initially (compared to
60 by default).
200 TS-677E Multinomial Logit, Discrete Choice Modeling
%macro bad;
bad = (x1 < 4) + (x2 < 4) + (x5 < 3) + (x6 < 3) + (x8 < 3);
bad = abs(bad - 3) * ((bad < 2) | (bad > 4));
%mend;
x1 x2 x3 x4 x5 x6 x7 x8
r r Square
x2 x6 0.50 0.25
x1 x5 0.42 0.17
x2 x5 0.38 0.14
x1 x2 0.37 0.13
Food Product Example with Asymmetry and Availability Cross Effects 201
Frequencies
* x1 6 5 7 8
* x2 6 6 6 8
x3 13 13
x4 13 13
* x5 8 9 9
* x6 10 8 8
* x7 14 12
* x8 9 9 8
* x1 x2 2 2 0 2 1 0 2 2 1 2 2 2 2 2 2 2
* x1 x3 3 3 3 2 3 4 4 4
* x1 x4 3 3 3 2 3 4 4 4
* x1 x5 2 1 3 2 1 2 2 2 3 2 5 1
* x1 x6 2 2 2 1 2 2 3 1 3 4 3 1
* x1 x7 4 2 3 2 3 4 4 4
* x1 x8 2 3 1 2 1 2 2 2 3 3 3 2
* x2 x3 3 3 3 3 3 3 4 4
* x2 x4 3 3 3 3 3 3 4 4
* x2 x5 1 3 2 2 2 2 1 3 2 4 1 3
* x2 x6 0 3 3 4 1 1 2 1 3 4 3 1
* x2 x7 3 3 2 4 4 2 5 3
* x2 x8 2 2 2 2 2 2 2 2 2 3 3 2
* x3 x4 7 6 6 7
* x3 x5 4 5 4 4 4 5
* x3 x6 4 4 5 6 4 3
* x3 x7 6 7 8 5
* x3 x8 5 4 4 4 5 4
* x4 x5 5 3 5 3 6 4
* x4 x6 5 4 4 5 4 4
* x4 x7 7 6 7 6
* x4 x8 5 4 4 4 5 4
* x5 x6 3 3 2 3 3 3 4 2 3
* x5 x7 3 5 5 4 6 3
* x5 x8 3 2 3 3 3 3 3 4 2
* x6 x7 6 4 4 4 4 4
* x6 x8 2 5 3 3 2 3 4 2 2
* x7 x8 4 6 4 5 3 4
N-Way 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1
Some of the canonical correlations are bigger than we would like. They all involve attributes in different alterna-
tives, so they should not pose huge problems. Still, they are large enough to make some researchers uncomfort-
able. The frequencies are pretty close to balanced. Perfect balance is not possible with 26 choice sets and this
design. If we were willing to consider blocking the design, we might do better with more choice sets.
202 TS-677E Multinomial Logit, Discrete Choice Modeling
Design Summary
Number of
Levels Frequency
2 3
3 3
4 2
Saturated = 16
Full Factorial = 3,456
144 0
72 1 16
48 3 9
96 3 9
192 3 9
24 4 9 16
120 4 9 16
168 4 9 16
36 7 8 16
108 7 8 16
The smallest suggestion larger than 26 is 36. With this mix of factor levels, we would have to have 144 runs
to get an orthogonal design, so we will definitely want to stick with a nonorthogonal design. Balance will be
possible in 36 runs, but 36 cannot be divided by 2 4 = 8 and 4 4 = 16. With 36 runs, a blocking factor will
be required (2 blocks of 18 or 3 blocks of 12). We would like the shelf-talker to appear in half of the choice sets
within block, so with two blocks, we will want the number of choice sets to be divisible by 2 2 = 4, and 36
can be divided by 4. The %MktRuns macro cannot provide us with much guidance with the interactions. We
“tricked” it in the past by substituting products of levels, like 9 = 3 3, but in this case, factors like x2, x3, and
x4 interact multiple times, so it would not be that simple. We will try making a design in 36 runs, and see how
it looks.
title ’Consumer Food Product Example’;
%macro bad;
bad = (x1 < 4) + (x2 < 4) + (x5 < 3) + (x6 < 3) + (x8 < 3);
bad = abs(bad - 3) * ((bad < 2) | (bad > 4));
%mend;
%mkteval;
Food Product Example with Asymmetry and Availability Cross Effects 203
Here is the last part of the output from the %MktEx macro.
Prediction
Design Standard
Number D-Efficiency A-Efficiency G-Efficiency Error
------------------------------------------------------------------------
1 94.6814 89.3664 94.3049 0.8333
x1 x2 x3 x4 x5 x6 x7 x8
r r Square
x2 x6 0.39 0.15
Frequencies
* x1 8 10 8 10
* x2 10 8 8 10
x3 18 18
x4 18 18
* x5 9 11 16
* x6 13 11 12
x7 18 18
* x8 12 9 15
.
.
.
204 TS-677E Multinomial Logit, Discrete Choice Modeling
The correlations are better, although we still have one a bit larger than we would like. However, the biggest
problem is that the balance is much worse than we would like. We can run the macro again, this time specifying
balance=2, which forces better balance. The specification of 2 allows the maximum frequency for a level in a
factor to be no more than two greater than the minimum frequency.
%mktex( 4 4 2 2 3 3 2 3, n=36, interact=x2*x3 x2*x4 x3*x4 x6*x7,
restrictions=bad, seed=377, outr=[Link], balance=2 )
%mkteval;
Here is the last part of the output from the %MktEx macro.
Average
Prediction
Design Standard
Number D-Efficiency A-Efficiency G-Efficiency Error
------------------------------------------------------------------------
1 94.0824 88.3946 93.3172 0.8333
The D-efficiency looks good. It is a little lower than before, but not much. Here is the first part of the output
from the %MktEval macro.
x1 x2 x3 x4 x5 x6 x7 x8
r r Square
x2 x8 0.32 0.10
Food Product Example with Asymmetry and Availability Cross Effects 205
The canonical correlations look good. One is just large enough to be flagged (0:32 > 0:316), but r2 is only 0.1.
Here is the last part of the output from the %MktEval macro.
Frequencies
* x1 8 10 9 9
* x2 8 8 10 10
x3 18 18
x4 18 18
* x5 11 13 12
* x6 11 12 13
* x7 17 19
x8 12 12 12
* x1 x2 2 2 2 2 2 2 2 4 2 3 2 2 2 1 4 2
* x1 x3 4 4 5 5 5 4 4 5
* x1 x4 4 4 5 5 5 4 4 5
* x1 x5 3 2 3 3 4 3 2 3 4 3 4 2
* x1 x6 2 3 3 2 4 4 3 2 4 4 3 2
* x1 x7 3 5 5 5 4 5 5 4
* x1 x8 3 2 3 3 4 3 3 3 3 3 3 3
* x2 x3 4 4 4 4 5 5 5 5
* x2 x4 4 4 4 4 5 5 5 5
* x2 x5 2 3 3 2 3 3 4 2 4 3 5 2
* x2 x6 2 3 3 2 2 4 4 3 3 3 4 3
* x2 x7 4 4 3 5 5 5 5 5
* x2 x8 2 2 4 2 2 4 4 4 2 4 4 2
x3 x4 9 9 9 9
* x3 x5 5 6 7 6 7 5
* x3 x6 5 7 6 6 5 7
* x3 x7 7 11 10 8
x3 x8 6 6 6 6 6 6
* x4 x5 6 6 6 5 7 6
* x4 x6 6 6 6 5 6 7
* x4 x7 8 10 9 9
x4 x8 6 6 6 6 6 6
* x5 x6 4 4 3 3 4 6 4 4 4
* x5 x7 6 5 6 7 5 7
* x5 x8 4 3 4 4 4 5 4 5 3
* x6 x7 5 6 6 6 6 7
* x6 x8 4 4 3 4 4 4 4 4 5
* x7 x8 6 6 5 6 6 7
N-Way 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
This design looks much better. It is possible to get designs with better balance by specifying balance=1, but
for this problem, the price in efficiency is too high. We do want to ensure that x4, the shelf talker factor is
balanced, since we will be dividing the design into two parts, depending on whether the shelf talker is there or
not. It is balanced in this design. If it had not been, we could have switched it with another two-level factor
or tried again with a different seed. If nothing else worked, we could have added it after the fact by blocking
(running the %MktBlock macro as if we were adding a blocking factor).
206 TS-677E Multinomial Logit, Discrete Choice Modeling
The balance= option in the %MktEx macro works by adding restrictions to the design. The approach it uses
often works quite well, but sometimes it does not. Forcing balance gives the macro much less freedom in its
search, and makes it easy for the macro to get stuck in suboptimal designs. Most of our restrictions are imposed
within each row. Those kinds of restrictions do not pose a problem for the macro. Balance restrictions are
imposed across rows within a column. We know of better ways to impose balance, but they tend to be very slow.
This is an area where more research is needed, and the way this option works will quite likely be different in
future releases. If perfect balance is critical, try the %MktBal macro.
%mkteval(data=desv)
%mend;
%evaleff(x1 ne 4)
%evaleff(x2 ne 4)
%evaleff(x5 ne 3)
%evaleff(x6 ne 3)
%evaleff(x8 ne 3)
Each step took just over two seconds. We hope to not see any efficiencies of zero, and we hope to not get the mes-
sage WARNING: Can’t estimate model parameters in the final design. Here are some
of the results.
Average
Prediction
Design Standard
Number D-Efficiency A-Efficiency G-Efficiency Error
------------------------------------------------------------------------
1 66.9776 54.6662 82.8184 0.6939
Food Product Example with Asymmetry and Availability Cross Effects 207
Average
Prediction
Design Standard
Number D-Efficiency A-Efficiency G-Efficiency Error
------------------------------------------------------------------------
1 73.7719 66.4421 87.3561 0.7071
Average
Prediction
Design Standard
Number D-Efficiency A-Efficiency G-Efficiency Error
------------------------------------------------------------------------
1 69.9539 59.0519 83.0652 0.7360
Average
Prediction
Design Standard
Number D-Efficiency A-Efficiency G-Efficiency Error
------------------------------------------------------------------------
1 70.8672 57.5401 80.8955 0.7518
Average
Prediction
Design Standard
Number D-Efficiency A-Efficiency G-Efficiency Error
------------------------------------------------------------------------
1 65.7047 50.8521 84.5539 0.7360
Intercept
x1
x2
x3
x4
x5
x6
x7
x8
208 TS-677E Multinomial Logit, Discrete Choice Modeling
x2*x3
x2*x4
x3*x4
x6*x7
Contrast this with a specification that includes all simple effects and two-way and three-way interactions. We
specify the model of interest first, so all of those terms will be listed first, then we specify all main effects
and two-way and three-way interactions using the notation x1|x2|x3|x4|x5|x6|x7|x8@3. This list will
generate all of the effects of interest, x1-x8 x2*x3 x2*x4 x3*x4 x6*x7, and all of the two-way and
three-way interactions. It is not a problem that some of the interactions were both explicitly specified and also
generated by the x1|x2|x3|x4|x5|x6|x7|x8@3 list since PROC GLM automatically eliminates duplicate
terms.
proc glm data=temp;
model y = x1-x8 x2*x3 x2*x4 x3*x4 x6*x7
x1|x2|x3|x4|x5|x6|x7|x8@3 / e aliasing;
run;
Again, we have a list of linear combinations that are estimable. This shows that the Intercept cannot be
estimated independently of the x4*x6 interaction and a bunch of others including four-way though eight-way
interactions which were not specified and hence not shown. Similarly, x1 is confounded with a bunch of in-
teractions, and so on. This is why we want to be estimable the two-way interactions between factors that are
combined to create an alternative. We did not want something like x2*x3, the client-line extension’s price and
microwave/stove top interaction to be confounded with say another brand’s price.
Food Product Example with Asymmetry and Availability Cross Effects 209
The first attempt (not shown) produced a design where x4, the shelf talker did not occur equally often within
each block. Changing the seed took care of the problem. Here are the canonical correlations.
Block x1 x2 x3 x4 x5 x6 x7 x8
The blocking variable is not highly correlated with any of the factors. Here are some of the frequencies.
Frequencies
Block 18 18
* x1 8 10 9 9
* x2 8 8 10 10
x3 18 18
x4 18 18
* x5 11 13 12
* x6 11 12 13
* x7 17 19
x8 12 12 12
* Block x1 4 5 4 5 4 5 5 4
* Block x2 4 4 5 5 4 4 5 5
Block x3 9 9 9 9
Block x4 9 9 9 9
* Block x5 6 6 6 5 7 6
* Block x6 6 6 6 5 6 7
* Block x7 9 9 8 10
* Block x8 5 6 7 7 6 5
210 TS-677E Multinomial Logit, Discrete Choice Modeling
The blocking variable is perfectly balanced, as it is guaranteed to be if the number of blocks divides the number
of runs. Balance within blocks, that is the cross-tabulations of the factors with the blocking variable, looks good.
The macro also prints canonical correlations within blocking variables. These can sometimes be quite high, even
1.0, but that is not a problem. Here is the design, as it is printed by the %MktBlock macro.
Block Run x1 x2 x3 x4 x5 x6 x7 x8
1 1 3 2 1 1 1 1 2 3
2 4 4 1 2 2 2 1 3
3 3 4 2 2 1 3 1 2
4 4 3 1 2 1 1 1 1
5 4 4 2 1 3 1 2 1
6 3 1 2 1 2 2 2 3
7 1 1 1 2 1 2 2 3
8 2 1 1 1 3 3 2 3
9 2 2 1 2 3 3 1 3
10 1 3 2 2 3 2 1 2
11 2 2 2 1 2 3 1 2
12 2 4 1 2 2 1 2 1
13 1 1 2 1 1 3 1 1
14 3 3 1 2 3 1 2 2
15 4 3 2 2 2 3 1 3
16 2 4 2 1 2 2 1 2
17 4 3 2 1 1 1 2 2
18 1 2 1 1 3 2 2 1
Block Run x1 x2 x3 x4 x5 x6 x7 x8
2 1 4 2 2 2 1 2 1 1
2 3 1 1 2 3 2 1 1
3 4 1 2 2 2 3 2 3
4 3 4 1 1 2 3 1 1
5 2 3 1 1 1 2 1 3
6 2 3 2 2 1 3 2 1
7 4 3 1 1 3 2 2 2
8 2 4 1 1 1 2 2 2
9 3 3 2 1 3 1 1 1
10 1 3 1 1 2 3 2 1
11 2 4 2 2 2 2 2 1
12 2 1 2 2 3 1 1 2
13 3 2 1 2 2 3 2 2
14 3 2 2 1 3 3 2 3
15 1 4 2 1 1 1 1 3
16 4 1 1 1 2 1 1 2
17 1 2 2 2 2 1 2 3
18 1 4 1 2 3 3 2 2
Ideally, each subject would only make one choice, since the choice model is based on this assumption (which is almost always ignored).
As the number of blocks increases, the correlations will mostly go to one, and ultimately be undefined when there is only one choice set per
block.
Food Product Example with Asymmetry and Availability Cross Effects 211
The choice design will need a quantitative price factor, make from all five of the linear price factors, that contains
the prices of each of the alternatives. At this point, our factor x1 contains 1, 2, 3, 4, and not 1.29, 1.69, 2.09, and
absent, which is different from x2 and from all of the other factors. A 1 in x1 will need to become a price of
1.29 in the choice design, a 1 in x2 will need to become a price of 1.39 in the choice design, a 1 in x3 will need
to become a price of 1.99 in the choice design, and so on. Before we use the %MktRoll macro to turn the linear
design into a choice design, we need to use the %MktLab macro to assign the actual prices to the price factors.
The %MktLab macro is like the %MktRoll macro in the sense that it can use as input a key= data set that
contains the rules for customizing a design for our particular usage. In the %MktRoll macro, the key= data
set provides the rules for turning a linear design into a choice design. In contrast, in the %MktLab macro, the
key= data set contains the rules for turning a linear design into another linear design, changing one or more of
the following: factor names, factor levels, factor types (numeric to character), level formats, and factor labels.
We could use the %MktLab macro to change the names of the variables and their types, but we will not do that
for this example. Ultimately, we will use the %MktRoll macro to assign all of the price factors to a variable
called Price and similarly provide meaningful names for all of the factors in the choice design, just as we have
in previous examples. We could also change a variable like x3 with values of 1 and 2 to something like Stove
with values ’Stove’ and ’Micro’. We will not do that because we want to make a design with a simple list
of numeric factors, with simple names like x1-x8 that we can run through the %MktRoll macro to get the final
choice design. We will assign formats and labels, so we can print the design in a meaningful way, but ultimately,
our only goal at this step is to handle the price asymmetries by assigning the actual price values to the factors.
The key= data set contains the rules for customizing our design. The data set has as many rows as the maximum
number of levels, in this case four. Each variable is one of the factors in the design, and the values are the factor
levels that we want in the final design. The first factor, x1, is the price factor for the client brand. Its levels are
1.29, 1.69, and 2.09. In addition, one level is ’not available’, which is flagged by the SAS special missing value
.N. In order to read special missing values in an input data set, you must use the missing statement and name
the expected missing values. The factor x2 has the same structure as x1, but with different levels. The factor
x3 has two levels, hence the key= data set has missing values in the third and fourth row. Since the design
has only 1’s and 2’s for x3, this missing values will never be used. Notice that we are keeping x3 as a numeric
variable with values 1 and 2 using a format to supply the character levels ’micro’ and ’stove’. The other factors
212 TS-677E Multinomial Logit, Discrete Choice Modeling
are created in a similar fashion. You may not use ordinary missing ’.’ for levels. You may only use ordinary
missing values as place holders for factors that have fewer levels than the maximum. If you want missing values
in the levels, you must use one of the special missing values .A, .B, ..., .Z, and .- .
The %MktLab macro specification names the input SAS data set with the design. By default, it looks for an
input key= data set named KEY and creates an output SAS data set called FINAL. The data set is sorted by
block and shelf talker and printed.
proc format;
value yn 1 = ’ No’ 2 = ’Talker’;
value micro 1 = ’Micro’ 2 = ’Stove’;
run;
data key;
missing N;
input x1-x8;
format x1 x2 x5 x6 x8 dollar5.2
x4 yn. x3 x7 micro.;
label x1 = ’Client Brand’
x2 = ’Client Line Extension’
x3 = ’Client Micro/Stove’
x4 = ’Shelf Talker’
x5 = ’Regional Brand’
x6 = ’Private Label’
x7 = ’ Private Micro/Stove’
x8 = ’National Competitor’;
datalines;
1.29 1.39 1 1 1.99 1.49 1 1.99
1.69 1.89 2 2 2.49 2.29 2 2.39
2.09 2.39 . . N N . N
N N . . . . . .
;
%mktlab(data=[Link], key=key)
In contrast, here are the actual values without formats and labels.
proc print data=[Link]; format _numeric_; run;
Obs x1 x2 x3 x4 x5 x6 x7 x8 Block
One issue remains to be resolved regarding this design and that concerns the role of the shelf-talker when the
client line extension is not available. The second part of each block of the design consists of choice sets in which
the shelf-talker is present and calls attention to the client line extension. However, in five of those choice sets,
the client line extension is unavailable. This problem can be handled in several ways. Here are a few:
Rerun the design creation and evaluation programs excluding all choice sets with shelf-talker present and
client line extension unavailable. However, this requires changing the model because the excluded cell
will make unestimable the interaction between client-line-extension price and shelf-talker. Furthermore,
the shelf-talker variable will almost certainly no longer be balanced.
Move the choice sets with client line extension unavailable to the no-shelf-talker block and rerandomize.
The shelf-talker is then on for all of the last nine choice sets.
Let the shelf-talker go on and off as needed.
Food Product Example with Asymmetry and Availability Cross Effects 215
Let the shelf-talker call attention to a brand that happens to be out of stock. It is easy to imagine this
happening in a real store.
Other options are available as well. No one approach is obviously superior to the alternatives. For this example,
we will take the latter approach and allow the shelf-talker to be on even when the client line extension is not
available. Note that if the shelf-talker is turned off when the client line extension is not available then the design
must be manually modified to reflect this fact.
Obs x1 x2 x3 x4 x5 x6 x7 x8 Block
Set 1, Alternative 1
Set 1, Alternative 2
Notice that x1 through x8 are constant within each choice set. The variable x1 is the price of alternative one,
which is the same no matter which alternative it is stored with.
We need to do a few more things to this design before we are ready to use it. Since we will be treating all of the
price factors as a quantitative (not a class variable), we need to convert the missing prices to zero. We also
need to convert the missings for when Micro and Shelf do not apply to 2 for ’Stove’ and 1 for ’No’. We also
need to assign formats. Eventually, we will also need to output just the alternatives that are available (those with
a nonzero price and also the none alternative). For now, we will just make a variable w that flags the available
alternative (w = 1).
Food Product Example with Asymmetry and Availability Cross Effects 217
data [Link](drop=i);
set rolled;
array x[6] price x1 -- x8;
do i = 1 to 6; if nmiss(x[i]) then x[i] = 0; end;
if nmiss(micro) then micro = 2;
if nmiss(shelf) then shelf = 1;
w = brand eq ’None’ or price ne 0;
format price dollar5.2 shelf yn. micro micro.;
run;
Now our choice design is done except for the final coding for the analysis. We can now use the %ChoicEff
macro to evaluate it for a choice model. Normally, you would use this macro to search a candidate set for an
efficient choice design. You can also use it to evaluate a design created by other means. Here is some sample
code, omitting for now the details of the model (indicated by model= ...). The complicated part of this is the
model due to the alternative-specific price effects and cross effects. For now, let’s concentrate on everything else.
%choiceff(data=[Link],
model= ..., /* model specification skipped for now */
nsets=36, nalts=6, weight=w,
beta=zero, init=[Link](keep=set),
intiter=0);
The way you check the efficiency of a design like this is to first name it on the data= option. This will be the
candidate set that contains all of the choice sets that we will consider. In addition, the same design is named on
the init= option. The full specification is init=[Link](keep=set). Just the variable
Set is kept. It will be used to bring in just the indicated choice sets from the data= design, which in this
case is all of them. The option nsets=36 specifies the number of choice sets, and nalts=6 specifies the
number of alternatives. This macro requires a constant number of alternatives in each choice set for ease of data
management. However, not all of the alternatives have to be used. In this case, we have an availability study. We
need to keep the unavailable alternatives in the design for this step, but we do not want them to contribute to the
analysis, so we specify a weight variable with weight=w and flag the available alternatives with w=1 and the
unavailable alternatives with w=0. The option beta=zero specifies that we are assuming for design evaluation
purpose all zero betas. We can specify other values and get other results for the variances and standard errors.
Finally, we specify intiter=0 which specifies zero internal iterations. We use zero internal iterations when
we want to evaluate an initial design, but not attempt to improve it. Here is the actual specification we will use,
complete with the model specification.
218 TS-677E Multinomial Logit, Discrete Choice Modeling
%choiceff(data=[Link],
model=class(brand / zero=’None’)
class(brand / zero=’None’ separators=’’ ’ ’) *
identity(price)
class(shelf micro / lprefix=5 0 zero=’No’ ’Stove’)
identity(x1 x2 x5 x6 x8) *
class(brand / zero=’None’ separators=’ ’ ’ on ’) /
lprefix=0 order=data,
nsets=36, nalts=6, weight=w,
beta=zero, init=[Link](keep=set),
intiter=0);
The specification class(brand / zero=’None’) specifies the brand effects. This specification will
create dummy variables for brand with the constant alternative being the reference brand. The option
zero=’None’ ensures that the reference level will be ’None’ instead of the default last sorted level (’Re-
gional’). Dummy variables will be created for the brands Client, Extension, Regional, Private, and National, but
not None. The zero=’None’ option, like zero=’Home’ and other zero=’literal-string’ options we have
used in previous examples, names the actual formatted value of the class variable that should be excluded from
the coded variables because the coefficient will be zero. Do not confuse zero=none and zero=’None’. The
zero=none option specifies that you want all dummy variables to be created, even including one for the last
level. In contrast, the option zero=’None’ (or zero= any quoted string) names a specific formatted value, in
this case ’None’, for which dummy variables are not to be created.
The specification class(brand / ...) * identity(price) creates the alternative-specific price
effects. They are specified as an interaction between a categorical variable Brand and a quantitative factor
Price. The separators=” ’ ’ option in the class specification specifies the separators that are used
to construct the labels for the main effect and interaction terms. The main-effects separator, which is the first
separators= value, ”, is ignored since lprefix=0. Specifying ’ ’ as the second value creates labels of
the form brand-blank-price instead of the default brand-blank-asterisk-blank-price.
The specification class(shelf micro / ...) names the shelf talker and microwave variables as cat-
egorical variables and creates dummy variables for the ’Talker’ category, not the ’No’ category and the
’Micro’ category not the ’Stove’ category. In zero=’No’ ’Stove’, the ’No’ applies to the first vari-
able, Shelf and the second value, ’Stove’, applies to second variable, Micro.
The specification identity(x1 x2 x5 x6 x8) * class(brand / ...) creates the cross effects.
The separators= option is specified with a second value of ’ on ’ to create cross effect labels like
’Client on Extension’. More will be said on the cross effects when we look at the actual coded values
in the next few pages.
Note that PROC TRANSREG produces the following warning twice.
WARNING: This usage of * sets one group’s slope to zero. Specify |
to allow all slopes and intercepts to vary. Alternatively,
specify CLASS(vars) * identity(vars) identity(vars) for
separate within group functions and a common intercept.
This is a change from Version 6.
This is because on two occasions class was interacted with identity using the asterisk instead of the vertical
bar. In a linear model, this may be a sign of a coding error, so the procedure prints a warning. If you get this
warning while coding a choice model specifying zero=’constant-alternative-level’, you can safely ignore it.
Still, it is always good to print out one or more coded choice sets to check the coding as we will do later. Here is
the last part of the output from the %ChoicEff macro.
Food Product Example with Asymmetry and Availability Cross Effects 219
Standard
n Variable Name Label Variance DF Error
First we see estimable brand effects for each of the five brands, excluding the constant alternative ’None’. Next
we see quantitative alternative-specific price effects for each of the brands. The next two effects are single df
effects for the shelf talker and the microwave option. Next we see five sets of cross effects, each consisting of
four effects of a brand on another brand, plus one more zero df cross effect of a bran on itself. The zero df
and missing variances and standard errors are correct since the cross effect of an alternative on itself is perfectly
aliased with the alternative-specific price effects. These results look fine. Everything that should be estimable is,
and everything that should not is not.
220 TS-677E Multinomial Logit, Discrete Choice Modeling
Next, we will run some further checks by looking at the coded design. Before we look at the coded design, recall
that the design for the first five choice sets is as follows.
The coded design that the %ChoicEff macro creates is called TMP– CAND. We will look at the coded data
set in several ways. First, here are the Brand, Price, microwave and shelf talker factors, for just the available
alternatives for the first five choice sets.
proc print data=tmp_cand(obs=21) label;
var Brand Price Shelf Micro;
where w;
run;
Unlike all previous examples, the number of alternatives is not the same in all of the choice sets. The first choice
set consists of five alternatives including ’None’. The national competitor is not available in this choice set.
The second choice set consists of three alternatives including ’None’. The client brand, extension, and regional
competitors are not available in this choice set. The third choice set consists of five alternatives including ’None’,
and so on.
Food Product Example with Asymmetry and Availability Cross Effects 221
Here are the coded factors for the brand effects and alternative-specific price effects for the first choice set.
proc print data=tmp_cand(obs=5) label;
id Brand;
var BrandClient -- BrandNational;
where w;
run;
proc print data=tmp_cand(obs=5) label;
id Brand Price;
var BrandClientPrice -- BrandNationalPrice;
where w;
run;
Client 1 0 0 0 0
Extension 0 1 0 0 0
Regional 0 0 1 0 0
Private 0 0 0 1 0
None 0 0 0 0 0
The brand effects and alternative-specific price effect codings are similar to those we have used previously. The
difference is the presence of all zero columns for unavailable alternatives, in this case the national competitor.
Note that Brand Price are just an ID variables and do not enter into the analysis.
Here are the shelf talker and microwave coded factors (along with the Brand, Price, Shelf, and Micro
factors.
proc print data=tmp_cand(obs=5) label;
id Brand Price Shelf Micro;
var shelftalker micromicro;
where w;
run;
Shelf
Brand Price Shelf Micro Talker Micro
The following code prints the cross effects along with Brand and Price for the first choice set.
proc print data=tmp_cand(obs=5) label;
id Brand Price;
var x1Brand:;
where w;
run;
proc print data=tmp_cand(obs=5) label;
id Brand Price;
var x2Brand:;
where w;
run;
proc print data=tmp_cand(obs=5) label;
id Brand Price;
var x5Brand:;
where w;
run;
proc print data=tmp_cand(obs=5) label;
id Brand Price;
var x6Brand:;
where w;
run;
proc print data=tmp_cand(obs=5) label;
id Brand Price;
var x8Brand:;
where w;
run;
The cross effects are printed in panels. This first panel shows the terms that capture the effect of the client brand
being available at $2.09 on the utility of the other brands. The last panel shows that the national competitor,
which is unavailable, has no effect on any other brand’s utility in this choice set.
Client Line Client Line Client Line Client Line Client Line
Extension Extension on Extension on Extension Extension on
Brand Price on Client Extension Regional on Private National
Client $2.09 0 0 0 0 0
Extension $1.89 0 0 0 0 0
Regional $1.99 0 0 0 0 0
Private $1.49 0 0 0 0 0
None $0.00 0 0 0 0 0
A column like ’Private Label on Client’ in the second last panel, for example captured the effect of
the private label brand being available at $1.49 on the utility of the client brand. In the previous pane, ’Re-
gional Brand on Extension’ captures the effect of the regional brand being available at $1.99 on the
utility of the extension.
The design looks good, it has reasonably good balance and correlations, it can be used to estimate all of the
effects of interest, and we have shown we know how to specify the model to get all the right codings. We are
ready to collect data.
proc format;
value yn 1 = ’ No’ 2 = ’Talker’;
value micro 1 = ’Micro’ 2 = ’Stove’;
run;
data _null_;
array brands[&m] _temporary_ (5 7 1 2 3 -2);
array u[&m];
array x[&mm1] x1 x2 x5 x6 x8;
do rep = 1 to 300;
if mod(rep, 2) then put;
put rep 3. +2 @@;
do j = 1 to &n;
set [Link] point=j;
do brand = 1 to &m; u[brand] = brands[brand] + 2 * normal(7); end;
do brand = 1 to &mm1;
if n(x[brand]) then u[brand] + -x[brand]; else u[brand] = .;
end;
if n(u2) and x4 = 2 then u2 + 1; /* shelf-talker */
if n(u2) and x3 = 1 then u2 + 1; /* microwave */
if n(u4) and x7 = 1 then u4 + 1; /* microwave */
* Choose the most preferred alternative.;
m = max(of u1-u&m);
do brand = 1 to &m;
if n(u[brand]) then if abs(u[brand] - m) < 1e-4 then c = brand;
end;
put +(-1) c @@;
end;
end;
stop;
run;
This DATA step reads the data.
data results;
input Subj (choose1-choose&n) (1.) @@;
datalines;
1 252212542412222122622122115222212221 2 252222521452221422122122212222212226
3 242221122412222422122122212222112221 4 242222122312222122122112212222252211
5 241222122452222122124152232522212221 6 251222122452222122122122212222212521
.
.
.
297 242222122412221122122522242422252221 298 251122141315222522122121212222112221
299 352222122412222112112511212222212221 300 242222122452222522512112212222112211
;
Here are the data and design for the first two choice sets for the first subject, including the unavailable alternatives.
These next steps aggregate the data. The data set is fairly large at 64,800 observations, and aggregating greatly
reduces its size, which makes both the TRANSREG and the PHREG steps run in just a few seconds. This step
also excludes the unavailable alternatives. When w is 1 (true) the alternative is available and counted, otherwise
when w is 0 (false) the alternative is unavailable and excluded by the where clause and not counted. There is
nothing in subsequent steps that assumes a fixed number of alternatives.
proc summary data=res2 nway;
class set brand price shelf micro x1 x2 x5 x6 x8 c;
output out=agg(drop=_type_);
where w; /* exclude unavailable, w = 0 */
run;
In the first choice set, the client brand was chosen (c = 1) a total of - freq- = 42 times and not chosen (c = 2)
a total of - freq- = 258 times. Each alternative was chosen and not chosen a total of 300 times, which is the
number of subjects. These next steps code and run the analysis.
226 TS-677E Multinomial Logit, Discrete Choice Modeling
Cross Effects
This next step codes the design for analysis. This coding was discussed on page 217. PROC TRANSREG is
run like before, except now the data set AGG is specified and the ID variable includes - freq- (the frequency
variable) but not Subj (the subject number variable).
proc transreg data=agg design=5000 nozeroconstant norestoremissing;
model class(brand / zero=’None’)
class(brand / zero=’None’ separators=’’ ’ ’) * identity(price)
class(shelf micro / lprefix=5 0 zero=’No’ ’Stove’)
identity(x1 x2 x5 x6 x8) *
class(brand / zero=’None’ separators=’ ’ ’ on ’) /
lprefix=0;
output out=coded(drop=_type_ _name_ intercept);
id set c _freq_;
label x1 = ’CE, Client’
x2 = ’CE, Extension’
x5 = ’CE, Regional’
x6 = ’CE, Private’
x8 = ’CE, National’
shelf = ’Shelf Talker’
micro = ’Microwave’;
run;
Note that like we saw in the %ChoicEff macro, PROC TRANSREG produces the following warning twice.
WARNING: This usage of * sets one group’s slope to zero. Specify |
to allow all slopes and intercepts to vary. Alternatively,
specify CLASS(vars) * identity(vars) identity(vars) for
separate within group functions and a common intercept.
This is a change from Version 6.
This is because on two occasions class was interacted with identity using the asterisk instead of the vertical
bar. In a linear model, this may be a sign of a coding error, so the procedure prints a warning. If you get this
warning while coding a choice model specifying zero=’constant-alternative-level’, you can safely ignore it.
Analysis is the same as we have done previously with aggregate data. PROC PHREG is run to fit the mother
logit model, complete with availability cross effects.
proc phreg data=coded;
strata set;
model c*c(2) = &_trgind / ties=breslow;
freq _freq_;
run;
Model Information
Convergence Status
Without With
Criterion Covariates Covariates
Parameter Standard
DF Estimate Error Chi-Square Pr > ChiSq
Since the number of alternatives is not constant within each choice set, the summary table has nonconstant
numbers of alternatives and numbers not chosen. The number chosen, 300 (or one per subject per choice set),
is constant, since each subject always chooses one alternative from each choice set regardless of the number of
alternatives. The first choice set has 1500 alternatives, 5 available times 300 subjects; whereas the fifth choice
set has 900 alternatives, 3 available times 300 subjects.
The most to least preferred brands are: client line extension, client brand, private label, national brand, and
regional competitor, and finally the none alternative (with an implicit part-worth utility of zero). The price effects
are mostly negative, and the positive effects are nonsignificant. Both the shelf-talker and the microwaveable
option have positive utility. The cross effects are mostly nonsignificant. The most significant cross effect is the
effect of the extension on the original client brand.
Here is a small sample of the data. Note that like before, the unavailable alternatives are required for the merge
step.
You can see that the demographic information matches the raw data and is constant within each subject. The
rest of the data processing is virtually the same as well. Since we have demographic information, we will not
aggregate. There would have to be ties in both the demographics and choice for aggregation to have any effect.
We use PROC TRANSREG to code, adding Age and Income to the analysis.
proc transreg data=res2 design=5000 nozeroconstant norestoremissing;
model class(brand / zero=’None’)
identity(age income) * class(brand / zero=’None’ separators=’’ ’, ’)
class(brand / zero=’None’ separators=’’ ’ ’) * identity(price)
class(shelf micro / lprefix=5 0 zero=’No’ ’Stove’)
identity(x1 x2 x5 x6 x8) *
class(brand / zero=’None’ separators=’ ’ ’ on ’) /
lprefix=0 order=data;
Food Product Example with Asymmetry and Availability Cross Effects 231
Shelf
Brand Price Client Extension Regional Private Talker Microwave c
Client $2.09 33 0 0 0 0
Extension $1.89 0 33 0 0 0
Regional $1.99 0 0 33 0 0
Private $1.49 0 0 0 33 0
None $0.00 0 0 0 0 0
Client $2.09 44 0 0 0 0
Extension $1.89 0 44 0 0 0
Regional $1.99 0 0 44 0 0
Private $1.49 0 0 0 44 0
None $0.00 0 0 0 0 0
Client $2.09 0 0 0 0 0
Extension $1.89 0 0 0 0 0
Regional $1.99 0 0 0 0 0
Private $1.49 0 0 0 0 0
None $0.00 0 0 0 0 0
The PROC PHREG specification is the same as we have used before with nonaggregated data.
proc phreg data=coded brief;
model c*c(2) = &_trgind / ties=breslow;
strata subj set;
run;
This step took just about one minute and produced the following results.
Model Information
1 2400 3 1 2
2 1200 4 1 3
3 7200 5 1 4
Convergence Status
Without With
Criterion Covariates Covariates
Parameter Standard
DF Estimate Error Chi-Square Pr > ChiSq
In previous examples, when we used the brief option to produce a brief summary of the strata, the table
had only one line. In this case, since our choice sets have 3, 4, or 5 alternatives, we have three rows, one for
each choice set size. The coefficients for the age and income variables are generally not very significant in this
analysis.
Allocation of Prescription Drugs 237
%mktruns( 3 ** 10 )
Design Summary
Number of
Levels Frequency
3 10
Saturated = 21
Full Factorial = 59,049
27 * 0
36 * 0
45 0
54 * 0
21 45 9
24 45 9
30 45 9
33 45 9
39 45 9
42 45 9
n Design Reference
27 3 ** 13 Fractional-factorial
36 2 ** 11 3 ** 12 Taguchi, 1987
36 2 ** 4 3 ** 13 Taguchi, 1987
36 2 ** 2 3 ** 12 6 ** 1 Wang and Wu, 1991
36 3 ** 13 4 ** 1 Dey, 1985
36 3 ** 12 12 ** 1 Wang and Wu, 1991
54 2 ** 1 3 ** 25 Taguchi, 1987
54 3 ** 24 6 ** 1 Hedayat, Sloane, and Stufken, 1999
54 3 ** 18 18 ** 1 Hedayat, Sloane, and Stufken, 1999
We need at least 21 choice sets and we see the optimal sizes are all divisible by nine. We will use 27 choice sets,
which can give us up to 13 three-level factors.
Next, we use the %MktEx macro to create the design. In addition, one more factor is added to the design. This
factor will be used to block the design into three blocks of size 9.
%let nalts = 10;
Current Best
Design Row,Col D-Efficiency D-Efficiency Notes
----------------------------------------------------------
1 Start 100.0000 100.0000 Tab
1 End 100.0000
x1 3 1 2 3
x2 3 1 2 3
x3 3 1 2 3
x4 3 1 2 3
x5 3 1 2 3
x6 3 1 2 3
x7 3 1 2 3
x8 3 1 2 3
x9 3 1 2 3
x10 3 1 2 3
x11 3 1 2 3
Allocation of Prescription Drugs 239
Average
Prediction
Design Standard
Number D-Efficiency A-Efficiency G-Efficiency Error
------------------------------------------------------------------------
1 100.0000 100.0000 100.0000 0.9230
The %MktEx macro always creates factor names of x1, x2, and so on with values of 1, 2, .... You can create
a data set with the names and values you want and use it to rename the factors and reset the levels. This first
step creates a data set with 11 variables, Block and Brand1 - Brand10. Block has values 1, 2, and 3,
and the brand variables have values of 50, 75, and 100 with a dollar format. The %MktLab macro takes the
data=Randomized design data set and uses the names, values, and formats in the key=Key data set to make
the out=Final data set. This data set is sorted by block and printed. The %MktEval macro is called to check
the results.
data key(drop=i);
input Block Brand1;
array Brand[10];
do i = 2 to 10; brand[i] = brand1; end;
format brand: dollar4.;
datalines;
1 50
2 75
3 100
;
%mktlab(key=key);
%mkteval(blocks=block)
Here is the key= data set.
Obs Block Brand1 Brand2 Brand3 Brand4 Brand5 Brand6 Brand7 Brand8 Brand9 Brand10
1 1 $50 $50 $50 $50 $50 $50 $50 $50 $50 $50
2 2 $75 $75 $75 $75 $75 $75 $75 $75 $75 $75
3 3 $100 $100 $100 $100 $100 $100 $100 $100 $100 $100
240 TS-677E Multinomial Logit, Discrete Choice Modeling
Variable Mapping:
x1 : Block
x2 : Brand1
x3 : Brand2
x4 : Brand3
x5 : Brand4
x6 : Brand5
x7 : Brand6
x8 : Brand7
x9 : Brand8
x10 : Brand9
x11 : Brand10
Block Brand1 Brand2 Brand3 Brand4 Brand5 Brand6 Brand7 Brand8 Brand9 Brand10
1 $100 $75 $100 $100 $75 $100 $50 $50 $75 $100
$50 $100 $75 $100 $100 $100 $100 $75 $75 $75
$75 $50 $50 $100 $50 $100 $75 $100 $75 $50
$75 $75 $100 $50 $75 $75 $100 $75 $50 $75
$75 $100 $75 $75 $100 $50 $50 $50 $100 $100
$50 $50 $50 $50 $50 $75 $50 $50 $50 $100
$100 $50 $50 $75 $50 $50 $100 $75 $100 $75
$100 $100 $75 $50 $100 $75 $75 $100 $50 $50
$50 $75 $100 $75 $75 $50 $75 $100 $100 $50
2 $75 $100 $50 $75 $75 $75 $75 $75 $75 $100
$100 $50 $100 $75 $100 $75 $50 $100 $75 $75
$100 $100 $50 $50 $75 $100 $100 $50 $100 $50
$100 $75 $75 $100 $50 $50 $75 $75 $50 $100
$50 $100 $50 $100 $75 $50 $50 $100 $50 $75
$75 $75 $75 $50 $50 $100 $50 $100 $100 $75
$50 $75 $75 $75 $50 $75 $100 $50 $75 $50
$50 $50 $100 $50 $100 $100 $75 $75 $100 $100
$75 $50 $100 $100 $100 $50 $100 $50 $50 $50
3 $100 $75 $50 $100 $100 $75 $100 $100 $100 $100
$75 $100 $100 $75 $50 $100 $100 $100 $50 $100
$100 $50 $75 $75 $75 $100 $75 $50 $50 $75
$100 $100 $100 $50 $50 $50 $50 $75 $75 $50
$75 $75 $50 $50 $100 $50 $75 $50 $75 $75
$75 $50 $75 $100 $75 $75 $50 $75 $100 $50
$50 $100 $100 $100 $50 $75 $75 $50 $100 $75
$50 $75 $50 $75 $100 $100 $50 $75 $50 $50
$50 $50 $75 $50 $75 $50 $100 $100 $75 $100
Allocation of Prescription Drugs 241
Block Brand1 Brand2 Brand3 Brand4 Brand5 Brand6 Brand7 Brand8 Brand9 Brand10
Block 1 0 0 0 0 0 0 0 0 0 0
Brand1 0 1 0 0 0 0 0 0 0 0 0
Brand2 0 0 1 0 0 0 0 0 0 0 0
Brand3 0 0 0 1 0 0 0 0 0 0 0
Brand4 0 0 0 0 1 0 0 0 0 0 0
Brand5 0 0 0 0 0 1 0 0 0 0 0
Brand6 0 0 0 0 0 0 1 0 0 0 0
Brand7 0 0 0 0 0 0 0 1 0 0 0
Brand8 0 0 0 0 0 0 0 0 1 0 0
Brand9 0 0 0 0 0 0 0 0 0 1 0
Brand10 0 0 0 0 0 0 0 0 0 0 1
Frequencies
Block 9 9 9
Brand1 9 9 9
Brand2 9 9 9
Brand3 9 9 9
Brand4 9 9 9
Brand5 9 9 9
Brand6 9 9 9
Brand7 9 9 9
Brand8 9 9 9
Brand9 9 9 9
Brand10 9 9 9
Block Brand1 3 3 3 3 3 3 3 3 3
Block Brand2 3 3 3 3 3 3 3 3 3
Block Brand3 3 3 3 3 3 3 3 3 3
Block Brand4 3 3 3 3 3 3 3 3 3
Block Brand5 3 3 3 3 3 3 3 3 3
Block Brand6 3 3 3 3 3 3 3 3 3
Block Brand7 3 3 3 3 3 3 3 3 3
Block Brand8 3 3 3 3 3 3 3 3 3
Block Brand9 3 3 3 3 3 3 3 3 3
Block Brand10 3 3 3 3 3 3 3 3 3
.
.
.
N-Way 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1
242 TS-677E Multinomial Logit, Discrete Choice Modeling
array freq[&nalts];
brand = ’ ’;
count = 10 * (sum(of freq:) = 0);
output;
run;
proc print data=results(obs=3) label noobs; run;
proc print data=allocs(obs=33); id block set; by block set; run;
The PROC PRINT steps show how the first three observations of the RESULTS data set are transposed into the
first 33 observations of the ALLOCS data set.
Allocation of Prescription Drugs 243
Block Subject Set Freq1 Freq2 Freq3 Freq4 Freq5 Freq6 Freq7 Freq8 Freq9 Freq10
1 1 1 0 0 8 0 2 0 0 0 0 0
1 1 2 0 0 8 0 0 0 2 0 0 0
1 1 3 0 0 0 0 0 0 0 0 10 0
1 1 Brand 1 0
Brand 2 0
Brand 3 8
Brand 4 0
Brand 5 2
Brand 6 0
Brand 7 0
Brand 8 0
Brand 9 0
Brand 10 0
0
1 2 Brand 1 0
Brand 2 0
Brand 3 8
Brand 4 0
Brand 5 0
Brand 6 0
Brand 7 2
Brand 8 0
Brand 9 0
Brand 10 0
0
1 3 Brand 1 0
Brand 2 0
Brand 3 0
Brand 4 0
Brand 5 0
Brand 6 0
Brand 7 0
Brand 8 0
Brand 9 10
Brand 10 0
0
The next step aggregates the data. It stores in the variable Count the number of times each alternative of each
choice set was chosen. This creates a data set with 297 observations (3 blocks 9 sets 11 alternatives = 297).
* Aggregate, store the results back in count.;
These next steps prepare the design for analysis. We need to create a data set KEY that describes how the factors
in our design will be used for analysis. It will contain all of the factor names, Brand1, Brand2, ... Brand10.
We can run the %MktKey macro to get these names in the SAS log for cutting and pasting into the program
without typing them.
%mktkey(Brand1-Brand10)
1 1 Brand 1 $100
2 1 Brand 2 $75
3 1 Brand 3 $100
4 1 Brand 4 $100
5 1 Brand 5 $75
6 1 Brand 6 $100
7 1 Brand 7 $50
8 1 Brand 8 $50
9 1 Brand 9 $75
10 1 Brand 10 $100
11 1 .
Both data sets must be sorted the same way before they can be merged. The constant alternative, indicated by a
missing brand, is last in the design choice set and hence is out of order. Missing must come before nonmissing
for the merge. The order is correct in the ALLOCS data set since it was created by PROC SUMMARY with
Brand as a class variable.
proc sort data=rolled; by set brand; run;
Allocation of Prescription Drugs 245
The data are merged along with error checking to ensure that the merge proceeded properly. Both data sets should
have the same observations and Set and Brand variables, so the merge should be one to one.
data allocs2;
merge allocs(in=flag1) rolled(in=flag2);
by set brand;
if flag1 ne flag2 then put ’ERROR: Merge is not 1 to 1.’;
format price dollar4.;
run;
proc print data=allocs2(obs=22);
var brand price count;
sum count;
by notsorted set;
id set;
run;
In the aggregate and combined data set, we see how often each alternative was chosen for each choice set. For
example, in the first choice set, the constant alternative was chosen zero times, Brand 1 at $100 was chosen 103
times, and so on. The 11 alternatives were chosen a total of 1000 times, 100 subjects times 10 choices each.
1 . 0
Brand 1 $100 103
Brand 2 $75 58
Brand 3 $100 318
Brand 4 $100 99
Brand 5 $75 54
Brand 6 $100 83
Brand 7 $50 71
Brand 8 $50 58
Brand 9 $75 100
Brand 10 $100 56
--- -----
1 1000
2 . 10
Brand 1 $50 73
Brand 2 $100 76
Brand 3 $75 342
Brand 4 $100 55
Brand 5 $100 50
Brand 6 $100 77
Brand 7 $100 95
Brand 8 $75 71
Brand 9 $75 72
Brand 10 $75 79
--- -----
2 1000
At this point, the data set contains 297 observations (27 choice sets times 11 alternatives) showing the number
of times each alternative was chosen. This data set must be augmented to also include the number of times each
alternative was not chosen. For example, in the first choice set, brand 1 was chosen 103 times, which means it
was not chosen 0 + 58 + 318 + 99 + 54 + 83 + 71 + 58 + 100 + 56 = 897 times. We use a macro, %MktAllo
for “marketing allocation study” to process the data. We specify the input data=allocs2 data set, the output
out=allocs3 data set, the number of alternatives including the constant (nalts=%eval(&nalts + 1)),
246 TS-677E Multinomial Logit, Discrete Choice Modeling
the variables in the data set except the frequency variable (vars=set brand price), and the frequency
variable (freq=Count). The macro counts how many times each alternative was chosen and not chosen and
writes the results to the out= data set along with the usual c = 1 for chosen and c = 2 for unchosen.
%mktallo(data=allocs2, out=allocs3, nalts=%eval(&nalts + 1),
vars=set brand price, freq=Count)
1 1 . 0 1
2 1 . 1000 2
3 1 Brand 1 $100 103 1
4 1 Brand 1 $100 897 2
5 1 Brand 2 $75 58 1
6 1 Brand 2 $75 942 2
7 1 Brand 3 $100 318 1
8 1 Brand 3 $100 682 2
9 1 Brand 4 $100 99 1
10 1 Brand 4 $100 901 2
11 1 Brand 5 $75 54 1
12 1 Brand 5 $75 946 2
13 1 Brand 6 $100 83 1
14 1 Brand 6 $100 917 2
15 1 Brand 7 $50 71 1
16 1 Brand 7 $50 929 2
17 1 Brand 8 $50 58 1
18 1 Brand 8 $50 942 2
19 1 Brand 9 $75 100 1
20 1 Brand 9 $75 900 2
21 1 Brand 10 $100 56 1
22 1 Brand 10 $50 944 2
In the first choice set, the constant alternative is chosen zero times and not chosen 1000 times, Brand 1 is chosen
103 times and not chosen 1000 103 = 897 times, Brand 2 is chosen 58 times and not chosen 1000 58 =
942 times, and so on. Note that allocation studies do not always have fixed sums, so it is important to use
the %MktAllo macro or some other approach that actually counts the number of times each alternative was
unchosen. It is not always sufficient to simply subtract from a fixed constant (in this case 1000).
Analysis proceeds like it has in all other examples. We stratify by choice set number. We do not need to stratify
by Block since choice set number does not repeat within block.
proc phreg data=coded;
where count > 0;
model c*c(2) = &_trgind / ties=breslow;
freq count;
strata set;
run;
We used the where statement to exclude observations with zero frequency; otherwise PROC PHREG complains
about them.
Model Information
Convergence Status
Without With
Criterion Covariates Covariates
Parameter Standard
DF Estimate Error Chi-Square Pr > ChiSq
The output shows that there are 27 strata, one per choice set, each consisting of 1000 chosen alternatives (10
choices by 100 subjects) and 10,000 unchosen alternatives. All of the brand coefficients are “significant,” with
the Brand 3 effect being by far the strongest. (We will soon see that statistical significance should be ignored
with allocation studies.) There is no price effect.
Analyzing Proportions
Recall that we collected data by asking physicians to report which brands they would prescribe the next ten times
they write prescriptions. Alternatively, we could ask them to report the proportion of time they would prescribe
each brand. We can simulate having proportion data by dividing our count data by 10. This means our frequency
variable will no longer contain integers, so we need to specify the notruncate option on PROC PHREG freq
statement to allow noninteger “frequencies.”
data coded2;
set coded;
count = count / 10;
run;
Model Information
Convergence Status
Without With
Criterion Covariates Covariates
Parameter Standard
DF Estimate Error Chi-Square Pr > ChiSq
data key;
input (x1-x5) ($) @@;
datalines;
x1 x2 x3 x4 x5
x6 x7 x8 x9 x10
x11 x12 x13 x14 x15
;
Design Summary
Number of
Levels Frequency
3 5
Saturated = 11
Full Factorial = 243
18 * 0
27 * 0
36 * 0
12 10 9
15 10 9
21 10 9
24 10 9
30 10 9
33 10 9
11 15 3 9
n Design Reference
18 2 ** 1 3 ** 7 Taguchi, 1987
18 3 ** 6 6 ** 1 Taguchi, 1987
27 3 ** 13 Fractional-factorial
27 3 ** 9 9 ** 1 Fractional-factorial
36 2 ** 11 3 ** 12 Taguchi, 1987
36 2 ** 4 3 ** 13 Taguchi, 1987
36 2 ** 2 3 ** 12 6 ** 1 Wang and Wu, 1991
36 2 ** 1 3 ** 8 6 ** 2 Zhang, Lu, and Pang, 1999
36 3 ** 13 4 ** 1 Dey, 1985
36 3 ** 12 12 ** 1 Wang and Wu, 1991
36 3 ** 7 6 ** 3 Finney, 1982
254 TS-677E Multinomial Logit, Discrete Choice Modeling
We could use candidate sets of size: 18, 27 or 36. Additionally, since this problem is small, we could try an
81-run fractional-factorial design or the 243-run full-factorial design. We will choose the 243-run full-factorial
design, since it is reasonably small and it should give us a good design.
We will use the %MktEx macro to create a candidate set. The candidate set will consist of 5 three-level factors,
one for each of the five generic attributes. We will add three flag variables to the candidate set, f1-f3, one
for each alternative. Since there are three alternatives, the candidate set must contain those observations that
may be used for alternative 1, those observations that may be used for alternative 2, and those observations that
may be used for alternative 3. The flag variable for each alternative consists of ones for those candidates that
may be included for that alternative and zeros or missings for those candidates that may not be included for
that alternative. The candidates for the different alternatives may be all different, all the same, or something in
between depending on the problem. For example, the candidate set may contain one observation that is only used
for the last, constant alternative. In this purely generic case, each flag variable consists entirely of ones indicating
that any candidate can appear in any alternative. The %MktEx macro will not allow you to create constant or
one-level factors. We can instead use the %MktLab macro to add the flag variables, essentially by specifying
that we have multiple intercepts. The option int=f1-f3 creates three variables with values all one. The default
output data set is called FINAL. The following code creates the candidates.
%mktex(3 ** 5, n=243)
%mktlab(data=design, int=f1-f3)
Obs f1 f2 f3 x1 x2 x3 x4 x5
1 1 1 1 1 1 1 1 1
2 1 1 1 1 1 1 1 2
3 1 1 1 1 1 1 1 3
4 1 1 1 1 1 1 2 1
5 1 1 1 1 1 1 2 2
6 1 1 1 1 1 1 2 3
7 1 1 1 1 1 1 3 1
8 1 1 1 1 1 1 3 2
9 1 1 1 1 1 1 3 3
10 1 1 1 1 1 2 1 1
11 1 1 1 1 1 2 1 2
12 1 1 1 1 1 2 1 3
13 1 1 1 1 1 2 2 1
14 1 1 1 1 1 2 2 2
15 1 1 1 1 1 2 2 3
16 1 1 1 1 1 2 3 1
17 1 1 1 1 1 2 3 2
18 1 1 1 1 1 2 3 3
19 1 1 1 1 1 3 1 1
20 1 1 1 1 1 3 1 2
21 1 1 1 1 1 3 1 3
22 1 1 1 1 1 3 2 1
23 1 1 1 1 1 3 2 2
24 1 1 1 1 1 3 2 3
25 1 1 1 1 1 3 3 1
26 1 1 1 1 1 3 3 2
27 1 1 1 1 1 3 3 3
Next, we will search that candidate set for an efficient design for the model specification class(x1-x5) and
the assumption = 0. We will use the %ChoicEff autocall macro to do this. (All of the autocall macros used
in this report are documented starting on page 287.) This approach is based on the work of Huber and Zwerina
(1996) who proposed constructing efficient experimental designs for choice experiments under an assumed model
and . The %ChoicEff macro uses a modified Federov algorithm (Federov, 1972; Cook and Nachtsheim, 1980)
to optimize the choice model variance matrix. We will be using the largest possible candidate set for this problem,
the full-factorial design, and we will ask for more than the default number of iterations, so run time will be slower
than it could be. However, we will be requesting a very small number of choice sets. Building the chairs will be
expensive, so we want to get a really good but small design. This specification requests a generic design with six
choice sets each consisting of three alternatives.
%choiceff(data=final, model=class(x1-x5), nsets=6, maxiter=100,
seed=121, flags=f1-f3, beta=zero);
The data=final option names the input data set of candidates. The model=class(x1-x5) option speci-
fies the most general model that will be considered at analysis time. The nsets=6 option specifies the number
of choice sets. Note that this is considerably smaller than the minimum of 31 that would be required if we
were just using the %MktEx linear-design approach (6 3 = 18 chairs instead of 31 3 = 93 chairs). The
maxiter=100 option requests 100 designs based on 100 random initial designs (by default, maxiter=2).
The seed=121 option specifies the random number seed. The flags=f1-f3 specifies the flag variables for
alternatives 1 to 3. Implicitly, this option also specifies the fact that there are three alternatives since three flag
variables were specified. The beta=zero option specifies the assumption = 0. A vector of numbers like
beta=-1 0 -1 0 -1 0 -1 0 -1 0 -1 0 could be specified. When you wish to assume all parameters
are zero, you can specify beta=zero instead of typing a vector of the zeros. You can also omit the beta=
option if you just want the macro to list the parameters. You can use this list to ensure that you specify the
parameters in the right order.
The first part of the output from the macro is a list of all of the effects generated and the assumed values of . It
is very important to check this list and make sure it is correct. In particular, when you are explicitly specifying
the vector, you need to make sure you specified all of the values in the right order.
1 x11 0 x1 1
2 x12 0 x1 2
3 x21 0 x2 1
4 x22 0 x2 2
5 x31 0 x3 1
6 x32 0 x3 2
7 x41 0 x4 1
8 x42 0 x4 2
9 x51 0 x5 1
10 x52 0 x5 2
256 TS-677E Multinomial Logit, Discrete Choice Modeling
Next, the macro produces the iteration history, which is different from the iteration histories we are used to
seeing in the %MktEx macro. The %ChoicEff macro uses PROC IML and a modified Federov algorithm to
iteratively improve the efficiency of the choice design given the specified candidates, model, and . Note that
these efficiencies are not on a 0 to 100 scale. This step took about 12 minutes. Here are some of the results.
Next, the macro shows which design it chose and the final efficiency and D-Error (D-Efficiency = 1 / D-Error).
Next, it shows the variance, standard error, and df for each effect. It is important to ensure that each effect is
estimable: (df = 1). Usually, when all of the variances are constant, like we see in this table, it means that the
macro has found the optimal design.
Variable Standard
n Name Label Variance DF Error
1 x11 x1 1 1 1 1
2 x12 x1 2 1 1 1
3 x21 x2 1 1 1 1
4 x22 x2 2 1 1 1
5 x31 x3 1 1 1 1
6 x32 x3 2 1 1 1
7 x41 x4 1 1 1 1
8 x42 x4 2 1 1 1
9 x51 x5 1 1 1 1
10 x52 x5 2 1 1 1
==
10
The data set BEST contains the final, best design found.
proc print; by set; id set; run;
The data set contains: Design - the number of the design with the maximum efficiency, Efficiency - the
efficiency of this design, Index - the candidate set observation number, Set - the choice set number, Prob -
the probability that this alternative will be chosen given , n - the observation number, x1-x5 - the design, and
f1-f3 - the flags.
This design has 18 runs (6 choice sets 3 alternatives). Notice that in this design, each level occurs exactly
once in each factor and each choice set. To use this design for analysis, you would only need the variables Set
and x1-x5. Since it is already in choice design format, it would not need to be processed using the %MktRoll
258 TS-677E Multinomial Logit, Discrete Choice Modeling
macro. Since data collection, processing, and analysis have already been covered in detail in other examples, this
example will concentrate solely on experimental design.
%mktlab(data=design, int=f1-f3)
1 x11 0 x1 1
2 x12 0 x1 2
3 x21 0 x2 1
4 x22 0 x2 2
5 x31 0 x3 1
6 x32 0 x3 2
7 x41 0 x4 1
8 x42 0 x4 2
9 x51 0 x5 1
10 x52 0 x5 2
Variable Standard
n Name Label Variance DF Error
1 x11 x1 1 1 1 1
2 x12 x1 2 1 1 1
3 x21 x2 1 1 1 1
4 x22 x2 2 1 1 1
5 x31 x3 1 1 1 1
6 x32 x3 2 1 1 1
7 x41 x4 1 1 1 1
8 x42 x4 2 1 1 1
9 x51 x5 1 1 1 1
10 x52 x5 2 1 1 1
==
10
1 1 1.15470 11 1 0.33333 1 1 1 1 2 3 1 3 1
2 1 1.15470 13 1 0.33333 2 1 1 1 3 1 2 1 2
3 1 1.15470 4 1 0.33333 3 1 1 1 1 2 3 2 3
4 1 1.15470 3 2 0.33333 4 1 1 1 1 2 1 3 2
5 1 1.15470 12 2 0.33333 5 1 1 1 2 3 2 1 3
6 1 1.15470 14 2 0.33333 6 1 1 1 3 1 3 2 1
7 1 1.15470 5 3 0.33333 7 1 1 1 1 3 2 2 1
8 1 1.15470 8 3 0.33333 8 1 1 1 2 1 3 3 2
9 1 1.15470 15 3 0.33333 9 1 1 1 3 2 1 1 3
10 1 1.15470 9 4 0.33333 10 1 1 1 2 2 2 2 2
11 1 1.15470 1 4 0.33333 11 1 1 1 1 1 1 1 1
12 1 1.15470 18 4 0.33333 12 1 1 1 3 3 3 3 3
13 1 1.15470 10 5 0.33333 13 1 1 1 2 2 3 1 1
14 1 1.15470 17 5 0.33333 14 1 1 1 3 3 1 2 2
15 1 1.15470 2 5 0.33333 15 1 1 1 1 1 2 3 3
16 1 1.15470 6 6 0.33333 16 1 1 1 1 3 3 1 2
17 1 1.15470 7 6 0.33333 17 1 1 1 2 1 1 2 3
18 1 1.15470 16 6 0.33333 18 1 1 1 3 2 2 3 1
260 TS-677E Multinomial Logit, Discrete Choice Modeling
Notice we got the same D-efficiency and variances as before (D-efficiency = 1.1547005384 and all variances 1).
Also notice the Index variable in the design (which is the candidate set row number). Each candidate appears
in the design exactly once. We have frequently found for problems like this (all generic attributes, no brands, no
constant alternative, total number of alternatives equal to the number of runs in an orthogonal design, all factors
available in that orthogonal design, and an assumed vector of zero) that the optimal design can be created by
optimally sorting the rows of an orthogonal design into choice sets, and the %ChoicEff macro can do this quite
well.
Six choice sets is a bit small. If you can afford a larger number, it would be good to try a larger design. In this
case, nine choice sets are requested using a fractional-factorial candidate set in 27 runs. Notice that like before,
the number of runs in the candidate set was chosen to be the product of the number of choice sets and the number
of alternatives in each choice set.
%mktex(3 ** 5, n=27)
%mktlab(data=design, int=f1-f3)
Variable Standard
n Name Label Variance DF Error
1 25 0.33333 3 3 1 1 2
2 0.33333 1 1 2 3 3
15 0.33333 2 2 3 2 1
2 10 0.33333 2 1 1 2 1
23 0.33333 3 2 2 1 2
9 0.33333 1 3 3 3 3
3 24 0.33333 3 2 3 3 1
11 0.33333 2 1 2 1 3
7 0.33333 1 3 1 2 2
Chair Design with Generic Attributes 261
4 13 0.33333 2 2 1 1 3
3 0.33333 1 1 3 2 2
26 0.33333 3 3 2 3 1
5 20 0.33333 3 1 2 2 3
6 0.33333 1 2 3 1 1
16 0.33333 2 3 1 3 2
6 8 0.33333 1 3 2 1 1
22 0.33333 3 2 1 2 3
12 0.33333 2 1 3 3 2
7 5 0.33333 1 2 2 2 2
18 0.33333 2 3 3 1 3
19 0.33333 3 1 1 3 1
8 1 0.33333 1 1 1 1 1
14 0.33333 2 2 2 3 2
27 0.33333 3 3 3 2 3
9 17 0.33333 2 3 2 2 1
4 0.33333 1 2 1 3 3
21 0.33333 3 1 3 1 2
Notice that like before, the variances are constant, 2/3, and each candidate appears once. This is an optimal
design in 9 choice sets.
%mktex(3 ** 5, n=243)
data final(drop=i);
set design end=eof;
retain f1-f3 1 f4 0;
output;
if eof then do;
array x[9] x1-x5 f1-f4;
do i = 1 to 9; x[i] = i le 5 or i eq 9; end;
output;
end;
run;
Obs x1 x2 x3 x4 x5 f1 f2 f3 f4
1 1 1 1 1 1 1 1 1 0
31 1 2 1 2 1 1 1 1 0
61 1 3 1 3 1 1 1 1 0
92 2 1 2 1 2 1 1 1 0
122 2 2 2 2 2 1 1 1 0
152 2 3 2 3 2 1 1 1 0
183 3 1 3 1 3 1 1 1 0
213 3 2 3 2 3 1 1 1 0
243 3 3 3 3 3 1 1 1 0
244 1 1 1 1 1 0 0 0 1
The first 243 observations may be used for any of the first three alternatives and the 244th observation may only
be used for fourth or constant alternative. In this example, the constant alternative is composed solely from the
first level of each factor. Of course this could be changed depending on the situation. The %ChoicEff macro
invocation is the same as before, except now we have four flags.
%choiceff(data=final, model=class(x1-x5), nsets=6, maxiter=100,
seed=121, flags=f1-f4, beta=zero);
1 x11 0 x1 1
2 x12 0 x1 2
3 x21 0 x2 1
4 x22 0 x2 2
5 x31 0 x3 1
6 x32 0 x3 2
7 x41 0 x4 1
8 x42 0 x4 2
9 x51 0 x5 1
10 x52 0 x5 2
.
.
.
Variable Standard
n Name Label Variance DF Error
When there were three alternatives, each alternative had a probability of choice of 1/3, and now with four al-
ternatives, the probability is 1/4. They are all equal because of the assumption = 0. With other assumptions
about , typically the probabilities will not all be equal. To use this design for analysis, you would only need
the variables Set and x1-x5. Since it is already in choice design format (one row per alternative), it would
not need to be processed using the %MktRoll macro. Note that when you make designs with the %ChoicEff
macro, the model statement in PROC TRANSREG should match or be no more complicated than the model
specification that generated the design:
model class(x1-x5);
A model with fewer degrees of freedom is safe, although the design will be suboptimal. For example, if x1-x5
are numeric, this would be safe:
model identity(x1-x5);
However, specifying interactions, or using this design in a branded study and specifying alternative-specific
effects like this could lead to quite a few unestimable parameters.
* Bad idea for this design!!;
model class(x1-x5 x1*x2 x4*x5);
%mktkey(x1-x15)
data key;
input (x1-x5) ($);
datalines;
x1 x2 x3 x4 x5
x6 x7 x8 x9 x10
x11 x12 x13 x14 x15
. . . . .
;
proc print; by set; id set; where set in (1, 100, 1000, 5000, 6561); run;
The %MktKey macro produced the following line, which we copied, pasted, and edited to make the KEY data
set.
x1 x2 x3 x4 x5 x6 x7 x8 x9 x10 x11 x12 x13 x14 x15
Here are a few of the candidate choice sets.
Set _Alt_ x1 x2 x3 x4 x5
1 1 3 2 2 1 2
2 3 2 1 1 2
3 2 1 3 3 1
4 1 1 1 1 1
100 1 3 3 2 2 3
2 3 1 3 3 2
3 1 3 3 3 1
4 1 1 1 1 1
1000 1 3 2 2 2 2
2 3 3 3 2 1
3 1 2 3 2 1
4 1 1 1 1 1
5000 1 1 2 2 3 3
2 3 3 3 3 2
3 2 2 1 3 3
4 1 1 1 1 1
6561 1 3 3 1 3 2
2 3 2 1 2 1
3 1 1 1 1 1
4 1 1 1 1 1
266 TS-677E Multinomial Logit, Discrete Choice Modeling
Next, we will then run the %ChoicEff macro, only this time we will specify nalts=4 instead of flags=f1-
f4. Since there are no alternative flag variables to count, we have to tell the macro how many alternatives are in
each choice set. We will also ask for fewer iterations since the candidate set is large.
%choiceff(data=final, model=class(x1-x5), nsets=6, nalts=4, maxiter=10,
beta=zero, seed=109);
1 x11 0 x1 1
2 x12 0 x1 2
3 x21 0 x2 1
4 x22 0 x2 2
5 x31 0 x3 1
6 x32 0 x3 2
7 x41 0 x4 1
8 x42 0 x4 2
9 x51 0 x5 1
10 x52 0 x5 2
Variable Standard
n Name Label Variance DF Error
This design is less efficient than we found using the alternative-swapping algorithm, so we will not use it.
Initial Designs
This section illustrates some design strategies that involve improving on or augmenting initial designs. We will
not actually use any designs from this section.
Average
Prediction
Design Standard
Number D-Efficiency A-Efficiency G-Efficiency Error
------------------------------------------------------------------------
1 91.2636 83.9694 97.8111 0.9747
Current Best
Design Row,Col D-Efficiency D-Efficiency Notes
----------------------------------------------------------
0 Initial 91.2636 91.2636 Ini
NOTE: Quitting the refinement step after 7.33 minutes and 2 designs.
The macro skips the normal first steps, algorithm search and design search, and goes straight into the design
refinement search. No improvements were found, which is usually the case.
Initial Designs 269
%mktex(n=36, seed=292)
data init;
set randomized end = eof;
f = 1;
output;
if eof then do;
f = .;
do i = 1 to 4; output; end;
drop i;
end;
run;
Augment a Design
O x x x x x x x x x x x x x x
b x x x x x x x x x 1 1 1 1 1 1 1 1 1 1 2 2 2 2
s 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 f
1 1 1 1 2 1 1 1 2 1 2 1 3 2 1 2 3 3 1 1 1 3 1 3 1
2 1 1 2 1 2 1 2 1 1 1 1 3 1 1 3 2 3 3 2 1 1 3 2 1
3 2 1 1 2 2 2 2 2 2 1 1 2 2 1 1 2 1 2 3 1 2 3 3 1
4 1 2 1 2 1 2 2 1 1 1 2 1 3 3 3 2 3 1 1 2 2 3 3 1
5 2 2 1 1 1 1 1 1 2 1 1 2 3 2 3 3 1 1 2 1 2 1 2 1
6 2 2 2 2 2 2 1 1 1 2 1 3 3 3 1 1 3 3 3 1 2 1 1 1
7 1 2 2 2 2 1 1 2 2 1 2 1 1 3 2 3 1 1 3 1 1 3 1 1
8 2 1 2 1 1 2 1 2 1 1 2 2 1 3 3 1 1 3 1 1 3 2 3 1
9 1 1 1 1 2 2 1 1 2 2 2 2 2 2 3 3 3 3 3 2 3 3 1 1
10 1 1 1 1 2 2 1 1 2 2 2 1 3 1 1 1 2 1 2 1 1 2 3 1
270 TS-677E Multinomial Logit, Discrete Choice Modeling
11 1 1 1 2 1 1 1 2 1 2 1 2 3 3 3 1 2 2 3 3 1 3 2 1
12 2 2 1 1 1 1 1 1 2 1 1 1 1 1 1 1 3 2 1 3 3 3 1 1
13 1 1 1 2 1 1 1 2 1 2 1 1 1 2 1 2 1 3 2 2 2 2 1 1
14 1 1 2 1 2 1 2 1 1 1 1 2 2 3 1 3 2 1 1 3 2 2 1 1
15 2 1 2 1 1 2 1 2 1 1 2 3 3 1 2 3 2 2 2 2 2 3 1 1
16 1 2 1 2 1 2 2 1 1 1 2 2 2 1 2 1 1 3 2 3 1 1 1 1
17 1 2 2 2 2 1 1 2 2 1 2 3 2 2 3 1 3 2 2 3 2 2 3 1
18 2 1 1 2 2 2 2 2 2 1 1 1 3 3 2 3 3 3 2 3 3 2 2 1
19 1 1 2 1 2 1 2 1 1 1 1 1 3 2 2 1 1 2 3 2 3 1 3 1
20 2 1 2 1 1 2 1 2 1 1 2 1 2 2 1 2 3 1 3 3 1 1 2 1
21 2 2 2 2 2 2 1 1 1 2 1 1 2 1 3 3 1 2 1 2 1 2 2 1
22 2 1 2 2 1 1 2 1 2 2 2 2 3 2 2 2 3 2 1 1 1 2 1 1
23 2 2 1 1 2 1 2 2 1 2 2 3 3 1 3 2 1 1 3 3 3 2 1 1
24 2 1 2 2 1 1 2 1 2 2 2 3 2 3 1 1 1 1 2 2 3 3 2 1
25 1 2 1 2 1 2 2 1 1 1 2 3 1 2 1 3 2 2 3 1 3 2 2 1
26 2 2 2 2 2 2 1 1 1 2 1 2 1 2 2 2 2 1 2 3 3 3 3 1
27 1 2 2 1 1 2 2 2 2 2 1 3 3 2 1 3 1 3 1 3 1 3 3 1
28 1 2 2 1 1 2 2 2 2 2 1 1 2 3 3 2 2 2 2 1 3 1 1 1
29 2 2 1 1 2 1 2 2 1 2 2 2 1 3 1 3 3 2 2 2 1 1 3 1
30 1 1 1 1 2 2 1 1 2 2 2 3 1 3 2 2 1 2 1 3 2 1 2 1
31 2 2 1 1 2 1 2 2 1 2 2 1 2 2 2 1 2 3 1 1 2 3 2 1
32 2 1 1 2 2 2 2 2 2 1 1 3 1 2 3 1 2 1 1 2 1 1 1 1
33 1 2 2 2 2 1 1 2 2 1 2 2 3 1 1 2 2 3 1 2 3 1 2 1
34 2 1 2 2 1 1 2 1 2 2 2 1 1 1 3 3 2 3 3 3 2 1 3 1
35 2 2 1 1 1 1 1 1 2 1 1 3 2 3 2 2 2 3 3 2 1 2 3 1
36 1 2 2 1 1 2 2 2 2 2 1 2 1 1 2 1 3 1 3 2 2 2 2 1
37 1 2 2 1 1 2 2 2 2 2 1 2 1 1 2 1 3 1 3 2 2 2 2 .
38 1 2 2 1 1 2 2 2 2 2 1 2 1 1 2 1 3 1 3 2 2 2 2 .
39 1 2 2 1 1 2 2 2 2 2 1 2 1 1 2 1 3 1 3 2 2 2 2 .
40 1 2 2 1 1 2 2 2 2 2 1 2 1 1 2 1 3 1 3 2 2 2 2 .
Augment a Design
Current Best
Design Row,Col D-Efficiency D-Efficiency Notes
----------------------------------------------------------
0 Initial 97.0381 97.0381 Ini
1 38 14 97.1225 97.1225
1 39 2 97.1460 97.1460
1 39 3 97.1569 97.1569
1 39 5 97.1629 97.1629
1 39 6 97.1815 97.1815
1 39 7 97.1878 97.1878
1 39 8 97.1899 97.1899
1 39 9 97.1965 97.1965
1 39 11 97.1986 97.1986
1 39 12 97.1986 97.1986
1 39 13 97.2002 97.2002
1 39 17 97.2002 97.2002
1 40 10 97.2002 97.2002
1 40 13 97.2002 97.2002
1 37 1 97.2023 97.2023
1 37 6 97.2043 97.2043
1 End 97.2033
Notice that the macro goes straight into the design refinement stage. Also notice that in the iteration history, only
rows 37 through 40 are changed. Here is the design. The last four rows are the holdouts.
Augment a Design
O x x x x x x x x x x x x x x
b x x x x x x x x x 1 1 1 1 1 1 1 1 1 1 2 2 2 2
s 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 f
1 1 1 1 2 1 1 1 2 1 2 1 3 2 1 2 3 3 1 1 1 3 1 3 1
2 1 1 2 1 2 1 2 1 1 1 1 3 1 1 3 2 3 3 2 1 1 3 2 1
3 2 1 1 2 2 2 2 2 2 1 1 2 2 1 1 2 1 2 3 1 2 3 3 1
4 1 2 1 2 1 2 2 1 1 1 2 1 3 3 3 2 3 1 1 2 2 3 3 1
5 2 2 1 1 1 1 1 1 2 1 1 2 3 2 3 3 1 1 2 1 2 1 2 1
6 2 2 2 2 2 2 1 1 1 2 1 3 3 3 1 1 3 3 3 1 2 1 1 1
7 1 2 2 2 2 1 1 2 2 1 2 1 1 3 2 3 1 1 3 1 1 3 1 1
8 2 1 2 1 1 2 1 2 1 1 2 2 1 3 3 1 1 3 1 1 3 2 3 1
9 1 1 1 1 2 2 1 1 2 2 2 2 2 2 3 3 3 3 3 2 3 3 1 1
10 1 1 1 1 2 2 1 1 2 2 2 1 3 1 1 1 2 1 2 1 1 2 3 1
11 1 1 1 2 1 1 1 2 1 2 1 2 3 3 3 1 2 2 3 3 1 3 2 1
12 2 2 1 1 1 1 1 1 2 1 1 1 1 1 1 1 3 2 1 3 3 3 1 1
13 1 1 1 2 1 1 1 2 1 2 1 1 1 2 1 2 1 3 2 2 2 2 1 1
14 1 1 2 1 2 1 2 1 1 1 1 2 2 3 1 3 2 1 1 3 2 2 1 1
15 2 1 2 1 1 2 1 2 1 1 2 3 3 1 2 3 2 2 2 2 2 3 1 1
16 1 2 1 2 1 2 2 1 1 1 2 2 2 1 2 1 1 3 2 3 1 1 1 1
17 1 2 2 2 2 1 1 2 2 1 2 3 2 2 3 1 3 2 2 3 2 2 3 1
18 2 1 1 2 2 2 2 2 2 1 1 1 3 3 2 3 3 3 2 3 3 2 2 1
19 1 1 2 1 2 1 2 1 1 1 1 1 3 2 2 1 1 2 3 2 3 1 3 1
20 2 1 2 1 1 2 1 2 1 1 2 1 2 2 1 2 3 1 3 3 1 1 2 1
21 2 2 2 2 2 2 1 1 1 2 1 1 2 1 3 3 1 2 1 2 1 2 2 1
22 2 1 2 2 1 1 2 1 2 2 2 2 3 2 2 2 3 2 1 1 1 2 1 1
23 2 2 1 1 2 1 2 2 1 2 2 3 3 1 3 2 1 1 3 3 3 2 1 1
24 2 1 2 2 1 1 2 1 2 2 2 3 2 3 1 1 1 1 2 2 3 3 2 1
25 1 2 1 2 1 2 2 1 1 1 2 3 1 2 1 3 2 2 3 1 3 2 2 1
26 2 2 2 2 2 2 1 1 1 2 1 2 1 2 2 2 2 1 2 3 3 3 3 1
27 1 2 2 1 1 2 2 2 2 2 1 3 3 2 1 3 1 3 1 3 1 3 3 1
28 1 2 2 1 1 2 2 2 2 2 1 1 2 3 3 2 2 2 2 1 3 1 1 1
29 2 2 1 1 2 1 2 2 1 2 2 2 1 3 1 3 3 2 2 2 1 1 3 1
30 1 1 1 1 2 2 1 1 2 2 2 3 1 3 2 2 1 2 1 3 2 1 2 1
31 2 2 1 1 2 1 2 2 1 2 2 1 2 2 2 1 2 3 1 1 2 3 2 1
32 2 1 1 2 2 2 2 2 2 1 1 3 1 2 3 1 2 1 1 2 1 1 1 1
33 1 2 2 2 2 1 1 2 2 1 2 2 3 1 1 2 2 3 1 2 3 1 2 1
34 2 1 2 2 1 1 2 1 2 2 2 1 1 1 3 3 2 3 3 3 2 1 3 1
35 2 2 1 1 1 1 1 1 2 1 1 3 2 3 2 2 2 3 3 2 1 2 3 1
36 1 2 2 1 1 2 2 2 2 2 1 2 1 1 2 1 3 1 3 2 2 2 2 1
37 2 2 2 1 2 1 2 2 2 2 1 2 2 3 2 1 3 3 3 1 1 1 3 .
38 2 1 1 1 1 2 2 1 2 1 1 3 3 2 1 2 1 2 2 1 1 1 3 .
39 2 1 2 2 1 2 1 2 2 2 2 3 3 3 2 3 2 3 2 3 3 3 3 .
40 1 2 1 1 1 2 2 2 1 2 2 1 3 1 3 2 3 3 1 2 1 3 3 .
Initial Designs 273
This code does the same thing only using the holdouts=4 option instead.
title ’Augment a Design’;
%mktex(n=36, seed=292)
%mktex(2 ** 11 3 ** 12, n=40, init=randomized,
holdouts=4, seed=513, options=nosort)
Augment a Design
O x x x x x x x x x x x x x x
b x x x x x x x x x 1 1 1 1 1 1 1 1 1 1 2 2 2 2
s 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 w
37 2 2 2 1 2 1 2 2 2 2 1 2 2 3 2 1 3 3 3 1 1 1 3 .
38 2 1 1 1 1 2 2 1 2 1 1 3 3 2 1 2 1 2 2 1 1 1 3 .
39 2 1 2 2 1 2 1 2 2 2 2 3 3 3 2 3 2 3 2 3 3 3 3 .
40 1 2 1 1 1 2 2 2 1 2 2 1 3 1 3 2 3 3 1 2 1 3 3 .
274 TS-677E Multinomial Logit, Discrete Choice Modeling
- - - - - - - - - 1 2 2 2 2 - - - - - -
- - 1 1 1 2 - - - - - - - - - - - - - 1
- - - - - - - - 1 1 1 1 1 - - - - - - -
- - - - - - - - - - 2 1 1 - 1 2 - - - -
- 1 1 2 2 2 - - - - - - - - - - - - - -
- - - - - - - - - - 2 1 2 - - 1 2 - - -
- - - - - - - - - - 1 2 1 1 - - 2 - - -
- - - - - - - - - - - - - 1 1 - 2 2 1 -
- - - - 2 1 - - 1 2 2 - - - - - - - - -
- - - - 1 2 - 2 - 2 - 1 - - - - - - - -
- - - - - - - - - - 1 1 - 2 - - 2 1 - -
- - - - - - - - - - - - - 2 1 2 - - 2 2
- - - - - - - - - - 1 1 2 2 2 - - - - -
- - - - - - - - - - - 2 2 - 1 2 - 1 - -
- - - - - - - - - - - - - 1 - 2 1 2 1 -
2 1 - - - - - - - - - - - - - - - 1 1 1
- 1 - - - - 1 - 2 - 2 1 - - - - - - - -
- - - - - - - - - - - - - - 2 2 2 2 2 -
1 2 - 1 2 - - - - - - - - - - - 1 - - -
- - - - 2 2 - 2 2 - 1 - - - - - - - - -
2 2 1 - - - - - - - - - - - - - - 2 - 2
- - - - - - - - - - - - - 1 2 - - 1 2 2
- - - - - 1 2 2 1 - 2 - - - - - - - - -
- 2 - - - - - - - - - - - - - 1 - 2 2 1
2 2 1 - - 1 - - - - - - - - - - - - 2 -
- 2 2 2 - - - - - - - - - - - - 1 - 1 -
- - - - 2 1 - - - - - - - - - - - 2 1 2
- - - 1 1 - 1 - - - - - - - - - - - 1 2
- - - - - 1 - - - 1 - - - 1 2 1 - - - -
- - - - 1 2 2 1 1 - - - - - - - - - - -
2 - - 2 2 - 1 - - - - - - - - - - - - 1
- - - - - - - - - - - - 1 2 - 1 1 - 2 -
1 - 1 - - - 2 1 - - - - - - - - - - - 1
- - - - - 2 1 1 1 2 - - - - - - - - - -
2 - 2 1 - - 2 - - - - - - - - - - - - 2
1 - 2 2 1 2 - - - - - - - - - - - - - -
- - - - - - - - - - 1 2 - - 1 1 1 - - -
- - - 2 1 - - 1 2 2 - - - - - - - - - -
- - - - - - - - - - - 2 - 2 2 1 - - 1 -
- - - - - 2 2 - 2 2 1 - - - - - - - - -
Partial Profiles and Restrictions 275
A design like this could be used to make a binary choice experiment. For example, the first run has factors 10
through 14 varying.
- - - - - - - - - 1 2 2 2 2 - - - - - -
Assume they are all yes-no factors (1 yes, 2 no). Subjects could be offered a choice between these two profiles:
The first profile came directly from the design and the second came from shifting the design: yes ! no, and no
! yes. Partial-profile designs have become very popular among some researchers.
Here is the code that generated and printed the partial profile design above.
%mktex(3 ** 20, n=41, partial=5, seed=292)
%mktlab(values=0 1 2)
data des(drop=i);
set = _n_;
set final(firstobs=2);
array x[20];
output;
do i = 1 to 20;
if x[i] then do; if x[i] = 1 then x[i] = 2; else x[i] = 1; end;
end;
output;
run;
%choiceff(data=des,
model=class(x1-x20 / zero=none),
nsets=20, nalts=2,
beta=zero, init=des(keep=set),
intiter=0)
Here is the last part of the output.
Partial Profiles
Variable Standard
n Name Label Variance DF Error
1 x10 x1 0 . 0 .
2 x11 x1 1 2.4989 1 1.58080
3 x12 x1 2 . 0 .
4 x20 x2 0 . 0 .
5 x21 x2 1 4.3585 1 2.08770
6 x22 x2 2 . 0 .
7 x30 x3 0 . 0 .
8 x31 x3 1 5.7179 1 2.39121
9 x32 x3 2 . 0 .
10 x40 x4 0 . 0 .
11 x41 x4 1 19.0020 1 4.35913
12 x42 x4 2 . 0 .
13 x50 x5 0 . 0 .
14 x51 x5 1 1.4018 1 1.18396
15 x52 x5 2 . 0 .
16 x60 x6 0 . 0 .
17 x61 x6 1 2.9092 1 1.70564
18 x62 x6 2 . 0 .
19 x70 x7 0 . 0 .
20 x71 x7 1 3.6474 1 1.90982
21 x72 x7 2 . 0 .
22 x80 x8 0 . 0 .
23 x81 x8 1 5.5731 1 2.36075
24 x82 x8 2 . 0 .
25 x90 x9 0 . 0 .
26 x91 x9 1 5.6681 1 2.38077
27 x92 x9 2 . 0 .
28 x100 x10 0 . 0 .
29 x101 x10 1 1.2731 1 1.12831
30 x102 x10 2 . 0 .
31 x110 x11 0 . 0 .
32 x111 x11 1 1.0522 1 1.02577
33 x112 x11 2 . 0 .
34 x120 x12 0 . 0 .
35 x121 x12 1 1.5623 1 1.24993
36 x122 x12 2 . 0 .
Partial Profiles and Restrictions 277
37 x130 x13 0 . 0 .
38 x131 x13 1 7.9449 1 2.81868
39 x132 x13 2 . 0 .
40 x140 x14 0 . 0 .
41 x141 x14 1 3.7175 1 1.92809
42 x142 x14 2 . 0 .
43 x150 x15 0 . 0 .
44 x151 x15 1 3.5820 1 1.89261
45 x152 x15 2 . 0 .
46 x160 x16 0 . 0 .
47 x161 x16 1 4.7737 1 2.18488
48 x162 x16 2 . 0 .
49 x170 x17 0 . 0 .
50 x171 x17 1 5.7060 1 2.38872
51 x172 x17 2 . 0 .
52 x180 x18 0 . 0 .
53 x181 x18 1 10.0597 1 3.17170
54 x182 x18 2 . 0 .
55 x190 x19 0 . 0 .
56 x191 x19 1 6.5273 1 2.55486
57 x192 x19 2 . 0 .
58 x200 x20 0 . 0 .
59 x201 x20 1 6.5214 1 2.55370
60 x202 x20 2 . 0 .
==
20
We see that one parameter is estimable for each factor and that is the parameter for the 1 or yes level. In effect,
we have two reference levels, one for the not shown level and the expected one for the no level. The %ChoicEff
macro prints a list of all redundant variables.
Redundant Variables:
x10 x12 x20 x22 x30 x32 x40 x42 x50 x52 x60 x62 x70 x72 x80 x82 x90 x92 x100
x102 x110 x112 x120 x122 x130 x132 x140 x142 x150 x152 x160 x162 x170 x172
x180 x182 x190 x192 x200 x202
We can cut this list into our program and drop those terms.
%choiceff(data=des,
model=class(x1-x20 / zero=none),
nsets=20, nalts=2,
beta=zero, init=des(keep=set),
intiter=0, drop=
x10 x12 x20 x22 x30 x32 x40 x42 x50 x52 x60 x62 x70 x72 x80 x82 x90 x92 x100
x102 x110 x112 x120 x122 x130 x132 x140 x142 x150 x152 x160 x162 x170 x172
x180 x182 x190 x192 x200 x202);
278 TS-677E Multinomial Logit, Discrete Choice Modeling
Partial Profiles
Variable Standard
n Name Label Variance DF Error
Partial Profiles
Average
Prediction
Design Standard
Number D-Efficiency A-Efficiency G-Efficiency Error
------------------------------------------------------------------------
1 41.2020 17.9653 100.0000 1.0000
Partial Profiles and Restrictions 279
With partial-profile designs, D-efficiency will typically be much less than we are accustomed to seeing with other
types of designs. Here is the design.
Partial Profiles
1 1 1 1 1 1 1 1 1 1 1 1 1
2 1 1 1 1 1 1 1 1 4 2 3 4
3 1 1 1 1 1 1 1 1 4 3 2 3
4 1 1 1 1 1 1 1 2 3 3 4 1
5 1 1 1 1 1 1 2 4 4 2 1 1
6 1 1 1 1 1 1 4 3 4 4 1 1
7 1 1 1 1 1 2 4 1 2 1 4 1
8 1 1 1 1 1 4 3 3 2 1 1 1
9 1 1 1 1 2 4 2 1 3 1 1 1
10 1 1 1 1 3 3 3 1 3 1 1 1
11 1 1 1 1 3 4 4 2 1 1 1 1
12 1 1 1 1 4 1 4 4 3 1 1 1
13 1 1 1 2 2 1 2 3 1 1 1 1
14 1 1 1 2 4 4 1 1 1 1 4 1
15 1 1 1 3 2 2 1 4 1 1 1 1
16 1 1 2 1 4 2 1 3 1 1 1 1
17 1 1 2 4 2 3 1 1 1 1 1 1
18 1 2 1 1 1 1 1 2 2 4 1 1
19 1 2 1 4 1 2 3 1 1 1 1 1
20 1 2 2 3 1 1 2 1 1 1 1 1
21 1 3 3 1 2 1 3 1 1 1 1 1
22 1 3 4 3 1 1 1 1 1 1 1 3
23 1 4 3 1 1 3 1 1 1 1 3 1
24 1 4 3 4 3 1 1 1 1 1 1 1
25 1 4 4 2 1 1 1 1 1 1 1 2
26 2 1 4 1 1 1 1 1 1 1 2 4
27 2 2 3 1 1 1 1 1 1 1 1 2
28 2 3 2 2 1 1 1 1 1 1 1 1
29 2 4 1 3 4 1 1 1 1 1 1 1
30 3 1 1 1 1 1 1 1 3 2 2 1
31 3 1 4 1 1 1 1 1 4 1 3 1
32 3 3 1 1 1 1 1 1 1 3 1 4
33 3 4 1 1 1 1 1 1 1 1 4 3
34 4 1 1 1 1 1 1 1 1 4 3 3
35 4 1 3 1 1 1 1 2 1 1 1 4
36 4 2 4 1 2 1 1 1 1 1 1 1
37 4 3 1 1 1 1 1 1 1 1 2 2
Notice that the first run is constant. For all other runs, exactly four factors vary and have levels not equal to 1.
280 TS-677E Multinomial Logit, Discrete Choice Modeling
2 2 1 3 1 2 1 2 2 2 2 1 3 2 1 1 2 1 2 2 2 3 2 1 1 3 3 3 2 2
2 2 1 3 2 2 1 3 2 3 3 2 2 3 1 2 1 1 1 1 1 2 3 3 3 2 1 2 3 2
Here are the same two potential choice sets, but now arrayed in choice design format.
Partial Profiles
Set x1 x2 x3 x4 x5 x6 x7 x8 x9 x10
1 2 2 1 3 1 2 1 2 2 2
2 1 3 2 1 1 2 1 2 2
2 3 2 1 1 3 3 3 2 2
2 2 2 1 3 2 2 1 3 2 3
3 2 2 3 1 2 1 1 1 1
1 2 3 3 3 2 1 2 3 2
Each choice set has 10 three-level factors and three alternatives. Four attributes are constant in each choice set:
x1, x5, x9, and x10 in the first choice set, and x2, x4, x6, and x7 in the second choice set. We do not need
an all-constant choice set like we saw in our earlier partial-profile designs, nor do we need an extra level for not
varying. In this approach, we will simply construct choice sets for four constant attributes (they may be constant
at 1, 2, or 3) and six varying attributes (with levels: 1, 2, and 3). Respondents will be given a choice task along
the lines of “Given a set of products that differ on these attributes but are identical in all other respects, which
one would you choose?”. They would then be shown a list of differences.
Partial Profiles and Restrictions 281
%macro partprof;
sum = 0;
do k = 1 to 10;
sum = sum + (x[k] = x[k+10] & x[k] = x[k+20] & x[k+10] = x[k+20]);
end;
bad = abs(sum - 4);
%mend;
Partial Profiles
Current Best
Design Row,Col D-Efficiency D-Efficiency Notes
----------------------------------------------------------
1 Start 85.1169 Ran
1 170 1 95.1279 95.1279 Conforms
1 170 3 95.1305 95.1305
1 171 16 95.1314 95.1314
1 171 6 95.1346 95.1346
282 TS-677E Multinomial Logit, Discrete Choice Modeling
.
.
.
1 60 7 96.5153 96.5153
1 66 3 96.5166 96.5166
1 End 96.5166
.
.
.
Partial Profiles
Average
Prediction
Design Standard
Number D-Efficiency A-Efficiency G-Efficiency Error
------------------------------------------------------------------------
1 96.5165 93.4268 95.9714 0.5551
The macro finds a design that conforms to the restrictions (shown by the Conforms note) that is 95.1% D-
efficient, and the final design is just over 96.5% D-efficient. This step took almost 28 minutes.
Here is the rest of the code for making the partial-profile choice design.
data des(drop=k sum);
set [Link];
array x[30];
sum = 0;
do k = 1 to 10;
sum = sum + (x[k] = x[k+10] & x[k] = x[k+20] & x[k+10] = x[k+20]);
end;
if sum eq 4;
run;
%mktkey(x1-x30)
data key;
input (x1-x10) ($);
datalines;
x1 x2 x3 x4 x5 x6 x7 x8 x9 x10
x11 x12 x13 x14 x15 x16 x17 x18 x19 x20
x21 x22 x23 x24 x25 x26 x27 x28 x29 x30
;
We use a DATA step to check each profile to see if it conforms using essentially the same code we saw in the
restrictions macro. The subsetting if statement outputs just those choice sets with four constant attributes. This
step is not necessary for this particular problem because we saw in the output that the design conformed to the
restrictions, however, it could be necessary for other problems. The %MktKey macro is run to generate the
full list of names in the range x1 - x30 for pasting into the next step. A KEY data set is created and the
%MktRoll macro is run to create a generic choice design from the linear candidate design.
The next step runs the %MktDups macro, which we have not used in previous examples. The %MktDups macro
can check a design to see if there are any duplicate runs and output just the unique sets. For a generic study like
this, it can also check to make sure there are no duplicate choice sets taking into account the fact that two choice
sets can be duplicates even if the alternatives are not in the same order. The %MktDups step names in a positional
parameter the type of design as a generic choice design. It names the input data set and the output data set
that will contain the design with any duplicates removed. It names the factors in the choice design x1-x10 and
the number of alternatives. The result is a data set called NODUPS. Here are the first 3 candidate choice sets.
Partial Profiles
1 1 1 1 1 1 1 3 1 3 3 3
2 1 2 2 3 1 2 1 1 2 3
3 1 3 3 2 1 2 1 2 1 3
2 1 1 1 1 1 3 2 2 1 3 1
2 3 1 1 1 2 2 1 3 3 3
3 2 1 3 1 1 2 3 2 3 2
3 1 1 1 1 2 1 3 3 2 3 3
2 3 1 1 2 3 1 1 1 1 3
3 2 1 1 2 2 2 2 3 2 3
The %ChoicEff macro is called to search for an efficient choice design. The specification
model=class(x1-x10) specifies a generic model with 10 attributes. The option iter=10 specifies
more than the default number of iterations (the default is 2 designs). We ask for a design with 27 sets and 3
alternatives. Furthermore, we ask for no duplicate choice sets and specify an assumed beta vector of zero. Here
are some of the results from the %ChoicEff macro.
Partial Profiles
.
.
.
Partial Profiles
Partial Profiles
Variable Standard
n Name Label Variance DF Error
Partial Profiles
Set x1 x2 x3 x4 x5 x6 x7 x8 x9 x10
16 1 1 2 3 2 1 3 3 3 3
3 1 2 2 1 2 3 1 3 2
2 1 2 1 3 3 3 2 3 1
196 3 3 3 3 1 2 3 2 1 1
1 2 3 2 2 3 3 2 1 2
2 1 3 1 3 1 3 2 1 3
.
.
.
77 2 1 2 2 3 1 1 1 2 2
1 2 2 1 3 2 1 3 1 2
3 3 2 3 3 3 1 2 3 2
Partial Profiles and Restrictions 285
The choice set number corresponds to the original set numbers in the candidate design.
Advanced Restrictions
There is one more aspect to restrictions that must be understood for the most sophisticated usages of restrictions.
The macro that imposes the restrictions is defined and called in four distinct places in the %MktEx macro. First,
the restrictions macro is called in a separate, preliminary IML step, just to catch some syntax errors you might
have made. Next, it is called in between calling PROC PLAN or FACTEX and calling PROC OPTEX. Here, the
restrictions macro is used to impose restrictions on the candidate set. Next it is used in the obvious way during
design creation and the coordinate-exchange algorithm. Finally, when options=accept is specified, which
means that restriction violations are acceptable, the macro is called after all of the iterations have completed to
report on restriction violations in the final design. For some advanced restrictions, we will not want exactly the
same code running in all four places. When the restrictions are purely written in terms of restrictions on x, which
is the ith row of the design matrix, there is no problem. The same macro will work fine for all uses. However,
when xmat (the full x matrix) or i or j1 (the row or column number) are used, the same code typically cannot
be used for all applications, although sometimes it does not matter. Next are some notes on each of the four
phases.
Syntax Check In this phase, the macro is defined and called just to check for syntax errors. This step allows the
macro to end more gracefully than it would otherwise if there are errors. Your restrictions macro can recognize
when it is in this phase because the macro variable &main is set to 0 and the macro variable &pass is set to
null. The pass variable is null before the iterations begin, 1 for the algorithm search phase, 2 for the design search
phase, 3 for the design refinement stage, and 4 after the iterations end. You can conditionally execute code in this
step or not using the following macro statements.
%if &main eq 0 and &pass eq %then %do; /* execute in syntax check */
%if not (&main eq 0 and &pass eq) %then %do; /* not execute in syntax check */
You will usually not need to worry about this step. It just calls the macro once and ignores the results to check for
syntax errors. For this step, xmat (and hence x) is a vector of ones (since the design does not exist yet) and j1
= j2 = j3 = i = 1. If you have complicated restrictions involving the row or column exchange indices
(i, j1, j2, j3) you may need to worry about this step. You may need to either not execute your restrictions
in this step or conditionally execute some assignment statements (just for this step) that set up j1, j2, and j3
more appropriately. If you have syntax errors in your restrictions macro and you cannot figure out what they are,
sometimes the best thing to do is directly submit the statements in your restrictions macro to IML so you can see
the normal IML syntax errors. First submit the following statements.
%let n = 27; /* substitute number of runs */
%let m = 10; /* substitute number of factors */
proc iml;
xmat = j(&n, &m, 1);
i = 1; j1 = 1; j2 = 1; j3 = 1; bad = 0; x = xmat[i,];
Candidate Check In this phase, the macro is used to impose restrictions on the candidate set created by PROC
PLAN or PROC FACTEX before it is searched by PROC OPTEX. For some problems, such as most partial profile
problems, the restrictions are so severe that virtually none of the candidates will conform. Also, restrictions that
are based on row number and column number do not make sense in the context of a candidate design. Your
restrictions macro can recognize when it is in this phase because the macro variable &main is set to 0 and the
macro variable &pass is set to 1 or 2. You can conditionally execute code in this step or not using the following
macro statements.
%if &main eq 0 and &pass ge 1 and &pass le 2)
%then %do; /* execute on candidates */
%if not (&main eq 0 and &pass ge 1 and &pass le 2)
%then %do; /* not execute on candidates */
286 TS-677E Multinomial Logit, Discrete Choice Modeling
For simple restrictions, not involving the column exchange indices (j1, j2, j3) you probably do not need to
worry about this step. If you use j1, j2, or j3, you will need to either not execute your restrictions in this step
or conditionally execute some assignment statements that set up j1, j2, and j3 appropriately. Ordinarily for
this step, xmat contains the candidate design, x contains the ith row, j1 = 0; j2 = 0; j3 = 0; and i
is set to the candidate row number.
Main Coordinate-Exchange Algorithm In this phase, the macro is used to impose restrictions on the design as
it is being built in the coordinate-exchange algorithm. Your restrictions macro can recognize when it is in this
phase because the macro variable &main is set to 1 and the macro variable &pass is set to 1, 2, or 3. You can
conditionally execute code in this step or not using the following macro statements.
%if &main eq 1 and &pass ge 1 and &pass le 3)
%then %do; /* execute on coordinate exchange */
%if not (&main eq 1 and &pass ge 1 and &pass le 3)
%then %do; /* not execute on coordinate exchange */
For this step, xmat contains the candidate design, x contains the ith row, j1 contains the column index, j2 and
j3 are zero (unless you are using exchange=, in which case j1 and j2 are indexes of other columns being
exchanged), and i is the row number.
Restrictions Violations Check In this phase, the macro is used to check the design when there are restrictions and
options=accept. Your restrictions macro can recognize when it is in this phase because the macro variable
&main is set to 1 and the macro variable &pass is greater than 3. You can conditionally execute code in this
step or not using the following macro statements.
%if &main eq 1 and &pass gt 3) %then %do; /* execute on final check */
%if not (&main eq 1 and &pass gt 3) %then %do; /* not execute on final check */
For this step, xmat contains the candidate design, x contains the ith row, j1 = 0; j2 = 0; j3 = 0; and
i is the row number.
Here is an example of a partial profile macro that does what the partial=4 option does.
%macro partprof;
nvary = sum(x ^= 1);
%if &main %then %do;
if i = 1 then bad = nvary;
else bad = abs(nvary - 4);
%end;
%else %do;
bad = ^ (nvary = 0 | nvary = 4);
%end;
%mend;
In the main algorithm, when imposing restrictions on the design, we restrict the first run to be constant and all
other runs to have four attributes varying. For the candidate-set restrictions, when MAIN is zero, any observation
with zero or four varying factors is acceptable. For the candidate-set restrictions, there is no reason to count the
number of violations. A candidate run is either acceptable or not. We do not worry about the syntax error or final
check steps; both versions will work fine in either.
The Macros 287
The Macros
The autocall macros that are used in this report are documented in this section on the indicated pages.
The “Release” column indicates the first SAS release in which each macro was distributed. If your site has
installed the autocall libraries supplied by SAS and uses the standard configuration of SAS supplied soft-
ware, you need to ensure that the SAS system option mautosource is in effect to begin using the auto-
call macros. Note however, that Version 9.0 was finished before the macros were finalized and this book
finished. Hence there are a few differences between the macros used in this book and those shipped with
Version 9.0 of SAS. If you are running version 8.2 or version 9.0 of SAS, get the latest macros from the
web at [Link] [Link] or by writing [Link]@[Link]. These
macros will not work with Version 6.12. You should install all of these macros, not just one. Some of the macros
call other macros and will not work if the other macros are not there or if only older versions of the other macros
are there. For example, the %MktEx macro calls the %MktRuns and %MktDes macros.
The macros do not have to be included (for example, with a %include statement). They can be called directly
once they are properly installed. For more information about autocall libraries, refer to SAS Macro Language:
Reference. On a PC for example, the autocall library may be installed in the statnsasmacro directory off of
your SAS root directory. The name or your SAS root directory could be anything, but it is probably something
like SAS or SASnV8. One way to find the right directory is to use Start ! Find to find one of the existing
autocall macros such as [Link] or [Link].
Unix should have a similar directory structure to the PC. The autocall library in Unix may be installed in the
stat/sasmacro directory off of your SAS root directory. On MVS, each macro will be a different member
of a PDS. For details on installing autocall macros, consult your host documentation.
Usually, an autocall library is a directory containing individual files, each of which contains one macro definition.
An autocall library can also be a SAS catalog. To use a directory as a SAS autocall library, store the source
code for each macro in a separate file in the directory. The name of the file must be the same as the macro
name, typically followed by .sas. For example, the macro %MktEx must typically be stored in a file named
[Link]. On most hosts, the reserved fileref sasautos is assigned at invocation time to the autocall
library supplied by SAS or another one designated by your site. If you are specifying your own autocall libraries,
remember to concatenate the autocall library supplied by SAS with your autocall libraries so that these macros
will also be available. For details, refer to your host documentation and SAS macro language documentation.
288 TS-677E Multinomial Logit, Discrete Choice Modeling
Macro Errors
Usually, if you make a mistake in specifying macro options, the macro will print an informative message and
quit. These macros go to great lengths to check their input and issue informative errors. However, complete error
checking is impossible in macros, and sometimes you will get a cascade of less than helpful error messages.
In that case, you will have to check the input and hunt for errors. One of the more common errors is a missing
comma between options. Sometimes for harder errors, specifying options mprint; will help you locate the
problem. Once you think you know which option is involved, be sure to also check the option before and after in
your macro invocation, because that might be where the problem really is. If you have problems with a %MktEx
macro restrictions macro, see page 285 for a suggestion on how to diagnose the problem.
The %MktRuns and %PhChoice macros use PROC TEMPLATE and ODS to create customized output tables.
Typically, the instructions for this customization, created by PROC TEMPLATE, are stored in a file under the
sasuser directory with a host dependent name. On some hosts, this name is templat.sas7bitm. On
other hosts, the name is some variation of the name templat. Sometimes this file can be corrupted. When this
happens, these macros will not run correctly, and you will see error messages including errors about invalid pages.
The solution is to find the corrupt file under sasuser and delete it (using your ordinary operating system file
deletion method). After that, these macros should run fine again. If you have run any other PROC TEMPLATE
customizations, you will need to rerun them after deleting the file. For more information, see “Template Store”
or “Item Store” in the SAS ODS documentation.
Sometimes, you will run the %MktEx macro, and everything will seem to run fine in the entire job, but at the end
of your SAS log, you will see the message:
ERROR: Errors printed on page ....
Typically, this is caused by one or more PROC FACTEX steps failing to find the requested design. When this
happens, the macro recovers and continues searching. The macro does not always know in advance if PROC
FACTEX will succeed. The only way for it to find out is for it to try. The macro suppresses the PROC FACTEX
error messages along with most other notes and warnings that would ordinarily come out. However, SAS still
knows that a procedure tried to print an error message, and prints an error at the end of the log. This error can be
ignored.
%ChoicEff Macro
The %ChoicEff autocall macro is used to find efficient experimental designs for choice experiments. You
supply sets of candidate alternatives. The macro searches the candidates for an efficient experimental design a
design in which the variances of the parameter estimates are minimized, given an assumed parameter vector .
There are two ways you can use the macro:
You can create a candidate set of alternatives, and the macro will create a design consisting of choice
sets built from the alternatives you supplied. You must designate for each candidate alternative the design
alternative(s) for which it is a candidate. For a branded study with m brands, you must create m lists of
candidate alternatives, one for each brand.
You can create a candidate set of choice sets, and the macro will build a design from the choice sets that
you supplied. Typically, you would only use this approach when there are restrictions on across alternative
restrictions (certain alternatives may not appear with certain other alternatives).
If this happens, please write [Link]@[Link], and I will see if I can make the macros better handle that problem in the next
release. Send all the code necessary to reproduce what you have done.
The Macros 289
The %ChoicEff macro uses a modified Federov algorithm, just like PROC OPTEX and the %MktEx macro.
First, the %ChoicEff macro either constructs a random initial design from the candidates or it uses an initial
design that you specified. The macro considers swapping out every design alternative/set and replacing it with
each candidate alternative/set. Typically, you use as a candidate set a full-factorial, fractional-factorial, or a tabled
design created with the %MktEx macro. Swaps that increase efficiency are performed. The process of evaluating
and swapping continues until efficiency stabilizes. This process is repeated with different initial designs, and the
best design is output for use. The key differences between the %ChoicEff macro and the %MktEx macro are as
follows. The %ChoicEff macro requires you to specify the true (or assumed true) parameters and it optimizes
the variance matrix for a multinomial logit model, whereas PROC OPTEX and the %MktEx macro optimize the
variance matrix for a linear model, which does not depend on the parameters.
Here is an example. This example creates a design for a generic model with 3 three-level factors. First, the
%MktEx macro is used to create a set of candidate alternatives, where x1-x3 are the factors. Note that the n=
specification allows expressions. Our candidate set must also contain flag variables, one for each alternative, that
flag which candidates can be used for which alternative(s). Since this is a generic model, each candidate can
appear in any alternative, so we need to add flags that are constant: f1=1 f2=1 f3=1. The %MktEx macro
does not allow you to create constant factors. Instead, we can use the %MktLab macro to add the flag variables,
essentially by specifying that we have multiple intercepts. The option int=f1-f3 creates three variables with
values all one. The default output data set is called FINAL. Next, the %ChoicEff macro is run to find an
efficient design for the unbranded, purely generic model assuming = 0. Here is the code.
%mktex(3 ** 3, n=3**3, seed=238)
%mktlab(int=f1-f3)
1 x11 0 x1 1
2 x12 0 x1 2
3 x21 0 x2 1
4 x22 0 x2 2
5 x31 0 x3 1
6 x32 0 x3 2
Variable Standard
n Name Label Variance DF Error
Set x1 x2 x3
1 2 1 1
1 2 2
3 3 3
2 2 2 3
3 3 2
1 1 1
3 2 1 1
3 2 3
1 3 2
4 3 2 2
2 3 1
1 1 3
5 1 2 1
3 1 3
2 3 2
6 1 2 2
3 3 1
2 1 3
7 1 3 3
3 2 1
2 1 2
8 1 1 2
2 2 3
3 3 1
9 3 1 2
1 3 3
2 2 1
The output from the %ChoicEff macro consists of a list of the parameter names, values and labels, followed by
two iteration histories (each based on a different random initial design), then a brief report on the most efficient
design found, and finally a table with the parameter names, variances, df, and standard errors. The design is
printed using PROC PRINT.
The Macros 291
Here is another example. These next steps directly create an optimal design for this generic model and evaluate
its efficiency using the %ChoicEff macro and the initial design options. The DATA step creates a cyclic design.
In a cyclic design, the factor levels increase cyclically from one alternative to the next. The levels for a factor for
the three alternatives will always be one of the following: (1, 2, 3) or (2, 3, 1) or (3, 1, 2).
* Cyclic (Optimal) Design;
data x(keep=f1-f3 x1-x3);
retain f1-f3 1;
d1 = ceil(_n_ / 3); d2 = mod(_n_ - 1, 3) + 1; input d3 @@;
do i = -1 to 1;
x1 = mod(d1 + i, 3) + 1;
x2 = mod(d2 + i, 3) + 1;
x3 = mod(d3 + i, 3) + 1;
output;
end;
datalines;
1 2 3 3 1 2 2 3 1
;
Obs x1 x2 x3 f1 f2 f3
1 1 1 1 1 1 1
2 2 2 2 1 1 1
3 3 3 3 1 1 1
4 1 2 2 1 1 1
5 2 3 3 1 1 1
6 3 1 1 1 1 1
.
.
.
25 3 3 1 1 1 1
26 1 1 2 1 1 1
27 2 2 3 1 1 1
1 x11 0 x1 1
2 x12 0 x1 2
3 x21 0 x2 1
4 x22 0 x2 2
5 x31 0 x3 1
6 x32 0 x3 2
292 TS-677E Multinomial Logit, Discrete Choice Modeling
Variable Standard
n Name Label Variance DF Error
These next steps use the %MktEx and %MktRoll macros to create a candidate set of choice sets and the
%ChoicEff macro to search for an efficient design using the candidate-set-swapping algorithm.
%mktex(3 ** 9, n=2187)
data key;
input (x1-x3) ($);
datalines;
x1 x2 x3
x4 x5 x6
x7 x8 x9
;
data full(drop=i);
set final;
array f[3];
do i = 1 to 3; f[i] = (brand eq i); end;
run;
Obs x1 x2 x3 Brand f1 f2 f3
1 1 1 1 1 1 0 0
2 1 1 1 2 0 1 0
3 1 1 1 3 0 0 1
4 1 1 2 1 1 0 0
5 1 1 2 2 0 1 0
6 1 1 2 3 0 0 1
7 1 1 3 1 1 0 0
8 1 1 3 2 0 1 0
9 1 1 3 3 0 0 1
1 Brand1 0 Brand 1
2 Brand2 0 Brand 2
3 Brand3 0 Brand 3
4 Brand1x11 0 Brand 1 * x1 1
5 Brand1x12 0 Brand 1 * x1 2
6 Brand2x11 0 Brand 2 * x1 1
7 Brand2x12 0 Brand 2 * x1 2
8 Brand3x11 0 Brand 3 * x1 1
9 Brand3x12 0 Brand 3 * x1 2
.
.
.
294 TS-677E Multinomial Logit, Discrete Choice Modeling
Variable Standard
n Name Label Variance DF Error
Redundant Variables:
Brand3
Notice that at each step, the efficiency is zero, but a nonzero ridged value is printed. This model contains a
structural-zero coefficient in Brand3. While we need alternative-specific effects for Brand 3 (like Brand3x11
and Brand3x12), we do not need the Brand 3 effect (Brand3), which is a structural-zero effect. This can
be seen from both the ’Redundant Variables’ list and from looking at the variance and df table. The inclusion
The Macros 295
of the Brand3 term in the model makes the efficiency of the design zero. However, the %ChoicEff macro
can still optimize the goodness of the design by optimizing a ridged efficiency criterion. That is what is shown
in the iteration history. The option converge=1e-12 was specified because for this example, iteration stops
prematurely with the default convergence criterion. These next steps switch to a full-rank coding, dropping the
redundant variable Brand3, and using the output from the last step as the initial design.
%choiceff(data=full, init=best(keep=index), drop=brand3,
model=class(brand brand*x1 brand*x2 brand*x3 / zero=’ ’),
nsets=15, flags=f1-f3, beta=zero, converge=1e-12);
The option drop=brand3 is used to drop the parameter with the zero coefficient. We could have moved
the brand specification into its own class specification (separate from the alternative-specific effects) and not
specified zero=’ ’ with it (see for example page 296). However, sometimes it is easier to specify a model
with more terms than you really need, and then list the terms to drop, so that is what we illustrate here.
In this usage of init= with alternative swapping, the only part of the initial design that is required is the Index
variable. It contains indices into the candidate set of the alternatives that are used to make the initial design. This
usage is for the situation where the initial design was output from the macro. (In contrast, in the example usage
on page 291, the option initvars=x1-x3 was specified because the initial design was not created by the
%ChoicEff macro.) Here is some of the output. Notice that now there are no zero parameters so D-efficiency
can be directly computed.
Variable Standard
n Name Label Variance DF Error
These next steps handle the same problem, only this time, we use the set-swapping algorithm, and we will specify
a parameter vector that is not zero. At first, we will omit the beta= option, just to see the coding. We specified
the effects option in the PROC TRANSREG class specification to get -1, 0, 1 coding.
%mktex(3 ** 9, n=2187)
data key;
input (Brand x1-x3) ($);
datalines;
1 x1 x2 x3
2 x4 x5 x6
3 x7 x8 x9
;
1 Brand1 . Brand 1
2 Brand2 . Brand 2
3 Brand1x11 . Brand 1 * x1 1
4 Brand1x12 . Brand 1 * x1 2
5 Brand2x11 . Brand 2 * x1 1
6 Brand2x12 . Brand 2 * x1 2
7 Brand3x11 . Brand 3 * x1 1
8 Brand3x12 . Brand 3 * x1 2
9 Brand1x21 . Brand 1 * x2 1
10 Brand1x22 . Brand 1 * x2 2
11 Brand2x21 . Brand 2 * x2 1
12 Brand2x22 . Brand 2 * x2 2
13 Brand3x21 . Brand 3 * x2 1
14 Brand3x22 . Brand 3 * x2 2
15 Brand1x31 . Brand 1 * x3 1
16 Brand1x32 . Brand 1 * x3 2
17 Brand2x31 . Brand 2 * x3 1
18 Brand2x32 . Brand 2 * x3 2
19 Brand3x31 . Brand 3 * x3 1
20 Brand3x32 . Brand 3 * x3 2
Now that we are sure we know the order of the parameters, we can specify the assumed betas on the beta=
option. These numbers are based on prior research or our expectations of approximately what we expect the
parameter estimates will be. We also specified n=100 on this run, which is a sample size we are considering.
%choiceff(data=rolled, nsets=15, nalts=3, n=100, seed=543,
beta=1 2 -0.5 0.5 -0.75 0.75 -1 1
-0.5 0.5 -0.75 0.75 -1 1 -0.5 0.5 -0.75 0.75 -1 1,
model=class(brand)
class(brand*x1 brand*x2 brand*x3 / effects zero=’ ’))
The Macros 297
Here is some of the output. Notice that parameters and test statistics are incorporated into the output. The n=
value is incorporated into the variance matrix and hence the efficiency statistics, variances and tests.
Prob >
Variable Assumed Standard Squared
n Name Label Variance Beta DF Error Wald Wald
These next steps create a design for a cross-effects model with five brands at three prices and a constant alterna-
tive. Note the choice-set-swapping algorithm can handle cross effects but not the alternative-swapping algorithm.
%mktex(3 ** 5, n=3**5)
data key;
input (Brand Price) ($);
datalines;
1 x1
2 x2
3 x3
4 x4
5 x5
. .
;
%mktroll(design=design, key=key, alt=brand, out=rolled, keep=x1-x5)
proc print; by set; id set; where set in (1, 48, 101, 243); run;
The keep= option on the %MktRoll macro is used to keep the price variables that are needed to make the cross
effects. Here are a few of the candidate choice sets.
298 TS-677E Multinomial Logit, Discrete Choice Modeling
1 1 1 1 1 1 1 1
2 1 1 1 1 1 1
3 1 1 1 1 1 1
4 1 1 1 1 1 1
5 1 1 1 1 1 1
. 1 1 1 1 1
48 1 1 1 2 3 1 3
2 2 1 2 3 1 3
3 3 1 2 3 1 3
4 1 1 2 3 1 3
5 3 1 2 3 1 3
. 1 2 3 1 3
101 1 2 2 1 3 1 2
2 1 2 1 3 1 2
3 3 2 1 3 1 2
4 1 2 1 3 1 2
5 2 2 1 3 1 2
. 2 1 3 1 2
243 1 3 3 3 3 3 3
2 3 3 3 3 3 3
3 3 3 3 3 3 3
4 3 3 3 3 3 3
5 3 3 3 3 3 3
. 3 3 3 3 3
Notice that x1 contains the price for Brand 1, x2 contains the price for Brand 2, and so on, and the price of brand
i in a choice set is the same, no matter which alternative it is stored with.
Here is the %ChoicEff macro call for creating the choice design with cross effects.
%choiceff(data=rolled, seed=17,
model=class(brand brand*price / zero=none)
identity(x1-x5) * class(brand / zero=none),
nsets=20, nalts=6, beta=zero);
Cross effects are created by interacting the price factors with brand. See pages 179 and 217 for more information
about cross effects.
Here is the redundant variable list from the log.
Redundant Variables:
Next, we will run the macro again, this time requesting a full-rank model. The list of dropped names was created
by copying from the redundant variable list. Also, zero=none was changed to zero=’ ’ so no level would
be zeroed for Brand but the last level of Price would be zeroed.
%choiceff(data=rolled, seed=17,
model=class(brand brand*price / zero=’ ’)
identity(x1-x5) * class(brand / zero=none),
drop=x1Brand1 x2Brand2 x3Brand3 x4Brand4 x5Brand5,
nsets=20, nalts=6, beta=zero);
The Macros 299
Here is the last part of the output. Notice that we have five brand parameters, two price parameters for each of
the five brands, and four cross effect parameters for each of the five brands.
Variable Standard
n Name Label Variance DF Error
model= model-specification
specifies a PROC TRANSREG model statement list of effects. There are many potential forms for the model
specification and a number of options. See the SAS/STAT PROC TRANSREG documentation.
300 TS-677E Multinomial Logit, Discrete Choice Modeling
nsets= n
specifies the number of choice sets desired.
You must specify exactly one of these next two options. When the candidate set consists of individual alternatives
to be swapped, specify the alternative flags with flags=. When the candidate set consists of entire sets of
alternatives to be swapped, specify the number of alternatives in each set with nalts=.
flags= variable-list
specifies variables that flag the alternative(s) for which each candidate may be used. There must be one flag
variable per alternative. If every candidate can be used in all alternatives, then the flags are constant. For example,
with three alternatives, create these constant flags: f1=1 f2=1 f3=1. Otherwise, with three alternatives,
specify flags=f1-f3 and create a candidate set where: alternative 1 candidates are indicated by f1=1 f2=0
f3=0, alternative 2 candidates are indicated by f1=0 f2=1 f3=0, and alternative 3 candidates are indicated
by f1=0 f2=0 f3=1.
nalts= n
specifies the number of alternatives in each choice set.
The rest of the parameters are optional. You may specify zero or more of them.
bestcov= SAS-data-set
specifies a name for the data set containing the covariance matrix for the best design. By default, this data set is
called BESTCOV.
bestout= SAS-data-set
specifies a name for the data set containing the best design. By default, this data set is called BEST.
beta= list
specifies the true parameters. By default, when beta= is not specified, the macro just reports on coding. You
can specify beta=zero to assume all zeros. Otherwise specify a number list: beta=1 -1 2 -2 1 -1.
The Macros 301
converge= n
specifies the D-efficiency convergence criterion. By default, converge=0.005.
cov= SAS-data-set
specifies a name for the data set containing all of the covariance matrices for all of the designs. By default, this
data set is called COV.
data= SAS-data-set
specifies the input choice candidate set. By default, the macro uses the last data set created.
drop= variable-list
specifies a list of variables to drop from the model. If you specified a less-than-full-rank model= specification,
you can use drop= to produce a full rank coding. When there are redundant variables, the macro prints a list
that you can use in the drop= option on a subsequent run.
fixed= variable-list
specifies the variable that flags the fixed alternatives. When fixed=variable is specified, the init= data
set must contain the named variable, which indicates which alternatives are fixed (cannot be swapped out) and
which ones may be changed. Example: fixed=fixed, init=init, initvars=x1-x3
fixed= may be specified only when both init= and initvars= are specified.
init= SAS-data-set
specifies an input initial design data set. Null means a random start. One usage is to specify the bestout=
data set for an initial start. When flags= is specified, init= must contain the index variable. Example:
init=best(keep=index). When nalts= is specified, init= must contain the choice set variable. Ex-
ample: init=best(keep=set).
Alternatively, the init= data set can contain an arbitrary design, potentially created outside this macro. In that
case, you must also specify initvars=factors, where factors are the factors in the design, for example
initvars=x1-x3. When alternatives are swapped, this data set must also contain the flags= variables.
When init= is specified with initvars=, the data set may also contain a variable specified on the fixed=
option, which indicates which alternatives are fixed, and which ones can be swapped in and out.
intiter= n
specifies the maximum number of internal iterations. Specify intiter=0 to just evaluate efficiency of an
existing design. By default, intiter=10.
initvars= variable-list
specifies the factor variables in the init= data set that must match up with the variables in the data= data set.
See init=. All of these variables must be of the same type.
302 TS-677E Multinomial Logit, Discrete Choice Modeling
maxiter= n
iter= n
specifies the maximum iterations (designs to create). By default, maxiter=10.
morevars= variable-list
specifies more variables to add to the model. This option gives you the ability to specify a list of variables to
copy along as is, through the TRANSREG coding, then add them to the model.
n= n
specifies the number of observations to use in the variance matrix formula. By default, n=1.
options= options-list
specifies binary options. By default, none of these options are specified. Specify one or more of the following
values after options=.
coded
prints the coded candidate set.
detail
prints the details of the swaps.
nocode
skips the PROC TRANSREG coding stage, assuming that [Link]– CAND was created by a previ-
ous step. This is most useful with set swapping when the candidate set can be big. It is important with
options=nocode to note that the effect of morevars= and drop= in previous runs has already been
taken care of, so do not specify them (unless for instance you want to drop still more variables).
nodups
prevents the same choice set from coming out more than once. This option does not affect the initialization,
so the random initial design may have duplicates. This options forces duplicates out during the iterations,
so do not set intiter= to a small value. It may take several iterations to eliminate all duplicates. It is
possible that efficiency will decrease as duplicates are forced out. With set swapping, this macro checks
the candidate choice set numbers to avoid duplicates. With alternative swapping, this macro checks the
candidate alternative index to avoid duplicates. The macro does not look at the actual factors. This makes
the checks faster, but if the candidate set contains duplicate choice sets or alternatives, the macro may not
succeed in eliminating all duplicates. Run the %MktDups macro (which looks at the actual factors) on the
design to check and make sure all duplicates are eliminated. If you are using set swapping to make a generic
design make sure you run the %MktDups macro on the candidate set to eliminate duplicate choice sets in
advance.
notes
stops the macro from submitting the statement options nonotes.
notests
suppresses printing the diagonal of the covariance matrix, and hypothesis tests for this n and . When
is not zero, the results include a Wald test statistic ( divided by the standard error), which is normally
distributed, and the probability of a larger squared Wald statistic.
orthcan
orthogonalizes the candidate set.
The Macros 303
out= SAS-data-set
specifies a name for the output SAS data set with the final designs. The default is out=results.
seed= n
specifies the random number seed. By default, seed=0, and clock time is used as the random number seed. By
specifying a random number seed, results should be reproducible within a SAS release for a particular operating
system. However, due to machine differences, some results may not be exactly reproducible on other machines,
although you would expect the efficiency differences to be slight.
submat= number-list
specifies a submatrix for which efficiency calculations are desired. Specify an index vector. For example, with
3 three-level factors, a, b, and c, and the model class(a b c a*b), specify submat=1:6, to see the
efficiency of just the 6 6 matrix of main effects. Specify submat=3:6, to see the efficiency of just the 4 4
matrix of b and c main effects.
types= integer-list
specifies the number of sets of each type to put into the design. This option is used when you have multiple
types of choice sets and you want the design to consist of only certain numbers of each type. This option can
be specified with the set-swapping algorithm. The argument is an integer list. When you specify types=, you
must also specify typevar=. Say you are creating a design with 30 choice sets, and you want the first 10 sets
to consist of sets whose typevar= variable in the candidate set is type 1, and you want the rest to be type 2.
You would specify types=10 20.
typevar= variable
specifies a variable in the candidate data set that contains choice set types. The types must be integers starting
with 1. This option can only be specified with the set-swapping algorithm. When you specify typevar=, you
must also specify types=.
weight= weight-variable
specifies an optional weight variable. Typical usage is with an availability design. Give unavailable alternatives
a weight of zero and available alternatives a weight of one. The number of alternatives must always be constant,
so varying numbers of alternatives are handled by giving unavailable or unseen alternatives a weight of zero.
%MktAllo Macro
The %MktAllo autocall macro is used for manipulating data for an allocation choice experiment. It takes as
input a data set with one row for each alternative of each choice set. For example, in a study with 10 brands plus
a constant alternative and 27 choice sets, there are 27 11 = 297 observations in the input data set. Here is
an example of an input data set. It contains a choice set variable, product attributes (Brand and Price) and a
frequency variable (Count) that contains the total number of times that each alternative was chosen.
1 1 0
2 1 Brand 1 $50 103
3 1 Brand 2 $75 58
4 1 Brand 3 $50 318
5 1 Brand 4 $100 99
6 1 Brand 5 $100 54
304 TS-677E Multinomial Logit, Discrete Choice Modeling
7 1 Brand 6 $100 83
8 1 Brand 7 $75 71
9 1 Brand 8 $75 58
10 1 Brand 9 $75 100
11 1 Brand 10 $50 56
.
.
.
296 27 Brand 9 $100 94
297 27 Brand 10 $50 65
The end result is a data set with twice as many observations that contains the number of times each alternative
was chosen and the number of times it was not chosen. This data set also contains a variable c with values 1 for
first choice and 2 for second or subsequent choice.
1 1 0 1
2 1 1000 2
3 1 Brand 1 $50 103 1
4 1 Brand 1 $50 897 2
5 1 Brand 2 $75 58 1
6 1 Brand 2 $75 942 2
7 1 Brand 3 $50 318 1
8 1 Brand 3 $50 682 2
.
.
.
593 27 Brand 10 $50 65 1
594 27 Brand 10 $50 935 2
data= SAS-data-set
specifies the input SAS data set. By default, the macro uses the last data set created.
freq= variable
specifies the frequency variable, which contains the number of times this alternative was chosen. This option
must be specified.
The Macros 305
nalts= n
specifies the number of alternatives (including if appropriate the constant alternative). This option must be
specified.
out= SAS-data-set
specifies the output SAS data set. The default is out=allocs.
vars= variable-list
specifies the variables in the data set that will be used in the analysis but not the freq= variable. This option
must be specified.
%MktBal Macro
The %MktBal macro creates linear experimental designs using an algorithm that ensures that the design is
perfectly balanced, or in the case when the number of levels of a factor does not divide the number of runs,
as close to perfectly balanced as possible. Do not use the %MktBal macro until you have tried the %MktEx
macro and determined that it does not make a design that is balanced enough for your needs. The %MktEx
macro can directly create hundreds of orthogonal and balanced designs that the %MktBal algorithm will never
be able to find. Even when the %MktEx macro cannot create an orthogonal and balanced design, it will usually
find a nearly balanced design. Designs created with the %MktBal macro, while perfectly balanced, may be less
efficient than designs found with the %MktEx macro, and for large problems, the %MktBal macro can be slow.
The %MktBal macro has several options that can make it run faster for large problems, but at a price of an
even further decrease in D-efficiency. It is likely that the current algorithm used by the %MktBal macro will be
changed in the future to use some now unknown algorithm that is both faster and better.
The %MktBal macro is not a full-featured experimental design generator. For example, you cannot specify
interactions that you want to estimate or specify restrictions such as which levels may or may not appear together.
You must use the %MktEx macro for that. The %MktBal macro builds a design by creating a balanced first
factor, optimally blocking it to create the second factor, then optimally blocking the first two factors to create the
third, and so on. Once it creates all factors, it refines each factor. Each factor is in turn removed from the design,
and the rest of the design is reblocked, replacing the initial factor if the new design is more D-efficient.
Here is a simple example of creating a design with 2 two-level factors and 3 three-level factors in 18 runs. The
%MktEval macro evaluates the results. This design is in fact optimal.
%mktbal(2 2 3 3 3, n=18, seed=151)
%mkteval;
In all cases, the factors are named x1, x2, x3, ... and so on.
This next example, at 120 runs and with factor levels greater than 5, is starting to get big and hence, by default,
will run slowly. You can use the maxstarts= and maxiter= options to make the macro run more quickly.
For example, the second example below runs much faster than the first.
%mktbal(2 3 4 5 6 7 8 9 10, n=120, options=progress, seed=17)
list
specifies a list of the numbers of levels of all the factors. For example, for 3 two-level factors specify ei-
ther 2 2 2 or 2 ** 3. Lists of numbers, like 2 2 3 3 4 4 or a levels**number of factors syntax like:
2**2 3**2 4**2 can be used, or both can be combined: 2 2 3**4 5 6. The specification 3**4 means
four three-level factors. You must specify a list. Note that the factor list is a positional parameter. This means it
must come first, and unlike all other parameters, it is not specified after a name and an equal sign.
n= n
specifies the number of runs in the design. You must specify n=. You can use the %MktRuns macro to get
suggestions for values of n=.
These next options, control some of the details of the %MktBal macro.
maxiter= n
iter= n
specifies the maximum iterations (designs to create). By default, maxiter=5.
maxstarts= n
specifies the maximum number of random starts for each factor. With larger values, the macro tends to find
slightly better designs at a cost of slower run times. The default is maxstarts=10.
maxtries= n
specifies the maximum number of times to try refining each factor after the initialization stage. The default is
maxtries=10.
options= options-list
specifies binary options. By default, none of these options are specified. Specify one or more of the following
values after options=.
noprint
specifies that the final D-efficiency should not be printed.
progress
reports on the macro’s progress. For large numbers of factors, a large number or runs, or when the number
of levels is large, this macro is slow. The options=progress specification gives you information about
which step is being executed.
The Macros 307
seed= n
specifies the random number seed. By default, seed=0, and clock time is used as the random number seed. By
specifying a random number seed, results should be reproducible within a SAS release for a particular operating
system. However, due to machine differences, some results may not be exactly reproducible on other machines,
although you would expect the efficiency differences to be slight.
%MktBlock Macro
The %MktBlock autocall macro is used to block a choice design or an ordinary linear experimental design.
When a choice design is too large to show all choice sets to each subject, the design is blocked and a block of
choice sets is shown to each subject. For example, if there are 36 choice sets, instead of showing each subject
36 sets, you could instead create 2 blocks and show 2 groups of subjects 18 sets each. You could also create 3
blocks of 12 choice sets or 4 blocks of 9 choice sets. You can also request just one block if you want to see the
correlations and frequencies among all of the attributes of all of the alternatives of a choice design.
The design can be in one of two formats. Typically, a choice design has one row for each alternative of each
choice set and one column for each of the attributes. Typically, this kind of design is produced by either the
%ChoicEff or %MktRoll macro. Alternatively, a “linear” design is an intermediate step in preparing some
choice designs. The linear design has one row for each choice set and one column for each attribute of each
alternative. Typically, the linear design is produced by the %MktEx macro. The output from the %MktBlock
macro is a data set containing the design, with the blocking variable added and hence not in the original order,
with runs or choice sets nested within blocks.
The macro tries to create a blocking factor that is uncorrelated with every attribute of every alternative. In other
words, the macro is trying to optimally add one additional factor, a blocking factor, to the linear design. It is
trying to make a factor that is orthogonal to all of the attributes of all of the alternatives. For linear designs, you
can usually just ask for a blocking factor directly as just another factor in the design, and then use the %MktLab
macro to provide a name like Block, or you can use the %MktBlock macro.
Here is an example of creating the blocking variable directly.
%mktex(3 ** 7, n=27)
%mktlab(vars=x1-x6 Block)
Here is an example of creating a design then blocking it.
%mktex(3 ** 6, n=27, seed=350)
Block x1 x2 x3 x4 x5 x6
Block 1 0 0 0 0 0 0
x1 0 1 0 0 0 0 0
x2 0 0 1 0 0 0 0
x3 0 0 0 1 0 0 0
x4 0 0 0 0 1 0 0
x5 0 0 0 0 0 1 0
x6 0 0 0 0 0 0 1
308 TS-677E Multinomial Logit, Discrete Choice Modeling
Summary of Frequencies
There are 0 Canonical Correlations Greater Than 0.316
Frequencies
Block 9 9 9
x1 9 9 9
x2 9 9 9
x3 9 9 9
x4 9 9 9
x5 9 9 9
x6 9 9 9
Block x1 3 3 3 3 3 3 3 3 3
Block x2 3 3 3 3 3 3 3 3 3
Block x3 3 3 3 3 3 3 3 3 3
Block x4 3 3 3 3 3 3 3 3 3
Block x5 3 3 3 3 3 3 3 3 3
Block x6 3 3 3 3 3 3 3 3 3
x1 x2 3 3 3 3 3 3 3 3 3
x1 x3 3 3 3 3 3 3 3 3 3
x1 x4 3 3 3 3 3 3 3 3 3
x1 x5 3 3 3 3 3 3 3 3 3
x1 x6 3 3 3 3 3 3 3 3 3
x2 x3 3 3 3 3 3 3 3 3 3
x2 x4 3 3 3 3 3 3 3 3 3
x2 x5 3 3 3 3 3 3 3 3 3
x2 x6 3 3 3 3 3 3 3 3 3
x3 x4 3 3 3 3 3 3 3 3 3
x3 x5 3 3 3 3 3 3 3 3 3
x3 x6 3 3 3 3 3 3 3 3 3
x4 x5 3 3 3 3 3 3 3 3 3
x4 x6 3 3 3 3 3 3 3 3 3
x5 x6 3 3 3 3 3 3 3 3 3
N-Way 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1
Block x1 x2 x3 x4 x5 x6
3 x1 1 0 0 0 0 0
x2 0 1 0 0 0 0
x3 0 0 1 0 1.00 0
x4 0 0 0 1 0 1.00
x5 0 0 1.00 0 1 0
x6 0 0 0 1.00 0 1
Notice that even with a perfect blocking variable like we have in this example, canonical correlations within each
block will not be all zero.
Here is the blocked linear design (3 blocks of nine choice sets). Note that in the linear version of the design,
there is one row for each choice set and all of the attributes of all of the alternatives are in the same row.
Block Run x1 x2 x3 x4 x5 x6
1 1 3 2 2 2 3 3
2 3 3 1 3 2 1
3 3 1 2 3 2 3
4 1 2 1 1 2 2
5 1 3 3 2 1 3
6 2 1 3 1 3 1
7 2 2 3 3 1 1
8 2 3 2 1 3 2
9 1 1 1 2 1 2
Block Run x1 x2 x3 x4 x5 x6
2 1 3 2 1 1 1 1
2 3 3 3 2 3 2
3 3 1 3 1 1 2
4 2 3 1 3 1 3
5 1 1 2 3 3 1
6 1 3 2 1 2 1
7 1 2 3 3 3 3
8 2 1 1 2 2 3
9 1 2 3 2 1 3
Block Run x1 x2 x3 x4 x5 x6
3 1 1 3 1 3 3 2
2 2 2 1 1 3 3
3 2 1 2 3 1 2
4 2 3 3 2 2 1
5 1 1 3 1 2 3
6 3 2 3 3 2 2
7 3 1 1 2 3 1
8 1 2 2 2 1 1
9 3 3 2 1 1 3
310 TS-677E Multinomial Logit, Discrete Choice Modeling
Next, we’ll create and block a choice design with two blocks of nine sets instead of blocking the linear version
of a choice design.
%mktex(3 ** 6, n=3**6)
Summary of Frequencies
There are 11 Canonical Correlations Greater Than 0.316
* - Indicates Unequal Frequencies
Frequencies
Block 9 9
* Alt1_x1 7 7 4
* Alt1_x2 8 2 8
* Alt1_x3 8 4 6
* Alt2_x1 5 5 8
* Alt2_x2 5 9 4
* Alt2_x3 4 8 6
The Macros 311
* Block Alt1_x1 4 3 2 3 4 2
* Block Alt1_x2 4 1 4 4 1 4
* Block Alt1_x3 4 2 3 4 2 3
* Block Alt2_x1 2 3 4 3 2 4
* Block Alt2_x2 3 4 2 2 5 2
* Block Alt2_x3 2 4 3 2 4 3
* Alt1_x1 Alt1_x2 3 1 3 4 1 2 1 0 3
* Alt1_x1 Alt1_x3 4 2 1 3 1 3 1 1 2
* Alt1_x1 Alt2_x1 0 4 3 2 0 5 3 1 0
* Alt1_x1 Alt2_x2 3 3 1 1 4 2 1 2 1
* Alt1_x1 Alt2_x3 1 4 2 2 2 3 1 2 1
* Alt1_x2 Alt1_x3 4 1 3 2 0 0 2 3 3
* Alt1_x2 Alt2_x1 1 3 4 1 0 1 3 2 3
* Alt1_x2 Alt2_x2 0 5 3 1 0 1 4 4 0
* Alt1_x2 Alt2_x3 2 2 4 0 2 0 2 4 2
* Alt1_x3 Alt2_x1 3 3 2 1 1 2 1 1 4
* Alt1_x3 Alt2_x2 2 5 1 2 1 1 1 3 2
* Alt1_x3 Alt2_x3 0 5 3 1 0 3 3 3 0
* Alt2_x1 Alt2_x2 1 3 1 1 3 1 3 3 2
* Alt2_x1 Alt2_x3 0 3 2 2 2 1 2 3 3
* Alt2_x2 Alt2_x3 0 3 2 3 3 3 1 2 1
N-Way 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
Note that in this example, the input is a choice design (as opposed to the linear version of a choice design) so the
results are in choice design format. There is one row for each alternative of each choice set.
1 1 1 3 1 3
2 2 3 1
1 2 1 2 1 1
2 1 2 3
.
.
.
2 1 1 2 1 1
2 3 2 3
2 2 1 2 2 1
2 1 3 2
.
.
.
312 TS-677E Multinomial Logit, Discrete Choice Modeling
alt= variable
specifies the variable to contain the alternative number. If this variable is in the input data set, it is excluded from
the factor list. The default is alt=Alt.
block= variable
specifies the variable to contain the block number. If this variable is in the input data set, it is excluded from the
factor list. The default is block=Block.
data= SAS-data-set
specifies either the choice or linear design. The choice design has one row for each alternative of each choice
set and one column for each of the attributes. Typically this design is produced by either the %ChoicEff
or %MktRoll macro. For choice designs, you must also specify the nalts= option. The default is
data=- last- . The linear design has one row for each choice set and one column for each attribute of each
alternative. Typically this design is produced by the %MktEx macro. This is the design that is input into the
%MktRoll macro.
factors= variable-list
vars= variable-list
specifies the factors in the design. By default, all numeric variables are used, except variables with names
matching those in the block=, set=, and alt= options. (By default, the variables Block, Set, Run, and
Alt are excluded from the factor list.) If you are using version 8.2 or an earlier SAS release with a branded
choice design (assuming the brand factor is called Brand), specify id=Brand. Do not add the brand factor to
the factor list unless you are using version 9.0 or a later SAS release.
id= variable-list
specifies variables in the data= data set to copy to the output data set. If you are using version 8.2 or an earlier
SAS release with a branded choice design (assuming the brand factor is called Brand), specify id=Brand. Do
not add the brand factor to the factor list unless you are using version 9.0 or a later SAS release.
initblock= variable
specifies the name of a variable in the data set that is to be used as the initial blocking variable for the first
iteration.
maxiter= n
iter= n
specifies the number of times to try to block the design starting with a different random blocking. By default,
the macro tries five random starts, and iteratively refines each until D-efficiency quits improving, then in the end
selects the blocking with the best D-efficiency.
nalts= n
specifies the number of alternatives in each choice set. If you are inputting a choice design, you must specify
nalts=, otherwise the macro assumes you are inputting a linear design.
The Macros 313
nblocks= n
specifies the number of blocks to create. The option nblocks=1 just reports information about the design. The
nblocks= option must be specified.
next= n
specifies how far into the design to go to look for the next swap. The specification next=1 specifies that
the macro should try swapping the level for each run with the level for the next run and all other runs. The
specification next=2 considers swaps with half of the other runs, which makes the algorithm run more quickly.
The macro considers swapping the level for run i with run i + 1 then uses the next= value to find the next
potential swaps. Other values, including nonintegers can be specified as well. For example next=1.5 considers
swapping observation 1 with observations 2, 4, 5, 7, 8, 10, 11, and so on. With smaller values, the macro tends
to find a slightly better blocking variable at a cost of much slower run time.
out= SAS-data-set
specifies the output data set with the block numbers. The default is out=blocked.
print= print-options
specifies both the %MktBlock and the %MktEval macro printing options, which control the printing of the
results. The default is print=normal. Values include:
corr canonical correlations
list list of big canonical correlations
freqs long frequencies list
summ frequency summaries
block canonical correlations within blocks
design blocked design
note blocking note
all all of the above
noprint no printed output
normal corr list summ block design note
short corr summ note
ridge= n
specifies the value to add to the diagonal of (X0 X) 1 to make it nonsingular. Usually, you will not need to
change this value. If you do, you probably will not notice any effect. Specify ridge=0 to use a generalized
inverse instead of ridging. The default is ridge=0.01.
seed= n
specifies the random number seed. By default, seed=0, and clock time is used as the random number seed. By
specifying a random number seed, results should be reproducible within a SAS release for a particular operating
system. However, due to machine differences, some results may not be exactly reproducible on other machines,
although you would expect the efficiency differences to be slight.
set= variable
specifies the variable to contain the choice set number. When nalts= is specified, the default is Set, otherwise
the default is Run. If this variable is in the input data set, it is excluded from the factor list.
314 TS-677E Multinomial Logit, Discrete Choice Modeling
%MktDes Macro
The %MktDes autocall macro creates efficient experimental designs. Throughout this report, we used the
%MktEx autocall macro, which calls the %MktDes macro, to design our experiments, Usually, we will not
need to call the %MktDes macro directly. At the heart of the %MktDes macro are PROC PLAN, PROC FAC-
TEX, and PROC OPTEX. We use macros instead of calling these procedures directly because the macros have a
simpler syntax. In extreme cases, a single-line macro call can generate hundreds of lines of otherwise tedious to
write procedure code.
The %MktDes macro creates efficient experimental designs. You specify the names of the factors and the number
of levels for each factor. You also specify the number of runs you want in your final design. Here for example is
how you can create a design in 18 runs with 2 two-level factors (x1 and x2) and 3 three-level factors (x3, x4,
and x5).
%mktdes(factors=x1-x2=2 x3-x5=3, n=18)
You can also optionally specify interactions that you want to be estimable. The macro creates a candidate design
in which every effect you want to be estimable is estimable, but the candidate design is bigger than you want.
By default, the candidate set is stored in a SAS data set called CAND1. The macro then uses PROC OPTEX to
search the candidate design for an efficient final design. By default, the final experimental design is stored in a
SAS data set called DESIGN.
When the full-factorial design is small (by default less than 2189 runs, although sizes up to 5000 or 6000 runs
are reasonably small) the experimental design problem is straightforward. First, the macro uses PROC PLAN to
create a full-factorial candidate set. Next, PROC OPTEX searches the full-factorial candidate set. For very small
problems (a few hundred candidates) PROC OPTEX will often find the optimal design, and for larger problems,
it may not find the optimal design, but given sufficient iteration (for example, specify iter=100 or more) it will
find very good designs. Run time will typically be a few seconds or a few minutes, but it could run longer. Here is
a typical example of using the %MktDes macro to find an optimal nonorthogonal design when the full-factorial
design is small (108 runs):
*---Two two-level factors and 3 three-level factors in 18 runs---;
%mktdes(factors=x1-x2=2 x3-x5=3, n=18, maxiter=500)
When the full-factorial design is larger, the macro uses PROC FACTEX to create a fractional-factorial candidate
set. In those cases, the other methods found in the %MktEx macro usually make better designs than those found
with the %MktDes macro.
big= n
specifies the size at which the candidate set is considered to be big. By default, big=2188. If the size of the
full-factorial design is less than or equal to this size, and if PROC PLAN is in the run= list, the macro uses
PROC PLAN instead of PROC FACTEX to create the candidate set. The default of 2188 is max(211 ; 37 ) + 1).
Specifying values as large as big=6000 or even slightly more is often reasonable. However, run time is slower
as the size of the candidate set increases. The %MktEx macro coordinate-exchange algorithm will usually work
better than a candidate-set search when the full-factorial design has more than several thousand runs.
The Macros 315
cand= SAS-data-set
specifies the output data set with the candidate design (from PROC FACTEX or PROC PLAN). The default name
is Cand followed by the step number, for example: Cand1 for step 1, Cand2 for step 2, and so on. You should
only use this option when you are reading an external candidate set. When you specify step= values greater
than 1, the macro assumes the default candidate set names, CAND1, CAND2, and so on, were used in previous
steps. Specify just a data set name, no data set options.
classopts= options
specifies PROC OPTEX class statement options. The default, is classopts=param=orthref. You
probably never want to change this option.
coding= name
specifies the PROC OPTEX coding= option. This option is usually not needed.
examine= I | V
specifies the matrices that you want to examine. The option examine=I prints the information matrix, X0 X;
examine=V prints the variance matrix, (X0 X) 1 ; and examine=I V prints both. By default, these matrices
are not printed.
facopts= options
specifies PROC FACTEX statement options.
factors= factor-list
specifies the factors and the number of levels for each factor. The factors= option must be specified. All other
options are optional. Optionally, the number of pseudo-factors can also be specified. Here is a simple example
of creating a design with 10 two-level factors.
%mktdes(factors=x1-x10=2)
First, a factor list, which is a valid SAS variable list, is specified. The factor list must be followed by an equal
sign and an integer, which gives the number of levels. Multiple lists can be specified. For example, to create 5
two-level factors, 5 three-level factors, and 5 five-level factors, specify:
%mktdes(factors=x1-x5=2 x6-x10=3 x11-x15=5)
By default, this macro creates each factor from a minimum number of pseudo-factors. Pseudo-factors are not
output. They are used to create the factors of interest and then discarded. For example, with nlev=2, a three-
level factor x1 is created from 2 two-level pseudo-factors (- 1 and - 2) and their interaction by coding down:
(_1=1, _2=1) -> x1=1
(_1=1, _2=2) -> x1=2
(_1=2, _2=1) -> x1=3
(_1=2, _2=2) -> x1=1
This creates imbalance the 1 level appears twice as often as 2 and 3. Somewhat better balance can be obtained
by instead using three pseudo-factors. The number of pseudo-factors is specified in parentheses after the number
of levels. Example:
%mktdes(factors=x1-x5=2 x6-x10=3(3))
316 TS-677E Multinomial Logit, Discrete Choice Modeling
The levels 1 to 8 are coded down to 1 2 3 1 2 3 1 3, which is a little better balanced. The cost is candidate-set
size may increase and efficiency may actually decrease. Some researchers are willing to sacrifice a little bit of
efficiency in order to achieve better balance.
generate= options
specifies the PROC OPTEX generate statement options. By default, additional options are not added to the
generate statement.
interact= interaction-list
specifies interactions that must be estimable. By default, no interactions are guaranteed to be estimable. Exam-
ples:
interact=x1*x2
interact=x1*x2 x3*x4*x5
interact=x1|x2|x3|x4|x5@2
The interaction syntax is like PROC GLM’s and many of the other modeling procedures. It uses “*” for simple
interactions (x1*x2 is the interaction between x1 and x2), “|” for main effects and interactions (x1|x2|x3
is the same as x1 x2 x1*x2 x3 x1*x3 x2*x3 x1*x2*x3) and “@” to eliminate higher-order interac-
tions (x1|x2|x3@2 eliminates x1*x2*x3 and is the same as x1 x2 x1*x2 x3 x1*x3 x2*x3). The
specification “@2” allows only main effects and two-way interactions. Only “@” values of 2 or 3 are allowed.
iter= n
maxiter= n
specifies the PROC OPTEX iter= option which creates n designs. By default, iter=10.
keep= n
specifies the PROC OPTEX keep= option which keeps n designs. By default, keep=5.
nlev= n
specifies the number of levels from which factors are constructed through pseudo-factors and coding down. The
value must be a prime or a power of a prime: 2, 3, 4, 5, 7, 8, 9, 11 .... This option is used with PROC FACTEX:
factors factors / nlev=&nlev;
By default, the macro uses the minimum prime or power of a prime from the factors= list or 2 if no suitable
value is found.
method= name
specifies the PROC OPTEX method= search method option. The default is method=m- federov (modified
Federov).
n= n|SATURATED
specifies the PROC OPTEX n= option, which is the number of runs in the final design. The default is the PROC
OPTEX default and depends on the problem. Typically, you will not want to use the default. Instead, you should
pick a value using the information produced by the %MktRuns macro as guidance. The n=saturated option
creates a design with the minimum number of runs.
The Macros 317
options= options-list
specifies binary options. By default, none of these options are specified. Specify one or more of the following
values after options=.
check
checks the efficiency of a given design, specified in cand=.
nocode
suppresses printing the PROC PLAN, PROC FACTEX, and PROC OPTEX code.
allcode
shows all code, even code that will not be run.
otherfac= variable-list
specifies other terms to mention in the factors statement of PROC FACTEX. These terms are not guaranteed
to be estimable. By default, there are no other factors.
otherint= terms
specifies interaction terms that will only be specified with PROC OPTEX for multi-step macro invocations.
By default, no interactions are guaranteed to be estimable. Normally, interactions that are specified via the
interact= option affect both the PROC FACTEX and the PROC OPTEX model statements. In multi-step
problems, part of an interaction may not be in a particular PROC FACTEX step. In that case, the interaction
term must only appear in the PROC OPTEX step. For example, if x1 is created in one step and x4 is created in
another, and if the x1*x4 interaction must be estimable, specify otherint=x1*x4 on the final step, the one
that runs PROC OPTEX.
%mktdes(step=1, factors=x1-x3=2, n=30, run=factex)
out= SAS-data-set
specifies the output experimental design (from PROC OPTEX). By default, out=design.
procopts= options
specifies PROC OPTEX statement options. By default, no options are added to the PROC OPTEX statement.
run= procedure-list
specifies the list of procedures that the macro may run. Normally, the macro runs either PROC FACTEX or PROC
PLAN and then PROC OPTEX. By default, run=plan factex optex. You can skip steps by omitting
procedure names from this list. When both PLAN and FACTEX are in the list, the macro chooses between them
based on the size of the full-factorial design and the value of big=. When PLAN is not in the list, the macro
generates code for PROC FACTEX.
318 TS-677E Multinomial Logit, Discrete Choice Modeling
seed= n
specifies the random number seed. By default, seed=0, and clock time is used as the random number seed. By
specifying a random number seed, results should be reproducible within a SAS release for a particular operating
system. However, due to machine differences, some results may not be exactly reproducible on other machines,
although you would expect the efficiency differences to be slight.
size= n|MIN
specifies the candidate-set size. Start with the default size=min and see how big that design is. If you want,
subsequently you can specify larger values that are nlev=n multiples of the minimum size. This option is used
with PROC FACTEX:
size design=&size;
Say you specified nlev=2 or the macro defaulted to nlev=2. Increase the size= value by a factor of two
each time. For example, if size=min implies size=128, then 256, 512, 1024, and 2048 are reasonable sizes
to try. Integer expressions like size=128*4 are allowed.
step= n
specifies the step number. By default, there is only one step. However, sometimes, a better design can be found
using a multi-step approach. Do not specify the cand= option on any step of a multistep run. Consider the
problem of making a design with 3 two-level factors, 3 three-level factors, and 3 five-level factors. The simplest
approach is to do something like this create a design from two-level factors using pseudo-factors and coding
down.
%mktdes(factors=x1-x3=2 x4-x6=3 x7-x9=5, n=30)
However, for small problems like this, the following three-step approach will usually be better.
%mktdes(step=1, factors=x1-x3=2, n=30, run=factex)
%mktdes(step=2, factors=x4-x6=3, n=30, run=factex)
%mktdes(step=3, factors=x7-x9=5, n=30, run=factex optex)
Note however, that the following %MktEx macro call will usually be better still.
%mktex(2 2 2 3 3 3 5 5 5, n=30)
Returning to the %MktDes macro, the first step uses PROC FACTEX to create a fractional-factorial design for the
two-level factors. The second step uses PROC FACTEX to create a fractional-factorial design for the three-level
factors and cross it with the two-level factors. The third step uses PROC FACTEX to create a fractional-factorial
design for the five-level factors and cross it with the design for the two and three-level factors and then run PROC
OPTEX.
Each step globally stores two macro variables (&class1 and &inter1 for the first step, &class2 and &in-
ter2 for the second step, ...) that are used to construct the PROC OPTEX class and model statements. When
step > 1, variables from the previous steps are used in the class and model statements. In this example, the
following PROC OPTEX code is created by step 3:
proc optex data=Cand3;
class
x1-x3
x4-x6
x7-x9
/ param=orthref;
model
x1-x3
x4-x6
x7-x9
;
The Macros 319
where= where-clause
specifies a SAS where clause for the candidate design, which is used to restrict the candidates. By default, the
candidate design is not restricted.
%MktDups Macro
The %MktDups autocall macro detects duplicate choice sets and duplicate alternatives within generic choice
sets. For example, consider a simple experiment with these two choice sets. These choice sets are completely
different and are not duplicates.
a b c a b c
1 2 1 1 1 1
2 1 2 2 2 2
1 1 2 2 2 1
2 1 1 1 2 2
a b c a b c
1 2 1 2 1 2
2 1 2 1 1 2
1 1 2 2 1 1
2 1 1 1 2 1
They are the same for a generic study because all of the same alternatives are there, they are just in a different
order. However, for a branded study they are different. For a branded study, there would be a different brand
for each alternative, so the choice sets would be the same only if all the same alternatives appeared in the same
order. For both a branded and generic study, these choice sets are duplicates:
a b c a b c
1 2 1 1 2 1
2 1 2 2 1 2
1 1 2 1 1 2
2 1 1 2 1 1
a b c a b c
1 2 1 1 2 1
2 1 1 1 2 1
1 1 2 1 1 2
2 1 1 2 1 1
First, each of these choice sets has duplicate alternatives (2 1 1 in the first and 1 2 1 in the second). Second,
these two choice sets are flagged as duplicates, even though they are not exactly the same. They are flagged as
duplicates because every alternative in choice set one is also in choice set two, and every alternative in choice set
two is also in choice set one. In generic studies, two choice sets are considered duplicates unless one has one or
more alternatives that are not in the other choice set.
320 TS-677E Multinomial Logit, Discrete Choice Modeling
Here is an example. A design is created with the %ChoicEff macro choice-set-swapping algorithm for a
branded study, then the %MktDups macro is run to check for and eliminate duplicate choice sets.
%mktex(3 ** 9, n=27, seed=424)
data key;
input (Brand x1-x3) ($);
datalines;
Acme x1 x2 x3
Ajax x4 x5 x6
Widgit x7 x8 x9
;
Cumulative Cumulative
Set Frequency Percent Frequency Percent
--------------------------------------------------------
1 3 5.56 3 5.56
3 3 5.56 6 11.11
4 6 11.11 12 22.22
8 3 5.56 15 27.78
10 3 5.56 18 33.33
11 3 5.56 21 38.89
16 3 5.56 24 44.44
19 3 5.56 27 50.00
21 6 11.11 33 61.11
22 6 11.11 39 72.22
24 3 5.56 42 77.78
25 3 5.56 45 83.33
26 3 5.56 48 88.89
27 6 11.11 54 100.00
The output from the %MktDups macro contains the following tables:
Design: Branded
Factors: brand x1-x3
Brand
x1 x2 x3
Duplicate Sets: 4
The Macros 321
Duplicate
Choice Choice Sets
Set To Delete
1 5
2 12
4 18
11 14
The first line of the first table tells us that this is a branded design as opposed to generic. The second line tells
us the factors as specified on the factors= option. These are followed by the actual variable names for the
factors. The last line reports the number of duplicates. The second table tells us that choice set 1 is the same as
choice set 5. Similarly, 2 and 12 are the same as are 4 and 18, and also 11 and 14. The out= data set will contain
the design with the duplicate choice set eliminated.
Now consider an example with purely generic alternatives.
%mktex(2 ** 5, n=2**5, seed=93)
%mktlab(int=f1-f4)
Design: Generic
Factors: x1-x5
x1 x2 x3 x4 x5
Sets w Dup Alts: 2
Duplicate Sets: 2
Duplicate
Choice Choice Sets
Set To Delete
3 36
5 Alternatives
24 Alternatives
35 42
For each choice set listed in the choice set column, either the other choice sets it duplicates are listed or the word
’Alternatives’ is printed if the problem is with duplicate alternatives.
322 TS-677E Multinomial Logit, Discrete Choice Modeling
Set x1 x2 x3 x4 x5
3 2 1 1 1 2
1 1 1 1 1
1 2 2 2 2
2 2 2 2 1
5 1 1 2 1 2
1 1 2 1 2
2 2 1 2 1
2 2 1 2 1
24 1 2 2 1 2
1 2 2 1 2
2 1 1 2 1
2 1 1 2 1
35 2 1 2 1 1
2 2 1 2 2
1 1 2 1 2
1 2 1 2 1
36 2 1 1 1 2
1 1 1 1 1
1 2 2 2 2
2 2 2 2 1
42 1 1 2 1 2
2 1 2 1 1
1 2 1 2 1
2 2 1 2 2
You can see that the macro detects duplicates even though the alternatives do not always appear in the same order
in the different choice sets.
Now consider another example.
%mktex(2 ** 6, n=2**6)
data key;
input (x1-x2) ($) @@;
datalines;
x1 x2 x3 x4 x5 x6
;
Here is some of the output. The output lists, for each set of duplicates, the choice set that will be kept (in the first
column) and all the matching choice sets that will be deleted (in the second column).
Design: Generic
Factors: x1-x2
x1 x2
Sets w Dup Alts: 40
Duplicate Sets: 50
Duplicate
Choice Choice Sets
Set To Delete
1 Alternatives
2 Alternatives
5
6
17
18
21
.
.
.
Set _Alt_ x1 x2
7 1 1 1
2 1 2
3 2 1
8 1 1 1
2 1 2
3 2 2
12 1 1 1
2 2 1
3 2 2
28 1 1 2
2 2 1
3 2 2
This next example creates a conjoint design and tests it for duplicates.
%mktex( 3 ** 3 2 ** 2, n=19, seed=513)
%mktdups(linear, factors=x1-x5);
324 TS-677E Multinomial Logit, Discrete Choice Modeling
Design: Linear
Factors: x1-x5
x1 x2 x3 x4 x5
Duplicate Runs: 1
Duplicate
Runs
Run To Delete
9 10
options
For the first option, specify one or more of the following. You may specify noprint and one of the following:
generic, branded, or linear.
branded
specifies that since one of the factors is brand, the macro only needs to compare corresponding alternatives
in each choice set.
generic
specifies a generic design and is the default. This means that there are no brands, so options are interchange-
able, so the macro needs to compare each alternative with every other alternative in every choice set.
linear
specifies a linear not a choice design. Specify linear for a full-profile conjoint design, for an ANOVA design,
or for the linear version of a branded choice design.
noprint
specifies no printed output. This option will be used when you are only interested in the output data set or
macro variable.
Example:
%mktdups(branded noprint, nalts=3)
nalts= n
specifies the number of alternatives. This option must be specified with generic or branded designs. It is ignored
with linear designs. For generic or branded designs, the data= data set must contain nalts= observations for
the first choice set, nalts= observations for the second choice set, and so on.
The Macros 325
data= SAS-data-set
specifies the input choice design. By default, the macro uses the last data set created.
out= SAS-data-set
specifies an output data set that contains the design with duplicate choice sets excluded. By default, no data set
is created, and the macro just reports on duplicates.
outlist= SAS-data-set
specifies the output data set with the list of duplicates. By default, outlist=outdups.
vars= variable-list
factors= variable-list
specifies the factors in the design. By default, all numeric variables are used.
%MktEval Macro
The %MktEval autocall macro helps you evaluate an experimental design. This macro reports on balance and
orthogonality. Typically, you will call it immediately after running the %MktEx macro. The output from this
macro contains two default tables. The first table shows the canonical correlations between pairs of coded factors.
A canonical correlation is the maximum correlation between linear combinations of the coded factors. All zeros
off the diagonal show that the design is orthogonal for main effects. Off-diagonal canonical correlations greater
than 0.316 (r2 > 0:1) are listed in a separate table.
For nonorthogonal designs and designs with interactions, the canonical-correlation matrix is not a substitute for
looking at the variance matrix with the %MktEx macro. It just provides a quick and more-compact picture of the
correlations between the factors. The variance matrix is sensitive to the actual model specified and the coding.
The canonical-correlation matrix just tells you if there is some correlation between the main effects. When is
a canonical correlation too big? You will have to decide that for yourself. In part, the answer depends on the
factors and how the design will be used. A high correlation between the client’s and the main competitor’s price
factor is a serious problem meaning you will need to use a different design. In contrast, a moderate correlation in
a choice design between one brand’s minor attribute and another brand’s minor attribute may be perfectly fine.
The macro also prints one-way, two-way and n-way frequencies. Equal one-way frequencies occur when the
design is balanced. Equal two-way frequencies occur when the design is orthogonal. Equal n-way frequencies,
all equal to one, occur when there are no duplicate runs or choice sets.
blocks= variable
specifies a blocking variable. This option prints separate canonical correlations within each bloc. By default,
there is one block.
data= SAS-data-set
specifies the input SAS data set with the experimental design. By default, the macro uses the last data set created.
326 TS-677E Multinomial Logit, Discrete Choice Modeling
factors= variable-list
vars= variable-list
specifies a list of the factors in the experimental design. The default is all of the numeric variables in the data set.
freqs= frequency-list
specifies the frequencies to print. By default, freqs=1 2 n, and 1-way, 2-way, and n-way frequencies are
printed. Do not specify the exact number of ways instead of n. For ways other than n, the macro checks for
and prints zero cell frequencies. For n-ways, the macro does not output or print zero frequencies. Only the
full-factorial design will have nonzero cells, so specifying something like freqs=1 2 20 will make the macro
take a long time and create huge data sets, whereas freqs=1 2 n runs very reasonably.
format= format
specifies the format for printing canonical correlations. The default format is 4.2.
list= n
specifies the minimum canonical correlation to list. The default is 0.316, the square root of r2 = 0:1.
outcorr= SAS-data-set
specifies the output SAS data set for the canonical correlation matrix. The default data set name is CORR.
outcb= SAS-data-set
specifies the output SAS data set for the with-block canonical correlation matrices. The default data set name is
CB.
outlist= SAS-data-set
specifies the output data set for the list of largest canonical correlations. The default data set name is LIST.
outfreq= SAS-data-set
specifies the output data set for the frequencies. The default data set name is FREQ.
outfsum= SAS-data-set
specifies the output data set for the frequency summaries. The default data set name is FSUM.
print= short|corr|list|freqs|summ|all
controls the printing of the results. Specify one or more values from the following list.
corr prints the canonical correlations matrix.
block prints the canonical correlations within block.
list prints the list of canonical correlations greater than the list= value.
freqs prints the frequencies, specified by the freqs= option.
summ prints the frequency summaries.
all prints all of the above.
short is the default and is equivalent to: corr list summ block.
noprint specifies no printed output.
By default, the frequency list, which contains the factor names, levels, and frequencies is not printed, but the
more compact frequency summary list, which contains the factors and frequencies but not the levels is printed.
The Macros 327
%MktEx Macro
The %MktEx autocall macro is designed for marketing researchers and any one else who wants to make good,
efficient experimental designs. This macro is designed to be very simple to use, and to run in seconds for trivial
problems, minutes for small problems, and in less than an hour for larger and difficult problems. This macro is
a full-featured linear designer that can handle simple problems like main-effects designs and more complicated
problems including designs with interactions and restrictions on which levels can appear together. The macro
is particularly designed to easily create the kinds of linear designs that marketing researches need for conjoint
and choice experiments. For any linear design problem, you can simply run the macro once, specifying only the
number of runs and the numbers of levels of all the factors. You will no longer have to try different algorithms
and different approaches to see which one works best. The macro does all of that for you.
Here is an example of using the %MktEx macro to create a design with 5 two-level factors, 4 three-level factors,
3 five-level factors, 2 six-level factors, all in 60 runs (rows or conjoint profiles or choice sets).
%mktex( 2 ** 5 3 ** 4 5 5 5 6 6, n=60 )
Larger sizes are available as well. The %MktEx macro can construct these designs when n is a multiple of 4 and
one or more of the following hold:
n 256
n 1 is prime
n=2 1 is prime and mod(n=2; 4) = 2
n is a power of 2 (2, 4, 8, 16, ...) times the size of a smaller Hadamard matrix that is available.
For some of these sizes, the macro can create orthogonal designs with a small number (say m) four-level factors
in place of 3 m of the two-level factors (for example, 270 43 in 80 runs and 274 47 in 96 runs).
Here is a simple example of using the %MktEx macro to request the L36 design, which has 11 two-level factors
and 12 three-level factors.
%mktex( n=36 )
No iterations are needed, and the macro immediately creates the L36 , which is 100% efficient. This example
runs in a few seconds. The factors are always named x1, x2, ... and the levels are always consecutive integers
starting with 1. You can use the %MktLab macro to get different names and levels.
By default, the macro creates two output data sets with the design.
out=Design - the experimental design, sorted by the factor levels.
outr=Randomized - the randomized experimental design.
The designs are equivalent and have the same D-efficiency. The out=Design data set is sorted and hence is
usually easier to look at, however the outr=Randomized design is the better one to use. The randomized
design has the rows sorted into a random order, and all of the factor levels are randomly reassigned. For example
with two-level factors, approximately half of the original (1, 2) mappings will be reassigned (2, 1). Similarly,
with three level factors, the mapping (1, 2, 3) will be changed to one of the following: (1, 2, 3), (1, 3, 2), (2, 1,
3), (2, 3, 1), (3, 1, 2), or (3, 2, 1). The reassignment of levels is usually not critical for the iteratively derived
designs, but it can be very important for some of the tabled designs, which have all ones in the first row.
The Macros 333
Vacation Example
Current Best
Design Row,Col D-Efficiency D-Efficiency Notes
----------------------------------------------------------
1 Start 82.2172 82.2172 Can
1 End 82.2172
Vacation Example
Current Best
Design Row,Col D-Efficiency D-Efficiency Notes
----------------------------------------------------------
0 Initial 98.8933 98.8933 Ini
Vacation Example
Current Best
Design Row,Col D-Efficiency D-Efficiency Notes
----------------------------------------------------------
0 Initial 98.9438 98.9438 Ini
The first column, Design, is a design number. Each design corresponds to a complete iteration using a differ-
ent initialization. Initial designs are numbered zero. The second column is Row,Col, which shows the design
row and column that is changing in the coordinate-exchange algorithm. This column also contains Start for
displaying the initial efficiency, End for displaying the final efficiency, and Initial for displaying the effi-
ciency of a previously created (perhaps externally, perhaps in a previous step) initial design. The Current
D-Efficiency column contains the D-efficiency for the design including starting, intermediate and final val-
ues. The next column is Best D-efficiency. Values are put in this column for initial designs and when
a design is found that is as good as or better than the previous best design. The last column, Notes, contains
assorted algorithm and explanatory details. Values are added to the table at the beginning of an iteration, at the
end of an iteration, when a better design is found, and when a design first conforms to restrictions. Details of
the candidate search iterations are not shown. Only the D-efficiency for the best design found through candidate
search is shown.
Here are the notes.
Sometimes, more than one note appears. For example, the triples Ran,Mut,Ann and Pre,Mut,Ann fre-
quently appear together.
The iteration history consists of three tables.
Algorithm Search History - searches for a design and the best algorithm for this problem
Design Search History - uses the best algorithm to search further
Design Refinement History - tries to refine the best design
336 TS-677E Multinomial Logit, Discrete Choice Modeling
list
specifies a list of the numbers of levels of all the factors. For example, for 3 two-level factors specify ei-
ther 2 2 2 or 2 ** 3. Lists of numbers, like 2 2 3 3 4 4 or a levels**number of factors syntax like:
2**2 3**2 4**2 can be used, or both can be combined: 2 2 3**4 5 6. The specification 3**4 means
four three-level factors. Note that the factor list is a positional parameter. This means that if it is specified, it must
come first, and unlike all other parameters, it is not specified after a name and an equal sign. Usually, you have
to specify a list. However, in some cases, you can just specify n= and omit the list and a default list is implied
(see page 328). For example, n=18 implies a list of 2 3 ** 7. When the list is omitted, and if there are no
interactions, restrictions, or duplicate exclusions, then by default there are no OPTEX iterations (optiter=0).
n= n
specifies the number of runs in the design. You must specify n=. You can use the %MktRuns macro to get
suggestions for values of n=.
Example:
%mktruns( 4 2 ** 5 3 ** 5 )
In this case, this macro suggests several sizes including an orthogonal design with n=72 runs and some smaller
nonorthogonal designs including n=36, 24, 48, 60.
Basic Options
This next group of options contains some of the more commonly used options.
balance= n
specifies the maximum allowed level-frequency range. The balance= option allows you to tell the macro that
it should make an extra effort to ensure that the design is nearly balanced. By default, the macro does not try to
ensure balance beyond the fact that lack of balance decreases D-efficiency. Specify a positive integer, usually 1
or 2, that specifies the degree of imbalance that is acceptable. You may need to also specify options=accept
with balance=. The macro usually does a good job of producing nearly balanced design, but if balance is
critically important, and your designs are not balanced enough, you can sometimes achieve better balance by
specifying balance=1, but usually at the price of worse efficiency, sometimes much worse. The balance=
option specifies additional restrictions (see restrictions=) that help achieve better balance. By default, no
additional restrictions are added. The balance=n option specifies that for each factor, the difference between
the frequencies, for the most and least frequently occuring levels, should be no larger than n. You may specify
balance=0, however this usually is not a good idea. The macro needs the flexibility to have imbalance as it
refines the design. Another option is to instead use the %MktBal macro, which produces perfectly balanced
main effects plans. It is likely that the algorithms used by both the balance= option and the %MktBal macro
will be changed in the future to use some now unknown algorithms that are both faster and better.
examine= I | V
specifies the matrices that you want to examine. The option examine=I prints the information matrix, X0 X;
examine=V prints the variance matrix, (X0 X) 1 ; and examine=I V prints both. By default, these matrices
are not printed.
The Macros 337
interact= interaction-list
specifies interactions that must be estimable. By default, no interactions are guaranteed to be estimable. Exam-
ples:
interact=x1*x2
interact=x1*x2 x3*x4*x5
interact=x1|x2|x3|x4|x5@2
the interaction syntax is like PROC GLM’s and many of the other modeling procedures. It uses “*” for simple
interactions (x1*x2 is the interaction between x1 and x2), “|” for main effects and interactions (x1|x2|x3 is
the same as x1 x2 x1*x2 x3 x1*x3 x2*x3 x1*x2*x3) and “@” to eliminate higher-order interactions
(x1|x2|x3@2 eliminates x1*x2*x3 and is the same as x1 x2 x1*x2 x3 x1*x3 x2*x3). The specifi-
cation “@2” allows only main effects and two-way interactions. Only “@” values of 2 or 3 are allowed. For the
factor names, you must specify either the actual variable names (for example, x1 x2 ...) or you can just specify
the number without the “x” (for example, x1*x2 is equivalent to 1*2).
options= options-list
specifies binary options. By default, none of these options are specified. Specify one or more of the following
values after options=.
accept
allows the macro to output designs that violate restrictions imposed by restrictions=, balance=, or
partial=, or have duplicates with options=nodups. Normally the macro will not output such designs.
With options=accept, a design becomes eligible for output when the macro can no longer improve on
the restrictions or eliminate duplicates. Without options=accept, a design is only eligible when all
restrictions are met and all duplicates are eliminated.
check
checks the efficiency of a given design, specified in init=, and disables the out=, outr=, and outall=
options. If init= is not specified, options=check is ignored.
nodups
eliminates duplicate runs.
nofinal
skips calling PROC OPTEX to print the efficiency of the final experimental design.
nohistory
does not print the iteration history.
nosort
does not sort the design. One use of this option is with Hadamard matrices. Hadamard matrices are generated
with a banded structure that is lost when the design is sorted. If you want to see the original Hadamard
matrix, and not just a design constructed from the Hadamard matrix, specify options=nosort.
partial= n
specifies a partial profile design. The default is an ordinary linear design. Specify for example partial=4
if you only want 4 attributes to vary in each row of the design (except the first run, in which none vary). This
option works by adding restrictions to the design (see restrictions=). Specifying options=accept or
balance= with partial= is not a good idea.
338 TS-677E Multinomial Logit, Discrete Choice Modeling
restrictions= macro-name
specifies the name of a macro that places restrictions on the design. By default, there are no restrictions. If
you have restrictions on the design, what combinations can appear with what other combinations, then you must
create a macro that creates a variable called bad that contains a numerical summary of how bad the row of the
design is. When everything is fine, set bad to zero. Otherwise set bad to 1 or a larger value. Ideally, set bad
to the number of violations so that the macro knows if changes to factor levels are moving in the right direction.
The macro must consist of PROC IML statements and possibly some macro statements.
Be sure to check the log when you specify restrictions=. The macro cannot always ensure that your
statements are syntax-error free and stop if they are not.
Your macro can look at several things in quantifying badness, and must store its results in bad.
i - is a scalar that contains the number of the row currently being changed.
x - is a row vector of factor levels, always containing integer values beginning with 1 and continuing on to
the number of levels for each factor.
x1 is the same as x[1], x2 is the same as x[2], and so on.
j1 - is a scalar that contains the number of the column currently being changed.
j2 - is a scalar that contains the number of the other column currently being changed (along with j1) with
exchange=2 and larger exchange= values.
j3 - is a scalar that contains the number of the third column currently being changed (along with j1 and
j2) with exchange=3 and larger exchange= values.
xmat - is the entire x matrix. Note that the ith row of xmat may not be x since x may contain information
on the swaps being considered.
bad - results: 0 - fine, or the number of violations of restrictions.
Do not use these names (other than bad) for intermediate values!
Other than that, you can create intermediate variables without worrying about conflicts with the names in the
macro. The levels of the factors for one row of the experimental design are stored in a vector x, and the first level
is always 1, the second always 2, and so on. All restrictions must be defined in terms of x[j] (or alternatively,
x1, x2, ..., and perhaps the other matrices). For example, if there are five three-level factors and if it is bad
if the level for a factor equals the level for the following factor, create a macro restrict as follows and specify
restrictions=restrict.
%macro restrict;
bad = (x1 = x2) +
(x2 = x3) +
(x3 = x4) +
(x4 = x5);
%mend;
Note that you specify just the macro name and no percents on the restrictions= option. Also note that IML
does not have the full set of Boolean operators that the DATA step and other parts of SAS have. For example,
these are not available: OR AND NOT GT LT GE LE EQ NE. Here are the operators you can use along with
their meaning.
= equals not: EQ
^ = or : = not equals not: NE
< less than not: LT
<= less than or equal to not: LE
> greater than not: GT
>= greater than or equal to not: GE
& and not: AND
j or not: OR
^ or : not not: NOT
The Macros 339
seed= n
specifies the random number seed. By default, seed=0, and clock time is used as the random number seed. By
specifying a random number seed, results should be reproducible within a SAS release for a particular operating
system. However, due to machine differences, some results may not be exactly reproducible on other machines.
For most orthogonal and balanced designs, the results should be reproducible. When computerized searches
are done, it is likely that you will not get the same design across different operating systems and different SAS
releases, although you would expect the efficiency differences to be slight.
init= SAS-data-set
specifies the initial (input) experimental design. By default, there is no initial design. Use init= when you
want to evaluate the efficiency of a design (along with options=check) or when you want to try to improve
a design.
out= SAS-data-set
specifies the output experimental design. The default is out=Design. By default, this design is sorted unless
you specify options=nosort. This is the output data set to look at in evaluating the design. See the outr=
option (next) for a randomized version of the same design, which is generally more suitable for actual use.
Specify a null value for out= if you do not want this data set created.
outall= SAS-data-set
specifies the output data set containing all designs found. By default, this data set is not created.
outr= SAS-data-set
specifies the randomized output experimental design. The default is out=Randomized. Random levels are
assigned within factors, and the runs are sorted into a random order. When restrictions= or partial= is
specified, only the random sort is performed. Specify a null value for outr= if you do not want a randomized
design created.
Iteration Options
These next options control some of the details of the iterations. The macro can perform three sets of iterations.
The ’Algorithm Search’ set of iterations looks for efficient designs using three different approaches. It then
determines which approach appears to be working best and uses that approach exclusively in the second set of
’Design Search’ iterations. The third set or ’Design Refinement’ iterations tries to refine the best design found
so far by using level swaps combined with random mutations and simulated annealing.
340 TS-677E Multinomial Logit, Discrete Choice Modeling
The first set of iterations can have up to three parts. The first part uses either PROC PLAN or PROC FACTEX
followed by PROC OPTEX, called through the %MktDes macro, to create and search a candidate set for an
optimal initial design. The second part may use a tabled or fractional-factorial design as an initial design. The
next part consists of level exchanges starting with random initial designs.
In the first part, if the full-factorial design is manageable (arbitrarily defined as < 5186 runs), it is used as a
candidate set, otherwise a fractional-factorial candidate set is used. The macro tries optiter= iterations to
make an optimal design using the %MktDes macro and PROC OPTEX.
In the second part, the macro will try to generate and improve a standard tabled or fractional-factorial design.
Sometimes, this can lead immediately to an optimal design, for example with 211 312 and n = 36. In other cases,
when only part of the desired design matches some standard design, only part of the design is initialized with the
standard design and multiple iterations are run using the standard design as a partial initialization with the rest of
the design randomly initialized.
In the third part, the macro uses the coordinate-exchange algorithm with random initial designs.
maxdesigns= n
specifies that the macro should stop after maxdesign= designs have been created. This option may be useful
for big, slow problems with restrictions. You could specify for example maxdesigns=3 and maxtime=0 and
the macro would perform one candidate-set-based iteration, one tabled design initialization iteration, and one
random initialization iteration and then stop. By default, this option is ignored and stopping is based on the other
iteration options.
maxstages= n
specifies that the macro should stop after maxstages= algorithm stages have been completed. This option may
be useful for big, slow problems with restrictions. You could specify maxstages=1 and the macro will stop
after the algorithm search stage, or maxstages=2 and the macro will stop after the design search stage. The
default is maxstages=3, which means the macro will stop after the design refinement stage.
Miscellaneous Options
This section contains some miscellaneous options that some users may occasionally find useful.
exchange= n
specifies the number of factors to consider at a time when exchanging levels. The default is exchange=1,
which means that the macro works with one factor at a time. You can specify exchange=2 to do pair-wise
exchanges. Pair-wise exchanges are much slower, but may produce better designs.
fixed= variable
specifies an init= data set variable that indicates which runs are fixed (cannot be changed) and which ones may
be changed. By default, no runs are fixed.
1 - (or any nonmissing) means this run may never change.
0 - means this run is used in the initial design, but it may be swapped out.
. - means this run should be randomly initialized, and it may be swapped out.
This option can be used to add holdout runs to a conjoint design, but see holdouts= for an easier way.
holdouts= n
adds holdout observations to the init= data set. This option augments an initial design. Specifying
holdouts=n optimally adds n runs to the init= design. The option holdouts=n works by adding a
fixed= variable and extra runs to the init= data set. Do not specify both fixed= and holdouts=. The
number of rows in the init= design, plus the value specified in holdouts= must equal the n= value.
stopearly= n
specifies that the macro may stop early when it keeps finding the same maximum D-efficiency over and over
again in different designs. The default is stopearly=5. By default, during the design search iterations and
refinement iterations, the macro will stop early if 5 times, the macro finds a D-efficiency essentially equal to the
maximum but not greater than the maximum. This may mean that the macro has found the optimal design, or it
may mean that the macro keeps finding a very attractive local optimum. Either way, it is unlikely it will do any
better. When the macro stops for this reason, the macro will print
NOTE: Stopping since it appears that no improvement is possible.
Specify either 0 or a very large value to turn off the stop-early checking.
344 TS-677E Multinomial Logit, Discrete Choice Modeling
tabsize= n
specifies which tabled (or FACTEX or Hadamard) design is used for the partial initialization when an exact match
to a tabled design is not found. Specify the number of runs in the tabled design. By default, the macro chooses a
tabled design that bests matches the specified design.
target= n
specifies the target efficiency criterion. The default is target=100. The macro stops when it finds an efficiency
value greater than or equal to this number. If you know what the maximum efficiency criterion is, or you know
how big is big enough, you can sometimes make the macro run faster by allowing it to stop when it reaches the
specified efficiency.
Esoteric Options
This last set of options contains all of the other miscellaneous options. Most of the time, most users should not
specify options from this list.
annealfun= function
specifies the function that controls how the simulated annealing probability changes with each pass through
the design. The default is annealfun=anneal # 0.85. Note that the IML operator # performs ordinary
(scalar) multiplication. Most users will never need this option.
detfuzz= n
specifies the value used to determine if determinants are changing. The default is detfuzz=1e-8. If newde-
ter > olddeter * (1 + detfuzz) then the new determinant is larger. If newdeter > olddeter
* (1 - detfuzz) then the new determinant is the same. Otherwise the new determinant is smaller. Most
users will never need this option.
imlopts= options
specifies IML PROC statement options. For example, for very large problems, you can use this option to specify
the IML symsize= or worksize= options: imlopts=symsize=n worksize=m, substituting numeric
values for n and m. The defaults for these options are host dependent. Most users will never need this option.
ridge= n
specifies the value to add to the diagonal of X0 X to make it nonsingular. The default is ridge=1e-7. Usually,
for normal problems, you will not need to change this value. If you want the macro to create designs with more
parameters than runs, you must specify some other value, usually something like 0.01. By default, the macro
will quit when there are more parameters than runs. Specifying a ridge= value other than the default (even if
you just change the ’e’ in 1e-7 to ’E’) allows the macro to create a design with more parameters than runs. Most
users will never need this option.
%MktKey Macro
The %MktKey macro creates expanded lists of variable names.
%mktkey(x1-x15)
data key;
input (x1-x5) ($);
datalines;
x1 x2 x3 x4 x5
x6 x7 x8 x9 x10
x11 x12 x13 x14 x15
. . . . .
;
list
specifies a variable list. Note that the variable list is a positional parameter and it is not specified after a name
and an equal sign.
%MktLab Macro
The macro %MktLab is used to process an experimental design, usually created by the %MktEx macro, and
assign the final variable names and levels.
For example, say you used the %MktEx macro to create a design with 11 two-level factors (with default levels
of 1 and 2).
%mktex(n=12, options=nosort)
x1 x2 x3 x4 x5 x6 x7 x8 x9 x10 x11
1 2 1 2 2 2 1 1 1 2 1
1 1 2 1 2 2 2 1 1 1 2
2 1 1 2 1 2 2 2 1 1 1
1 2 1 1 2 1 2 2 2 1 1
1 1 2 1 1 2 1 2 2 2 1
1 1 1 2 1 1 2 1 2 2 2
2 1 1 1 2 1 1 2 1 2 2
2 2 1 1 1 2 1 1 2 1 2
2 2 2 1 1 1 2 1 1 2 1
1 2 2 2 1 1 1 2 1 1 2
2 1 2 2 2 1 1 1 2 1 1
2 2 2 2 2 2 2 2 2 2 2
The %MktLab macro can be used to assign levels of -1 and 1, add an intercept, and change the variable name
prefixes from x to Had. This creates a Hadamard matrix (although, of course, the Hadamard matrix can have
any set of variable names).
%mktlab(data=design, values=-1 1, int=Had0, prefix=Had);
Had0 Had1 Had2 Had3 Had4 Had5 Had6 Had7 Had8 Had9 Had10 Had11
1 -1 1 -1 1 1 1 -1 -1 -1 1 -1
1 -1 -1 1 -1 1 1 1 -1 -1 -1 1
1 1 -1 -1 1 -1 1 1 1 -1 -1 -1
1 -1 1 -1 -1 1 -1 1 1 1 -1 -1
1 -1 -1 1 -1 -1 1 -1 1 1 1 -1
1 -1 -1 -1 1 -1 -1 1 -1 1 1 1
1 1 -1 -1 -1 1 -1 -1 1 -1 1 1
1 1 1 -1 -1 -1 1 -1 -1 1 -1 1
1 1 1 1 -1 -1 -1 1 -1 -1 1 -1
1 -1 1 1 1 -1 -1 -1 1 -1 -1 1
1 1 -1 1 1 1 -1 -1 -1 1 -1 -1
1 1 1 1 1 1 1 1 1 1 1 1
Here is an alternative way of doing the same thing using a key= data set.
data key;
array Had[11];
input Had1 @@;
do i = 2 to 11; Had[i] = Had1; end;
drop i;
datalines;
-1 1
;
proc print data=key; run;
Obs Had1 Had2 Had3 Had4 Had5 Had6 Had7 Had8 Had9 Had10 Had11
1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
2 1 1 1 1 1 1 1 1 1 1 1
The Hadamard matrix from this step (not shown) is exactly the same as above.
The key= data set contains all of the variables that you want in the design and all of their levels. This information
will be applied to the design, by default the one stored in a data set called RANDOMIZED, which is the default
outr= data set name from the %MktEx macro. The results are stored in a new data set, FINAL, with the desired
factor names and levels.
Consider the consumer food product example from Kuhfeld, Tobias, and Garratt (1994). Here is one possible
design.
data randomized;
input x1-x8 @@;
datalines;
4 2 1 1 1 2 2 2 2 1 1 2 1 3 1 3 3 4 2 2 1 3 2 3 4 3 2 1 3 2 2 3 4 1 2 1
1 1 1 1 2 4 1 2 1 2 1 1 1 2 1 2 3 3 2 1 2 2 2 2 2 2 2 3 1 4 2 1 1 2 2 2
3 2 2 1 3 1 2 1 1 4 1 2 2 3 1 2 1 3 2 2 1 3 1 1 3 2 1 2 2 1 2 3 3 4 1 1
3 1 1 3 4 1 2 2 2 1 2 1 2 3 2 1 2 3 2 2 2 1 2 1 3 3 1 3 4 2 2 2 1 3 1 2
2 4 2 2 3 1 1 2 3 1 2 2 3 2 1 2 3 3 1 1 2 3 1 1 4 4 2 1 2 2 1 3 1 1 1 1
3 2 1 2 4 3 1 2 3 3 2 2 1 2 2 1 2 1 1 3 1 3 1 1 1 1 2 3
;
The Macros 347
Designs created by the %MktEx macro always have factor names x1, x2, ..., and so on, and the levels are
consecutive integers beginning with 1 (1, 2 for two-level factors; 1, 2, 3 for three-level factors; and so on). The
%MktLab macro provides you with a convenient way to change the names and levels to more meaningful values.
The data set KEY contains the variable names and levels that you ultimately want.
data key;
missing N;
input Client ClientLineExtension ClientMicro $ ShelfTalker $
Regional Private PrivateMicro $ NationalLabel;
format _numeric_ dollar5.2;
datalines;
1.29 1.39 micro Yes 1.99 1.49 micro 1.99
1.69 1.89 stove No 2.49 2.29 stove 2.39
2.09 2.39 . . N N . N
N N . . . . . .
;
%mktlab(key=key);
Client
Line Client Private National
Obs Client Extension Micro Regional Private Micro Label
Client
Line Client Private National
Obs Client Extension Micro Regional Private Micro Label
This macro creates the out= data set by repeatedly reading and rereading the key= data set, one datum at a
time, using the information in the data= data set to determine which levels to read from the key= data set. In
this example, for the first observation, x1=4 so the fourth value of the first key= variable is read, then x2=2 so
the second value of the second key= variable is read, then x3=1 so the first value of the third key= variable is
read, ..., then x8=2 so the second value of the eighth key= variable is read, then the first observation is output.
This continues for all observations. This is why the data= data set must have integer values beginning with 1.
This example creates the L36 , renames the two-level factors two1-two11 and assigns them values -1, 1, and
renames the three-level factors thr1-thr12 and assigns them values -1, 0, 1.
%mktex(n=36)
data key;
array x[23] two1-two11 thr1-thr12;
input two1 thr1;
do i = 2 to 11; x[i] = two1; end;
do i = 13 to 23; x[i] = thr1; end;
drop i;
datalines;
-1 -1
1 0
. 1
;
%mktlab(key=key);
two1 two2 two3 two4 two5 two6 two7 two8 two9 two10 two11
-1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
1 1 1 1 1 1 1 1 1 1 1
. . . . . . . . . . .
thr1 thr2 thr3 thr4 thr5 thr6 thr7 thr8 thr9 thr10 thr11 thr12
-1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
0 0 0 0 0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 1 1 1 1 1
two1 two2 two3 two4 two5 two6 two7 two8 two9 two10 two11
1 -1 1 1 1 1 -1 1 1 1 -1
-1 1 1 -1 -1 1 1 1 1 1 1
-1 -1 -1 -1 1 1 1 1 -1 -1 -1
1 1 1 -1 1 -1 -1 1 -1 -1 1
1 -1 1 1 -1 1 1 -1 -1 -1 1
The Macros 349
thr1 thr2 thr3 thr4 thr5 thr6 thr7 thr8 thr9 thr10 thr11 thr12
1 0 1 0 0 1 0 0 1 -1 1 1
1 1 1 1 -1 -1 0 -1 -1 -1 0 -1
-1 0 1 -1 0 0 -1 -1 0 -1 0 0
0 0 0 1 -1 -1 -1 1 1 -1 1 0
0 -1 1 -1 1 -1 1 -1 1 -1 -1 1
This next step creates a design and blocks it. This example shows that it is OK if not all of the variables in the
input design are used. The variables Block, Run, and x4 are just copied from the input to the output.
%mktex(n=18, seed=396)
data key;
input Brand $ Price Size;
format price dollar5.2;
datalines;
Acme 1.49 6
Apex 1.79 8
. 1.99 12
;
%mktlab(data=blocked, key=key)
1 1 Acme $1.79 6 1
2 Acme $1.79 8 3
3 Acme $1.99 8 2
4 Acme $1.99 12 1
5 Apex $1.49 8 3
6 Apex $1.49 12 2
7 Apex $1.79 6 3
8 Apex $1.79 12 1
9 Apex $1.99 6 2
2 1 Acme $1.49 6 2
2 Acme $1.49 8 1
3 Acme $1.49 12 3
4 Acme $1.79 12 2
5 Acme $1.99 6 3
6 Apex $1.49 6 1
7 Apex $1.79 8 2
8 Apex $1.99 8 1
9 Apex $1.99 12 3
350 TS-677E Multinomial Logit, Discrete Choice Modeling
This next example illustrates using the labels= option. This option is more typically used with values=
input, rather than when you construct the key= data set yourself, but it can be used either way. This example is
from the Vacation Example.
%mktex(3 ** 15, n=36, seed=17, maxtime=0)
%macro lab;
label X1 = ’Hawaii, Accommodations’
X2 = ’Alaska, Accommodations’
X3 = ’Mexico, Accommodations’
X4 = ’California, Accommodations’
X5 = ’Maine, Accommodations’
X6 = ’Hawaii, Scenery’
X7 = ’Alaska, Scenery’
X8 = ’Mexico, Scenery’
X9 = ’California, Scenery’
X10 = ’Maine, Scenery’
X11 = ’Hawaii, Price’
X12 = ’Alaska, Price’
X13 = ’Mexico, Price’
X14 = ’California, Price’
X15 = ’Maine, Price’;
format x11-x15 dollar5.;
%mend;
data key;
length x1-x5 $ 16 x6-x10 $ 8 x11-x15 8;
input x1 & $ x6 $ x11;
x2 = x1; x3 = x1; x4 = x1; x5 = x1;
x7 = x6; x8 = x6; x9 = x6; x10 = x6;
x12 = x11; x13 = x11; x14 = x11; x15 = x11;
datalines;
Cabin Mountains 999
Bed & Breakfast Lake 1249
Hotel Beach 1499
;
data= SAS-data-set
specifies the input data set with the experimental design, usually created by the %MktEx macro. The default is
data=Randomized. The factor levels in the data= data set must be consecutive integers beginning with 1.
dolist= do-list
specifies the new values, using a do-list syntax (n TO m <BY p>), for example: 1 to 10 or 0 to 9. With
asymmetric designs (not all factors have the same levels), specify the levels for the largest number of levels. For
example, with two-level and three-level factors and dolist=0 to 2, the two-level factors will be assigned
levels 0 and 1, and the three-level factors will be assigned levels 0, 1, and 2. Do not specify both values= and
dolist=. By default, when key=, values=, and dolist= are all not specified, the default value list comes
from dolist=1 to 100.
int= variable-list
specifies the name of an intercept variable (column of ones), if you want an intercept added to the out= data set.
You can also specify a variable list instead of a variable name if you would like to make a list of variables with
values all one. This can be useful for example, for generic choice models, for creating flag variables when the
design is going to be used as a candidate set for the %ChoicEff macro.
key= SAS-data-set
specifies the input data set with the key to recoding the design. When values= or dolist= is specified, this
data set is made for you. By default, when key=, values=, and dolist= are all not specified, the default
value list comes from dolist=1 to 100.
352 TS-677E Multinomial Logit, Discrete Choice Modeling
labels= macro-name
specifies the name of a macro that provides labels, formats, or other additional information to the key= data
set. For a simple format specification, it is easier to use statements=. For more involved specifications, use
labels=. Note that you specify just the macro name, no percents on the labels= option. Example:
%mktex(3 ** 4, n=18, seed=205)
%macro labs;
label x1 = ’Sploosh’ x2 = ’Plumbob’
x3 = ’Platter’ x4 = ’Moosey’;
format x1-x4 dollar5.2;
%mend;
%mktlab(values=1.49 1.99 2.49, labels=labs)
proc print label; run;
proc print label; run;
out= SAS-data-set
specifies the output data set with the final, recoded design. The default is out=final.
prefix= variable-prefix
specifies a prefix for naming variables when values= is specified. For example prefix=Var creates variables
Var1, Var2, and so on. By default, the variables are x1, x2, .... This option is ignored when vars= is specified.
statements= SAS-code
is an alternative to labels= that you can use to add extra statements to the key= data set. For a simple format
specification, it is easier to use statements=. For more involved specifications, use labels=. Example:
%mktex(3 ** 4, n=18, seed=205)
values= value-list
specifies the new values for all of the variables. If all variables will have the same value, it is easier to specify
values= or dolist= than key=. When you specify values=, the key= data set is created for you. Specify
a list of levels separated by blanks. If your levels contain blanks, separate them with two blanks. With asymmetric
designs (not all factors have the same levels) specify the levels for the largest number of levels. For example,
with two-level and three-level factors and values=a b c, the two-level factors will be assigned levels ’a’
and ’b’, and the three-level factors will be assigned levels ’a’, ’b’, and ’c’. Do not specify both values=
and dolist=. By default, when key=, values=, and dolist= are all not specified, the default value list
comes from dolist=1 to 100.
vars= variable-list
specifies a list of variable names when values= or dolist= is specified. If vars= is not specified with
values=, then prefix= is used.
%MktMerge Macro
The %MktMerge autocall macro merges a data set containing an experimental design for a choice model with
the data for the choice model. Here is a typical usage of the macro.
%mktmerge(design=rolled, data=results, out=res2,
nsets=18, nalts=5, setvars=choose1-choose18)
The design= data set comes from the %MktRoll macro. The data= data set contains the data, and the
setvars= variables in the data= data set contain the numbers of the chosen alternatives for each of the 18
choice sets. The nsets= option specifies the number of choice sets, and the nalts= option specifies the
number of alternatives. The out= option names the output SAS data set that contains the experimental design
and a variable c that contains 1 for the chosen alternatives (first choice) and 2 for unchosen alternatives (second
or subsequent choice).
When the data= data set contains a blocking variable, name it on the blocks= option. When there is blocking,
it is assumed that the design= data set contains blocks of nalts nsets observations. The blocks= variable
must contain values 1, 2, ..., n for n blocks. Here is an example of using the %MktMerge macro with blocking.
%mktmerge(design=rolled, data=results, out=res2, blocks=form,
nsets=18, nalts=5, setvars=choose1-choose18)
blocks= 1|variable
specifies either a 1 (the default) if there is no blocking or the name of a variable in the data= data set that
contains the block number. When there is blocking, it is assumed that the design= data set contains blocks
of nalts nsets observations, one set per block. The blocks= variable must contain values 1, 2, ..., n for n
blocks.
data= SAS-data-set
specifies an input SAS data set with data for the choice model. By default, the data= data set is the last data set
created.
354 TS-677E Multinomial Logit, Discrete Choice Modeling
design= SAS-data-set
specifies an input SAS data set with the choice design. This data set could have been created for example with
the %MktRoll macro. This option must be specified.
nalts= n
specifies the number of alternatives. This option must be specified.
nsets= n
specifies the number of choice sets. This option must be specified.
out= SAS-data-set
specifies the output SAS data set. If out= is not specified, the DATAn convention is used. This data set contains
the experimental design and a variable c that contains 1 for the chosen alternatives (first choice) and 2 for
unchosen alternatives (second or subsequent choice).
setvars= variable-list
specifies a list of variables, one per choice set, in the data= data set that contain the numbers of the chosen
alternatives. It is assumed that the values of these variables range from 1 to nalts. This option must be specified.
stmts= SAS-statements
specifies additional statements like format and label statements. Example:
%mktmerge(design=rolled, data=results, out=res2, blocks=form,
nsets=&n, nalts=&m, setvars=choose1-choose&n,
stmts=%str(price = input(put(price, price.), 5.);
format scene scene. lodge lodge.;))
%MktOrth Macro
The %MktOrth macro lists some of the 100% orthogonal main-effects plans that the %MktEx macro can gen-
erate, up through 100 runs. Here is a typical usage.
%mktorth;
1 4 2 ** 3 Hadamard
2 6 2 ** 1 3 ** 1 Full-factorial
3 8 2 ** 7 Hadamard
4 9 3 ** 4 Fractional-factorial
5 10 2 ** 1 5 ** 1 Full-factorial
6 12 2 ** 11 Hadamard
7 12 2 ** 4 3 ** 1 Hedayat, Sloane, and Stufken, 1999
8 12 2 ** 2 6 ** 1 Hedayat, Sloane, and Stufken, 1999
9 12 3 ** 1 4 ** 1 Full-factorial
343 98 2 ** 1 49 ** 1 Full-factorial
344 99 3 ** 2 11 ** 1 Full-factorial
345 100 2 ** 99 Hadamard
If you just want to display a list of designs, possibly selecting on n, the number of runs, you can use the MKT-
DESCAT data set. However, if you would like to do more advanced processing, based on the numbers of levels of
some of the factors, you can use the outlev=mktdeslev data set to select potential designs. You can look at
the level information in MKTDESLEV and see the number of two-level factors in x2, the number of three-level
factors in x3, ..., and the number of fifty-level factors is in x50. The number of one level factors, x1, is always
zero, but x1 is available so you can make arrays (for example, array x[50]) and have x[2] refer to x2, the
number of two-level factors.
Say you are interested in the design 25 35 41 . Here are the ways in which it is available.
proc print data=mktdeslev(where=(x2 ge 5 and x3 ge 5 and x4 ge 1));
var n design reference;
run;
Here is how you can see all the designs in a certain range of sizes.
proc print; where 12 le n le 20; run;
6 12 2 ** 11 Hadamard
7 12 2 ** 4 3 ** 1 Hedayat, Sloane, and Stufken, 1999
8 12 2 ** 2 6 ** 1 Hedayat, Sloane, and Stufken, 1999
9 12 3 ** 1 4 ** 1 Full-factorial
10 14 2 ** 1 7 ** 1 Full-factorial
11 15 3 ** 1 5 ** 1 Full-factorial
12 16 2 ** 15 Hadamard
13 16 2 ** 12 4 ** 1 Fractional-factorial
14 16 2 ** 9 4 ** 2 Fractional-factorial
15 16 2 ** 6 4 ** 3 Fractional-factorial
16 16 2 ** 3 4 ** 4 Fractional-factorial
17 16 4 ** 5 Fractional-factorial
18 18 2 ** 1 3 ** 7 Taguchi, 1987
19 18 3 ** 6 6 ** 1 Taguchi, 1987
20 20 2 ** 19 Hadamard
356 TS-677E Multinomial Logit, Discrete Choice Modeling
outall= SAS-data-set
specifies the output data set with all designs. This is like the outlev= data set, except larger. The outall=
data set includes all of the %MktEx design catalogue, including all of the smaller designs that can be trivially
made from larger designs by dropping factors. For example, when the outlev= data set has x2=2 x3=2, then
the outall= data set has that design and also x1=2 x3=1, x1=1 x3=2, and x1=1 x2=1. This data set is not
created by default.
outcat= SAS-data-set
specifies the output data set with the catalogue of designs that the %MktEx macro can create. The default is
outcat=MktDesCat.
outlev= SAS-data-set
specifies the output data set with the list of designs and 50 more variables: x2 - number of two-level factors, x3
- number of three-level factors and so on. The default is outlev=MktDesLev.
%MktRoll Macro
The %MktRoll autocall macro is used for manipulating the experimental design for choice experiments. It
takes as input a SAS data set containing an experimental design with one row per choice set, for example a
design created by the %MktEx macro. This data set is specified in the design= option. This data set has one
variable for each attribute of each alternative in the choice experiment.
The output from this macro is an out= SAS data set containing the experimental design with one row per
alternative per choice set. There is one column for each different attribute. For example, in a simple branded
study, design= could contain the variables x1-x5 which contain the prices of each of five alternative brands.
The output data set would have one factor, Price, that contains the price of each of the five alternatives. In
addition, it would have the number (or optionally the name) of each alternative.
The rules for determining the mapping between factors in the design= data set and the out= data set are
contained in the key= data set. For example, assume that the design= data set contains the variables x1-x5
which contain the prices of each of five alternative brands: Brand A, B, C, D, and E. Here is how you would
create the key= data set. The choice design has two factors, Brand and Price. Brand A price is made from
x1, Brand B price is made from x2, ..., and Brand E price is made from x5.
A convenient way to get all the names in a variable list like x1-x5 is with the %MktKey macro.
%mktkey(x1-x5)
Here is how you can create the design with one row per alternative per choice set:
%mktroll(design=randomized, key=key, out=[Link], alt=brand)
Obs x1 x2 x3 x4 x5
9 3 1 1 2 1
41 9 A 3
42 9 B 1
43 9 C 1
44 9 D 2
45 9 E 1
The price for Brand A is made from x1=3, ..., and the price for Brand E is made from x5=1.
Now assume that there are three alternatives, each a different brand, and each composed of four factors: Price,
Size, Color, and Shape. In addition, there is a constant alternative. First, the %MktEx macro is used to
create a design with 12 factors, one for each attribute of each alternative.
%mktex(2 ** 12, n=16)
Next, the key= data set is created. It shows that there are three brands, A, B, and C, and also None.
data key;
input (Brand Price Size Color Shape) ($);
datalines;
A x1 x2 x3 x4
B x5 x6 x7 x8
C x9 x10 x11 x12
None . . . .
;
Brand A is created from Brand = ’A’, Price = x1, Size = x2, Color = x3, Shape = x4.
Brand B is created from Brand = ’B’, Price = x5, Size = x6, Color = x7, Shape = x8.
Brand C is created from Brand = ’C’, Price = x9, Size = x10, Color = x11, Shape = x12.
358 TS-677E Multinomial Logit, Discrete Choice Modeling
The constant alternative is created from Brand = ’None’ and none of the attributes. The “.” notation is used
to indicate missing values in input data sets. The actual values in the KEY data set will be blank (character
missing).
Here is how you create the design with one row per alternative per choice set:
%mktroll(key=key, design=randomized, out=[Link], alt=brand)
8 2 1 2 1 1 2 2 2 1 2 1 1
29 8 A 2 1 2 1
30 8 B 1 2 2 2
31 8 C 1 2 1 1
32 8 None . . . .
Now assume like before that there are three branded alternatives, each composed of four factors: Price, Size,
Color, and Shape. In addition, there is a constant alternative. Also, there is an alternative-specific factor,
Pattern, that only applies to Brand A and Brand C. First, the %MktEx macro is used to create a design with
14 factors, one for each attribute of each alternative.
%mktex(2 ** 14, n=16)
Next, the key= data set is created. It shows that there are three brands, A, B, and C, plus None.
data key;
input (Brand Price Size Color Shape Pattern) ($);
datalines;
A x1 x2 x3 x4 x13
B x5 x6 x7 x8 .
C x9 x10 x11 x12 x14
None . . . . .
;
Brand A is created from Brand = ’A’, Price = x1, Size = x2, Color = x3, Shape = x4, Pattern =
x13.
Brand B is created from Brand = ’B’, Price = x5, Size = x6, Color = x7, Shape = x8.
Brand C is created from Brand = ’C’, Price = x9, Size = x10, Color = x11, Shape = x12, Pattern =
x14.
The constant alternative is Brand = ’None’ and none of the attributes.
Here is how you can create the design with one row per alternative per choice set:
%mktroll(key=key, design=randomized, out=[Link], alt=brand)
The Macros 359
8 1 2 2 1 1 2 1 2 2 1 2 1 2 2
29 8 A 1 2 2 1 2
30 8 B 1 2 1 2 .
31 8 C 2 1 2 1 2
32 8 None . . . . .
Now assume we are going to fit a model with price cross effects so we need x1, x5, and x9 (the three price
effects) available in the out= data set.
%mktroll(key=key, design=randomized, out=[Link], alt=brand,
keep=x1 x5 x9)
Now the data set also contains the three original price variables.
29 8 A 1 2 2 1 2 1 1 2
30 8 B 1 2 1 2 . 1 1 2
31 8 C 2 1 2 1 2 1 1 2
32 8 None . . . . . 1 1 2
Every value in the key= data set must appear as a variable in the design= data set. The macro prints a warning
if it encounters a variable name in the design= data set that does not appear as a value in the key= data set.
alt= variable
specifies the variable in the key= data set that contains the name of each alternative. Often this will be something
like alt=Brand. When alt= is not specified, the macro creates a variable - Alt- that contains the alternative
number.
design= SAS-data-set
specifies an input SAS data set with one row per choice set. The design= option must be specified.
keep= variable-list
specifies factors from the design= data set that should also be kept in the out= data set. This option is useful
to keep terms that will be used to create cross effects.
key= SAS-data-set
specifies an input SAS data set containing the rules for mapping the design= data set to the out= data set. The
key= option must be specified.
360 TS-677E Multinomial Logit, Discrete Choice Modeling
options= options-list
specifies binary options. By default, none of these options are specified. Specify one or more of the following
values after options=.
notes
do not specify options nonotes during most of the macro.
nowarn
do not print a warning when the design= data set contains variables not mentioned in the KEY= data set.
Sometimes this is perfectly fine.
out= SAS-data-set
specifies the output SAS data set. If out= is not specified, the DATAn convention is used.
set= variable
specifies the variable in the out= data set that will contain the choice set number. By default, this variable is
named Set.
%MktRuns Macro
The %MktRuns autocall macro suggests reasonable sizes for main-effects experimental designs. It tries to find
sizes in which perfect balance and orthogonality can occur, or at least sizes in which violations of orthogonality
and balance are minimized. Typically, the macro takes one argument, a list of the number of levels of each factor.
For example, with 3 two-level and 4 three-level factors, specify either of the following.
%mktruns( 2 2 2 3 3 3 3 )
%mktruns( 2 ** 3 3 ** 4 )
The output from the macro in this example is:
Design Summary
Number of
Levels Frequency
2 3
3 4
The Macros 361
Saturated = 12
Full Factorial = 648
36 * 0
72 * 0
18 3 4
54 3 4
12 6 9
24 6 9
48 6 9
60 6 9
30 9 4 9
42 9 4 9
n Design Reference
36 2 ** 13 3 ** 4 Suen, 1989
36 2 ** 11 3 ** 12 Taguchi, 1987
36 2 ** 4 3 ** 13 Taguchi, 1987
72 2 ** 49 3 ** 4 Hedayat, Sloane, and Stufken, 1999
72 2 ** 47 3 ** 12 Wang, 1996
72 2 ** 40 3 ** 13 Wang and Wu, 1991
72 2 ** 38 3 ** 12 6 ** 1 Hedayat, Sloane, and Stufken, 1999
72 2 ** 37 3 ** 8 6 ** 2 Hedayat, Sloane, and Stufken, 1999
72 2 ** 36 3 ** 13 4 ** 1 Hedayat, Sloane, and Stufken, 1999
72 2 ** 36 3 ** 12 12 ** 1 Hedayat, Sloane, and Stufken, 1999
72 2 ** 36 3 ** 7 6 ** 3 Hedayat, Sloane, and Stufken, 1999
72 2 ** 23 3 ** 24 Dey, 1985
72 2 ** 20 3 ** 24 4 ** 1 Wang, 1996
72 2 ** 16 3 ** 25 Wang, 1996
72 2 ** 14 3 ** 24 6 ** 1 Wang, 1996
72 2 ** 13 3 ** 25 4 ** 1 Wang, 1996
72 2 ** 12 3 ** 24 12 ** 1 Hedayat, Sloane, and Stufken, 1999
72 2 ** 11 3 ** 24 4 ** 1 6 ** 1 Wang, 1996
The macro reports that the saturated design has 12 runs and that 36 is an optimal design size. The macro picks
36, because it is the smallest integer >= 12 that can be divided by 2, 3, 2 2, 2 3, and 3 3. The macro also
reports 18 as a reasonable size. There are three violations with 18 because 18 cannot be divided by each of the
three pairs of 2 2, so perfect orthogonality in the two-level factors will not be possible with 18 runs. Larger
sizes are reported as well. The macro prints orthogonal designs that are available from the %MktEx macro that
match your specification.
To see every size the macro considered, simply run PROC PRINT after the macro finishes. The output from this
step is not shown.
proc print label data=nums split=’-’;
id n;
run;
For 2 two-level factors, 2 three-level factors, 2 four-level factors, and 2 five-level factors specify:
%mktruns( 2 2 3 3 4 4 5 5 )
362 TS-677E Multinomial Logit, Discrete Choice Modeling
Design Summary
Number of
Levels Frequency
2 2
3 2
4 2
5 2
Saturated = 21
Full Factorial = 14,400
120 3 9 16 25
180 6 8 16 25
60 7 8 9 16 25
144 15 5 10 15 20 25
48 16 5 9 10 15 20 25
72 16 5 10 15 16 20 25
80 16 3 6 9 12 15 25
96 16 5 9 10 15 20 25
160 16 3 6 9 12 15 25
192 16 5 9 10 15 20 25
Among the smaller design sizes, 60 or 48 look like good possibilities. The macro has an optional keyword
parameter: max=. It specifies the maximum number of sizes to try. The smallest design that is considered is
the saturated design. Usually you will not need to specify the max= option. For example, this specification tries
5000 sizes (21 to 5020) and reports that a perfect design can be found with 3600 runs.
%mktruns(2 2 3 3 4 4 5 5, max=5000)
Design Summary
Number of
Levels Frequency
2 2
3 2
4 2
5 2
Saturated = 21
Full Factorial = 14,400
3600 0
720 1 25
1200 1 9
1440 1 25
1800 1 16
The Macros 363
2160 1 25
2400 1 9
2880 1 25
4320 1 25
4800 1 9
Now consider again the problem with 3 two-level and 4 three-level factors, but this time we want to be estimable
the interaction of two of the two-level factors. Now, instead of specifying %mktruns( 2 2 2 3 3 3 3 ),
we replace two of the 2’s with a 4.
%mktruns( 2 4 3 3 3 3 )
Design Summary
Number of
Levels Frequency
2 1
3 4
4 1
Saturated = 13
Full Factorial = 648
72 * 0
144 0
36 1 8
108 1 8
18 6 4 8 12
24 6 9
48 6 9
54 6 4 8 12
90 6 4 8 12
96 6 9
n Design Reference
Now we need 72 runs for perfect balance and orthogonality and there are six violations in 18 runs (4, 4 2, 4 3,
4 3, 4 3, and 4 3).
If you ever get errors running this macro, like invalid page errors, see “Macro Errors” on page 288.
364 TS-677E Multinomial Logit, Discrete Choice Modeling
list
specifies a list of the numbers of levels of all the factors. For example, for 3 two-level factors specify ei-
ther 2 2 2 or 2 ** 3. Lists of numbers, like 2 2 3 3 4 4 or a levels**number of factors syntax like:
2**2 3**2 4**2 can be used, or both can be combined: 2 2 3**4 5 6. The specification 3**4 means
four three-level factors. You must specify a list. Note that the factor list is a positional parameter. This means it
must come first, and unlike all other parameters, it is not specified after a name and an equal sign.
n= n
specifies the design size to evaluate. By default, this option is not specified, and the max= option specification
provides a range of design sizes to evaluate.
options= options-list
specifies binary options. By default, none of these options are specified. Specify one the following values after
options=.
justparse
is used by other Mkt macros to have this macro just parse the list argument and return it as a simple list of
integers.
out= SAS-data-set
specifies the name of a SAS data set with the suggested sizes. The default is out=nums.
%PhChoice Macro
The %PhChoice autocall macro is used to customize the discrete choice output from PROC PHREG. Typically,
you run the following macro once to customize the PROC PHREG output.
%phchoice(on)
The macro uses PROC TEMPLATE and ODS (Output Delivery System) to customize the output from PROC
PHREG. Running this code edits the templates and stores copies in SASUSER. These changes will remain in
effect until you delete them. Note that these changes assume that each effect in the choice model has a variable
label associated with it so there is no need to print variable names. If you are coding with PROC TRANSREG,
this will usually be the case. To return to the default output from PROC PHREG, run the following macro.
%phchoice(off)
If you ever have errors running this macro, like invalid page errors, see “Macro Errors” on page 288. The rest
of this section discusses the details of what the %PhChoice macro does and why. Unless you are interested in
further customization of the output, you should skip to “%PhChoice Macro Options” on page 368.
The Macros 365
We are most interested in the ’Analysis of Maximum Likelihood Estimates’ table, which contains the parameter
estimates. We can first use PROC TEMPLATE to identify the template for the parameter estimates table and then
edit the template. First, let’s have PROC TEMPLATE display the templates for PROC PHREG. The source
[Link] statement specifies that we want to see PROC TEMPLATE source code for the STAT product and
the PHREG procedure.
proc template;
source [Link];
run;
If we search the results for the ’Analysis of Maximum Likelihood Estimates’ table we find the following code,
which defines the [Link] table.
define table [Link];
notes "Parameter Estimates Table";
dynamic Confidence NRows;
column Variable DF Estimate StdErr StdErrRatio ChiSq ProbChiSq HazardRatio
HRLowerCL HRUpperCL Label;
header h1 h2;
define h1;
text "Analysis of Maximum Likelihood Estimates";
space = 1;
spill_margin;
end;
define h2;
text Confidence BEST8. %nrstr("%% Hazard Ratio Confidence Limits");
space = 0;
end = HRUpperCL;
start = HRLowerCL;
spill_margin = OFF;
end;
define Variable;
header = "Variable";
style = RowHeader;
id;
end;
define DF;
parent = [Link];
end;
define Estimate;
header = ";Parameter;Estimate;";
format = D10.;
parent = [Link];
end;
define StdErr;
header = ";Standard;Error;";
format = D10.;
parent = [Link];
end;
define StdErrRatio;
header = ";StdErr;Ratio;";
format = 6.3;
end;
define ChiSq;
parent = [Link];
end;
366 TS-677E Multinomial Logit, Discrete Choice Modeling
define ProbChiSq;
parent = [Link];
end;
define HazardRatio;
header = ";Hazard;Ratio;";
glue = 2;
format = 8.3;
end;
define HRLowerCL;
glue = 2;
format = 8.3;
print_headers = OFF;
end;
define HRUpperCL;
format = 8.3;
print_headers = OFF;
end;
define Label;
header = "Variable Label";
end;
col_space_max = 4;
col_space_min = 1;
required_space = NRows;
end;
It contains header, format, spacing and other information for each column in the table. Most of this need not
concern us now. The template contains this column statement, which lists the columns of the table.
column Variable DF Estimate StdErr StdErrRatio ChiSq ProbChiSq HazardRatio
HRLowerCL HRUpperCL Label;
Since we will usually have a label that adequately names each parameter, we do not need the variable column.
We also do not need the hazard information. If we move the label to the front of the list and drop the variable
column and the hazard columns, we get this.
column Label DF Estimate StdErr ChiSq ProbChiSq;
We use the edit statement to edit the template. We can also modify some headers. We specify the new column
statement and the new headers. We can also modify the Summary table ([Link])
to use the vocabulary of choice models instead of survival analysis models. The code is grabbed from the
PROC TEMPLATE step with the source statement. The overall header ’Summary of the Number of Event and
Censored Values’ is changed to ’Summary of Subjects, Sets, and Chosen and Unchosen Alternatives’, ’Total’ is
changed to ’Number of Alternatives’, ’Event’ is changed to ’Chosen Alternatives’, ’Censored’ is changed to ’Not
Chosen’, and ’Percent Censored’ is dropped. Finally Style=RowHeader was specified on the label column.
This sets the color, font, and general style for HTML output. The RowHeader style is typically used on first
columns that provide names or labels for the rows. Here is the code that the %phchoice(on) macro runs.
proc template;
edit [Link];
column Label DF Estimate StdErr ChiSq ProbChiSq;
header h1;
define h1;
text "Multinomial Logit Parameter Estimates";
space = 1;
spill_margin;
end;
The Macros 367
define Label;
header = " " style = RowHeader;
end;
end;
edit [Link];
column Stratum Pattern Freq GenericStrVar Total
Event Censored;
header h1;
define h1;
text "Summary of Subjects, Sets, "
"and Chosen and Unchosen Alternatives";
space = 1;
spill_margin;
first_panel;
end;
define Freq;
header=";Number of;Choices" format=6.0;
end;
define Total;
header = ";Number of;Alternatives";
format_ndec = ndec;
format_width = 8;
end;
define Event;
header = ";Chosen;Alternatives";
format_ndec = ndec;
format_width = 8;
end;
define Censored;
header = "Not Chosen";
format_ndec = ndec;
format_width = 8;
end;
end;
run;
Here is the code that %phchoice(off) runs.
* Delete edited templates, restore original templates;
proc template;
delete [Link];
delete [Link];
run;
Our editing of the multinomial logit parameter estimates table assumes that each independent variable has a
label. If you are coding with PROC TRANSREG, this will be true of all variables created by class expansions.
You may have to provide labels for identity and other variables. Alternatively, if you want variable names
to appear in the table, you can do that as follows. This may be useful when you are not coding with PROC
TRANSREG.
%phchoice(on, Variable DF Estimate StdErr ChiSq ProbChiSq Label)
The optional second argument provides a list of the column names to print. The available columns are: Vari-
able DF Estimate StdErr StdErrRatio ChiSq ProbChiSq HazardRatio HRLowerCL
HRUpperCL Label. (HRLowerCL and HRUpperCL are confidence limits on the hazard ratio.) For very
detailed customizations, you may have to run PROC TEMPLATE directly.
368 TS-677E Multinomial Logit, Discrete Choice Modeling
onoff
ON specifies choice model customization.
OFF turns off the choice model customization and returns to the default PROC PHREG templates.
EXPB turns on choice model customization and adds the hazard ratio to the output.
Upper/lower case does not matter.
column
specifies an optional column list for more extensive customizations.
Concluding Remarks 369
Concluding Remarks
This report has illustrated how to design a choice experiment; prepare the questionnaire; input, process, and code
the design; perform the analysis; and interpret the results. All examples were artificial. We would welcome
any real data sets that we could use in future examples. This report has already been revised many times, and
future revisions are likely. If you have comments or suggestions for future revisions write Warren F. Kuhfeld,
([Link]@[Link]) at SAS Institute Inc. Please direct questions to the technical support division. For
more information on discrete choice, see Carson et. al. (1994) and the papers they reference. For information on
designing experiments for discrete choice, see Lazari and Anderson (1994), and see Kuhfeld, Tobias, and Garratt
(1994) on page 25.
I hope you like the new macros. In particular, I hope you find the new %MktEx macro to be very powerful and
useful. My goal in writing this book is to help you do better research and do it more quickly and more easily. I
would like to hear what you think.
For Those Who Like a Challenge
What do most of the random number seeds used in the Multinomial Logit, Discrete Choice Modeling re-
port and all of the seeds used in the Conjoint Analysis Examples report have in common? Send answers to
[Link]@[Link]. I will send a small prize to the first person to send me the answer that I have in mind.
Hints: Ignore seed 7654321; it has nothing in common with the others. Seeds 201 and 155 almost but not quite
fit with the others. Seeds 446, 538, and 543 are part of a still larger group. Answers like “they are all less than
619,” while true, are not what I have in mind.
370 TS-677E Multinomial Logit, Discrete Choice Modeling
References
Addelman, S. (1962), “Orthogonal Main-Effects Plans for Asymmetrical Factorial Experiments”, Technometrics,
4, 21 46.
Bose, R.C. (1947), “Mathematical Theory of the Symmetrical Factorial Design”, Sankhya, 8, 107 166.
Carson, R.T., Louviere, J.J, Anderson, D.A., Arabie, P., Bunch, D., Hensher, D.A., Johnson, R.M., Kuhfeld,
W.F., Steinberg, D., Swait, J., Timmermans, H., and Wiley, J.B. (1994), “Experimental Analysis of Choice,”
Marketing Letters, 5(4), 351 368.
Cook, R.D. and Nachtsheim, C.J. (1980), “A Comparison of Algorithms for Constructing Exact D-optimal De-
signs”, Technometrics, 22, 315 324.
Dey, A. (1985), Orthogonal Fractional Factorial Designs, New York: Wiley.
Fedorov, V.V. (1972), Theory of Optimal Experiments, translated and edited by W.J. Studden and E.M. Klimko,
New York: Academic Press.
Finney, D.J. (1982), “Some Enumerations for the 6x6 Latin Squares”, Utilitas Mathematics, 21, 137 153.
Hadamard, J. (1893), “Resolution d’une question relative aux determinants”,Bull. des Sciences Math, (2), 17,
240 246.
Hedayat, A.S., Sloane, N.J.A., and Stufken, J. (1999), Orthogonal Arrays, New York: Springer.
Huber, J., and Zwerina, K. (1996), “The Importance of Utility Balance in Efficient Choice Designs,” Journal of
Marketing Research, 33, 307 317.
Kuhfeld, W.F., Tobias, R.D., and Garratt, M. (1994), “Efficient Experimental Design with Marketing Research
Applications,” Journal of Marketing Research, 31, 545 557.
Lazari, A.G. and Anderson, D.A. (1994), “Designs of Discrete Choice Set Experiments for Estimating Both
Attribute and Availability Cross Effects,” Journal of Marketing Research, 31, 375 383.
Louviere, J.J. (1991), “Consumer Choice Models and the Design and Analysis of Choice Experiments,” Tutorial
presented to the American Marketing Association Advanced Research Techniques Forum, Beaver Creek,
Colorado.
Louviere, J.J. and Woodworth, G (1983), “Design and Analysis of Simulated Consumer Choice of Allocation Ex-
periments: A Method Based on Aggregate Data,” Journal of Marketing Research, 20 (November), 350 67.
Manski, C.F., and McFadden, D. (1981), Structural Analysis of Discrete Data with Econometric Applications.
Cambridge: MIT Press.
Meyer, R.K., and Nachtsheim, C.J. (1995), “The Coordinate-Exchange Algorithm for Constructing Exact Opti-
mal Experimental Designs”, Technometrics, 37, 60 69.
Paley, R.E.A.C (1933), On Orthogonal Matrices, J. Math. Phys, 12, 311 320.
Rao, C.R. (1947), “Factorial Experiments Derivable from Combinatorial Arrangements of Arrays”, Journal of
the Royal Statistical Society, Suppl., 9, 128 139.
Suen, C.-Y. (1989), “Some Resolvable Orthogonal Arrays with Two Symbols”, Communications in Statistics,
Theory and Methods, 18, 3875 3881.
Suen, C.-Y. (1989), “A Class of Orthogonal Main Effects Plans”, Journal of Statistical Planning and Inference,
21, 391 394.
Taguchi, G. (1987), System of Experimental Design: Engineering Methods to Optimize Quality and Minimize
Costs. White Plains, NY: UNIPIB, and Dearborn, MI: American Supplier Institute.
Wang, J.C., and Wu, C.F.J. (1991), “An Approach to the Construction of Asymmetrical Orthogonal Arrays”,
Journal of the American Statistical Association, 86, 450 456.
References 371
Wang, J.C., (1996), “Mixed Difference Matrices and the Construction of Orthogonal Arrays”, Statist. Probab.
Lett., 28, 121 126.
Wang, J.C., (1996), A Recursive Construction of Orthogonal Arrays, Preprint.
Williamson, J. (1944), “Hadamard’s Determinant Theorem and the Sum of Four Squares”, Duke Math. J., 11,
65 81.
Zhang, Y.S., Lu, Y., and Pang, S., (1999), “Orthogonal Arrays Obtained by Orthogonal Decompositions of
Projection Matrices”, Statistica Sinica, 9, 595 604.
SAS and SAS/STAT are registered trademarks or trademarks of SAS in the USA and other countries. indicates
USA registration.
372 TS-677E Multinomial Logit, Discrete Choice Modeling
ABSTRACT Multinomial logit models are used to model relationships between a polytomous response variable
and a set of regressor variables. The term “multinomial logit model” includes, in a broad sense, a variety of
models. The cumulative logit model is used when the response of an individual unit is restricted to one of a finite
number of ordinal values. Generalized logit and conditional logit models are used to model consumer choices.
This article focuses on the statistical techniques for analyzing discrete choice data and discusses fitting these
models using SAS/STAT R software.
Introduction Multinomial logit models are used to model relationships between a polytomous response variable
and a set of regressor variables. These polytomous response models can be classified into two distinct types,
depending on whether the response variable has an ordered or unordered structure.
In an ordered model, the response Y of an individual unit is restricted to one of m ordered values. For example,
the severity of a medical condition may be: none, mild, and severe. The cumulative logit model assumes that the
ordinal nature of the observed response is due to methodological limitations in collecting the data that results in
lumping together values of an otherwise continuous response variable (McKelvey and Zavoina 1975). Suppose
Y takes values y1 ; y2 ; : : :; ym on some scale, where y1 < y2 < : : : < ym . It is assumed that the observable
variable is a categorized version of a continuous latent variable U such that
Y =y i , i 1 <U ; i = 1; : : :; m
i
where 1 = 0 < 1 < : : : < m = 1. It is further assumed that the latent variable U is determined by the
explanatory variable vector x in the linear form U = 0 x + ; where is a vector of regression coefficients
and is a random variable with a distribution function F . It follows that
PrfY y jxg = F ( + 0 x)
i i
If F is the logistic distribution function, the cumulative model is also known as the proportional odds model.
You can use PROC LOGISTIC or PROC PROBIT directly to fit the cumulative logit models. Although the
cumulative model is the most widely used model for ordinal response data, other useful models include the
adjacent-categories logit model and the continuation-ratio model (Agresti 1990).
In an unordered model, the polytomous response variable does not have an ordered structure. Two classes of
models, the generalized logit models and the conditional logit models, can be used with nominal response data.
The generalized logit model consists of a combination of several binary logits estimated simultaneously. For
example, the response variable of interest is the occurrence or nonoccurrence of infection after a Caesarean
section with two types of (I,II) infection. Two binary logits are considered: one for type I infection versus no
infection and the other for type II infection versus no infection. The conditional logit model has been used in
biomedical research to estimate relative risks in matched case-control studies. The nuisance parameters that
correspond to the matched sets in an unconditional analysis are eliminated by using a conditional likelihood
that contains only the relative risk parameters (Breslow and Days 1980). The conditional logit model was also
introduced by McFadden (1973) in the context of econometrics.
In studying consumer behavior, an individual is presented with a set of alternatives and asked to choose the most
preferred alternative. Both the generalized logit and conditional logit models are used in the analysis of discrete
choice data. In a conditional logit model, a choice among alternatives is treated as a function of the characteristics
of the alternatives, whereas in a generalized logit model, the choice is a function of the characteristics of the
individual making the choice. In many situations, a mixed model that includes both the characteristics of the
alternatives and the individual is needed for investigating consumer choice.
This paper was presented at SUGI 20 by Ying So and can also be found in the SUGI 20 proceedings.
Multinomial Logit Models 373
Consider an example of travel demand. People are asked to choose between travel by auto, plane or public
transit (bus or train). The following SAS R statements create the data set TRAVEL. The variables AUTOTIME,
PLANTIME, and TRANTIME represent the total travel time required to get to a destination by using auto, plane,
or transit, respectively. The variable AGE represents the age of the individual being surveyed, and the variable
CHOSEN contains the individual’s choice of travel mode.
data travel;
input AutoTime PlanTime TranTime Age Chosen $;
datalines;
10.0 4.5 10.5 32 Plane
5.5 4.0 7.5 13 Auto
4.5 6.0 5.5 41 Transit
3.5 2.0 5.0 41 Transit
1.5 4.5 4.0 47 Auto
10.5 3.0 10.5 24 Plane
7.0 3.0 9.0 27 Auto
9.0 3.5 9.0 21 Plane
4.0 5.0 5.5 23 Auto
22.0 4.5 22.5 30 Plane
7.5 5.5 10.0 58 Plane
11.5 3.5 11.5 36 Transit
3.5 4.5 4.5 43 Auto
12.0 3.0 11.0 33 Plane
18.0 5.5 20.0 30 Plane
23.0 5.5 21.5 28 Plane
4.0 3.0 4.5 44 Plane
5.0 2.5 7.0 37 Transit
3.5 2.0 7.0 45 Auto
12.5 3.5 15.5 35 Plane
1.5 4.0 2.0 22 Auto
;
In this example, AUTOTIME, PLANTIME, and TRANTIME are alternative-specific variables, whereas AGE is
a characteristic of the individual. You use a generalized logit model to investigate the relationship between the
choice of transportation and AGE, and you use a conditional logit model to investigate how travel time affects
the choice. To study how the choice depends on both the travel time and age of the individual, you need to use a
mixed model that incorporates both types of variables.
A survey of the literature reveals a confusion in the terminology for the nominal response models. The term
“multinomial logit model” is often used to describe the generalized logit model. The mixed logit is sometimes
referred to as the multinomial logit model in which the generalized logit and the conditional logit models are
special cases.
The following sections describe discrete choice models, illustrate how to use SAS/STAT software to fit these
models, and discuss cross-alternative effects.
Modeling Discrete Choice Data Consider an individual choosing among m alternatives in a choice set. Let jk
denote the probability that individual j chooses alternative k , let Xj represent the characteristics of individual j ,
and let Zjk be the characteristics of the k th alternative for individual j . For example, Xj may be an age and each
Zjk a travel time.
The generalized logit model focuses on the individual as the unit of analysis and uses individual characteristics
as explanatory variables. The explanatory variables, being characteristics of an individual, are constant over the
alternatives. For example, for each of the m travel modes, Xj = (1 age)0 , and for the first subject, X1 = (1 32)0 .
The probability that individual j chooses alternative k is
0
= P exp(exp(X0 X
) =P
k j 1
)0 X )]
) =1 exp[(
jk m m
=1 l l j l l k j
374 TS-677E Multinomial Logit, Discrete Choice Modeling
0 Z )
= P exp(exp(
jk
m
1
0 Z ) = P exp[0 (Z
jk
m
Zjk )]
=1 l =1 jl l jl
is a single vector of regression coefficients. The impact of a variable on the choice probabilities derives from
the difference of its values across the alternatives.
For the mixed logit model that includes both characteristics of the individual and the alternatives, the choice
probabilities are
0 0
= Pexp(exp(X 0 X+ +Z0 Z) )
jk m
k j jk
=1 l l j jl
1 ; : : :; m 1 and m
0 are the alternative-specific coefficients, and is the set of global coefficients.
Fitting Discrete Choice Models The CATMOD procedure in SAS/STAT software directly fits the generalized
logit model. SAS/STAT software does not yet have a procedure that is specially designed to fit the conditional or
mixed logit models. However, with some preliminary data processing, you can use the PHREG procedure to fit
these models.
The PHREG procedure fits the Cox proportional hazards model to survival data (refer to SAS Technical Report
P-229). The partial likelihood of Breslow has the same form as the likelihood in a conditional logit model.
Let zl denote the vector of explanatory variables for individual l. Let t1 < t2 < : : : < tk denote k distinct
ordered event times. Let di denote the number of failures at ti . Let si be the sum of the vectors zl for those
individuals that fail at ti , and let Ri denote the set of indices for those who are at risk just before ti .
The Breslow (partial) likelihood is
L () =
Y k
exp(0 s )
P i
B
=1
i
[ 2Ri exp(0 z )] i
l l
d
In a stratified analysis, the partial likelihood is the product of the partial likelihood for each individual stratum.
For example, in a study of the time to first infection from a surgery, the variables of a patient consist of TIME
(time from surgery to the first infection), STATUS (an indicator of whether the observation time is censored,
with value 2 identifying a censored time), Z1 and Z2 (explanatory variables thought to be related to the time to
infection), and GRP (a variable identifying the stratum to which the observation belongs). The specification in
PROC PHREG for fitting the Cox model using the Breslow likelihood is as follows:
proc phreg;
model time*status(2) = z1 z2 / ties=breslow;
strata grp;
run;
Multinomial Logit Models 375
To cast the likelihood of the conditional logit model in the form of the Breslow likelihood, consider m artificial
observed times for each individual who chooses one of m alternatives. The k th alternative is chosen at time 1; the
choices of all other alternatives (second choice, third choice, ...) are not observed and would have been chosen
at some later time. So a choice variable is coded with an observed time value of 1 for the chosen alternative and
a larger value, 2, for all unchosen (unobserved or censored alternatives). For each individual, there is exactly
one event time (1) and m 1 nonevent times, and the risk set just prior to this event time consists of all the m
alternatives. For individual j with alternative-specific characteristics Zjl , the Breslow likelihood is then
L () = P
exp(0 Z ) jk
0
=1 exp( Z )
B m
l jl
This is precisely the probability that individual j chooses alternative k in a conditional logit model. By stratifying
on individuals, you get the likelihood of the conditional logit model. Note that the observed time values of 1 and
2 are chosen for convenience; however, the censored times have to be larger than the event time to form the
correct risk set.
Before you invoke PROC PHREG to fit the conditional logit, you must arrange your data in such a way that there
is a survival time for each individual-alternative. In the example of travel demand, let SUBJECT identify the
individuals, let TRAVTIME represent the travel time for each mode of transportation, and let CHOICE have a
value 1 if the alternative is chosen and 2 otherwise. The CHOICE variable is used as the artificial time variable
as well as a censoring variable in PROC PHREG. The following SAS statements reshape the data set TRAVEL
into data set CHOICE and display the first nine observations:
data choice(keep=subject mode travtime choice);
array times[3] autotime plantime trantime;
array allmodes[3] $ _temporary_ (’Auto’ ’Plane’ ’Transit’);
set travel;
Subject = _n_;
do i = 1 to 3;
Mode = allmodes[i];
TravTime = times[i];
Choice = 2 - (chosen eq mode);
output;
end;
run;
Trav
Obs Subject Mode Time Choice
1 1 Auto 10.0 2
2 1 Plane 4.5 1
3 1 Transit 10.5 2
4 2 Auto 5.5 1
5 2 Plane 4.0 2
6 2 Transit 7.5 2
7 3 Auto 4.5 2
8 3 Plane 6.0 2
9 3 Transit 5.5 1
Notice that each observation in TRAVEL corresponds to a block of three observations in CHOICE, exactly one
of which is chosen.
376 TS-677E Multinomial Logit, Discrete Choice Modeling
The following SAS statements invoke PROC PHREG to fit the conditional logit model. The Breslow likelihood
is requested by specifying TIES=BRESLOW. CHOICE is the artificial time variable, and a value of 2 identifies
censored times. SUBJECT is used as a stratification variable.
proc phreg data=choice;
model choice*choice(2) = travtime / ties=breslow;
strata subject;
title ’Conditional Logit Model Using PHREG’;
run;
To study the relationship between the choice of transportation and the age of people making the choice, the
analysis is based on the generalized logit model. You can use PROC CATMOD directly to fit the generalized
logit model (refer to SAS/STAT User’s Guide, Vol. 1). In the following invocation of PROC CATMOD, CHOSEN
is the response variable and AGE is the explanatory variable:
proc catmod data=travel;
direct age;
model chosen=age;
title ’Multinomial Logit Model Using Catmod’;
run;
Response Profiles
Response Chosen
-------------------
1 Auto
2 Plane
3 Transit
Note that there are two intercept coefficients and two slope coefficients for AGE. The first INTERCEPT and the
first AGE coefficients correspond to the effect on the probability of choosing auto over transit, and the second
intercept and second age coefficients correspond to the effect of choosing plane over transit.
Multinomial Logit Models 377
Let Xj be a (p +1)-vector representing the characteristics of individual j . The generalized logit model can be cast
in the framework of a conditional model by defining the global parameter vector and the alternative-specific
regressor variables Zjk as follows:
2 3
2 3 2
X
3 0 2
0
3 2 3
1 j 6 X 7 0
6 0 7
6 7 6 6 j 7 6
6 ... 7
= 66
2
..
7
7 Zj
7
1 = 6 .. 7 Zj
6
2 =6
0 77 ::: Zj;m 1 =6
7
7 Zjm = 4 ... 75
6
4 5 4 . 5 6 .. 7 4 0 5
.
0
4 . 5 0
m 1 0 Xj
where the 0 is a (p +1)-vector of zeros. The probability that individual j chooses alternative k for the generalized
logit model is put in the form that corresponds to a conditional logit model as follows:
0
jk = P exp(exp(X0 X) )
m
k j
=1 l l j
exp( 0 Z )
= P exp( m
0 Z )
jk
l=1 jl
Here, the vector Xj representing the characteristics of individual j includes the element 1 for the intercept
parameter (provided that the intercept parameters are to be included in the model).
By casting the generalized logit model into a conditional logit model, you can then use PROC PHREG to analyze
the generalized logit model. In the example of travel demand, the alternative-specific variables AUTO, PLANE,
AGEAUTO, and AGEPLANE are created from the individual characteristic variable AGE. The following SAS
statements reshape the data set TRAVEL into data set CHOICE2 and display the first nine observations:
data choice2;
array times[3] autotime plantime trantime;
array allmodes[3] $ _temporary_ (’Auto’ ’Plane’ ’Transit’);
set travel;
Subject = _n_;
do i = 1 to 3;
Mode = allmodes[i];
TravTime = times[i];
Choice = 2 - (chosen eq mode);
Auto = (i eq 1);
Plane = (i eq 2);
AgeAuto = auto * age;
AgePlane = plane * age;
output;
end;
keep subject mode travtime choice auto plane ageauto ageplane;
run;
proc print data=choice2(obs=9);
run;
378 TS-677E Multinomial Logit, Discrete Choice Modeling
1 1 Auto 10.0 2 1 0 32 0
2 1 Plane 4.5 1 0 1 0 32
3 1 Transit 10.5 2 0 0 0 0
4 2 Auto 5.5 1 1 0 13 0
5 2 Plane 4.0 2 0 1 0 13
6 2 Transit 7.5 2 0 0 0 0
7 3 Auto 4.5 2 1 0 41 0
8 3 Plane 6.0 2 0 1 0 41
9 3 Transit 5.5 1 0 0 0 0
The following SAS statements invoke PROC PHREG to fit the generalized logit model:
proc phreg data=choice2;
model choice*choice(2) = auto plane ageauto ageplane /
ties=breslow;
strata subject;
title ’Generalized Logit Model Using PHREG’;
run;
By transforming individual characteristics into alternative-specific variables, the mixed logit model can be ana-
lyzed as a conditional logit model.
Analyzing the travel demand data for the effects of both travel time and age of individual requires the same data
set as the generalized logit model, only now the TRAVTIME variable will be used as well. The following SAS
statements use PROC PHREG to fit the mixed logit model:
proc phreg data=choice2;
model choice*choice(2) = auto plane ageauto ageplane travtime /
ties=breslow;
strata subject;
title ’Mixed Logit Model Using PHREG’;
run;
Multinomial Logit Models 379
A special case of the mixed logit model is the conditional logit model with alternative-specific constants. Each
alternative in the model can be represented by its own intercept, which captures the unmeasured desirability of
the alternative.
proc phreg data=choice2;
model choice*choice(2) = auto plane travtime / ties=breslow;
strata subject;
title ’Conditional Logit Model with Alternative Specific Constants’;
run;
With transit as the reference mode, the intercept for auto, which is negative, may reflect the inconvenience of
having to drive over traveling by bus/train, and the intercept for plane may reflect the high expense of traveling
by plane over bus/train.
Cross-Alternative Effects Discrete choice models are often derived from the principle of maximum random
utility. It is assumed that an unobserved utility Vk is associated with the k th alternative, and the response function
Y is determined by
Y = k , V = maxfV ; 1 l mg
k l
Both the generalized logit and the conditional logit models are based on the assumption that V1 ; : : :; Vm are
independently distributed and each follows an extreme maxima value distribution (Hoffman and Duncan, 1988).
An important property of such models is Independence from Irrelevant Alternatives (IIA); that is, the ratio of
the choice probabilities for any two alternatives for a particular observation is not influenced systematically by
any other alternatives. IIA can be tested by fitting a model that contains all the cross-alternative effects and
examining the significance of these effects. The cross-alternative effects pick up a variety of IIA violations and
other sources of error in the model. (See pages 179, 185, 192, and 383 for other discussions of IIA.)
380 TS-677E Multinomial Logit, Discrete Choice Modeling
In the example of travel demand, there may be separate effects for the three travel modes and travel times. In
addition, there may be cross-alternative effects for travel times. Not all the effects are estimable, only two of
the three intercepts and three of the six cross-alternative effects can be estimated. The following SAS statements
create the design variables for all the cross-alternative effects and display the first nine observations:
* Number of alternatives in each choice set;
%let m = 3;
data choice3;
drop i j k autotime plantime trantime;
1 Auto 10.0 2 1 0 0
1 Plane 4.5 1 0 1 0
1 Transit 10.5 2 0 0 1
2 Auto 5.5 1 1 0 0
2 Plane 4.0 2 0 1 0
2 Transit 7.5 2 0 0 1
3 Auto 4.5 2 1 0 0
3 Plane 6.0 2 0 1 0
3 Transit 5.5 1 0 0 1
PROC PHREG allows you to specify TEST statements for testing linear hypotheses of the parameters. The
test is a Wald test, which is based on the asymptotic normality of the parameter estimators. The following
SAS statements invoke PROC PHREG to fit the so called “Mother Logit” model that includes all the cross-
alternative effects. The TEST statement, with label IIA, specifies the null hypothesis that cross-alternative effects
AUTOPLAN, PLANTRAN, and TRANAUTO are 0. Since only three cross-alternative effects are estimable and
these are the first cross-alternative effects specified in the model, they account for all the cross-alternative effects
in the model.
proc phreg data=choice3;
model choice*choice(2) = auto plane transit timeauto timeplan
timetran autoplan plantran tranauto planauto tranplan
autotran / ties=breslow;
IIA: test autoplan,plantran,tranauto;
strata subject;
title ’Mother Logit Model’;
run;
Convergence Status
Without With
Criterion Covariates Covariates
Wald
Label Chi-Square DF Pr > ChiSq
The 2 statistic for the Wald test is 1:6526 with 3 degrees of freedom, indicating that the cross-alternative effects
are not statistically significant (p = :6475). A generally more preferable way of testing the significance of
the cross-alternative effects is to compare the likelihood of the “Mother logit” model with the likelihood of the
reduced model with the cross- alternative effects removed. The following SAS statements invoke PROC PHREG
to fit the reduced model:
proc phreg data=choice3;
model choice*choice(2) = auto plane transit timeauto
timeplan timetran / ties=breslow;
strata subject;
title ’Reduced Model without Cross-Alternative Effects’;
run;
Convergence Status
Without With
Criterion Covariates Covariates
The chi-squared statistic for the likelihood ratio test of IIA is (27:153 24:781) = 2:372, which is not statistically
significant (p = :4989) when compared to a 2 distribution with 3 degrees of freedom. This is consistent with
the previous result of the Wald test. (See pages 179, 185, 192, and 379 for other discussions of IIA.)
Final Comments For some discrete choice problems, the number of available alternatives is not the same for
each individual. For example, in a study of consumer brand choices of laundry detergents as prices change, data
are pooled from different locations, not all of which offer a brand that contains potash. The varying choice sets
across individuals can easily be accommodated in PROC PHREG. For individual j who chooses from a set of
mj alternatives, consider mj artificial times in which the chosen alternative has an event time 1 and the unchosen
alternatives have a censored time of 2. The analysis is carried out in the same fashion as illustrated in the previous
section.
Unlike the example of travel demand in which data for each individual are provided, choice data are often given
in aggregate form, with choice frequencies indicating the repetition of each choice. One way of dealing with
aggregate data is to expand the data to the individual level and carry out the analysis as if you have nonaggregate
data. This approach is generally not recommended, because it defeats the purpose of having a smaller aggregate
data set. PROC PHREG provides a FREQ statement that allows you to specify a variable that identifies the
frequency of occurrence of each observation. However, with the specification of a FREQ variable, the artificial
event time is no longer the only event time in a given stratum, but has ties of the given frequency. With proper
stratification, the Breslow likelihood is proportional to the likelihood of the conditional logit model. Thus PROC
PHREG can be used to obtain parameter estimates and hypothesis testing results for the choice models.
384 TS-677E Multinomial Logit, Discrete Choice Modeling
The TIES=DISCRETE option should not be used instead of the TIES=BRESLOW option. This is especially
detrimental with aggregate choice data because the likelihood that PROC PHREG is maximizing may no longer
be the same as the likelihood of the conditional logit model. TIES=DISCRETE corresponds to the discrete
logistic model for genuinely discrete time scale, which is also suitable for the analysis of case-control studies
when there is more than one case in a matched set (Gail, Lubin, and Rubinstein, 1981). For nonaggregate choice
data, all TIES= options give the same results; however, the resources required for the computation are not the
same, with TIES=BRESLOW being the most efficient.
Once you have a basic understanding of how PROC PHREG works, you can use it to fit a variety of models
for the discrete choice data. The major involvement in such a task lies in reorganizing the data to create the
observations necessary to form the correct risk sets and the appropriate design variables. There are many options
in PROC PHREG that can also be useful in the analysis of discrete choice data. For example, the OFFSET=
option allows you to restrict the coefficient of an explanatory variable to the value of 1; the SELECTION= option
allows you to specify one of four methods for selecting variables into the model; the OUTEST= option allows
you to specify the name of the SAS data set that contains the parameter estimates, based on which you can easily
compute the predicted probabilities of the alternatives.
This article deals with estimating parameters of discrete choice models. There is active research in the field of
marketing research to use design of experiments to study consumer choice behavior. If you are interested in this
area, refer to Carson et al. (1994), Kuhfeld et al. (1994), and Lazari et al. (1994).
Multinomial Logit Models 385
References
Agresti, A. (1990) Categorical Data Analysis. New York: John Wiley & Sons.
Breslow, N. and Day, N.E. (1980), Statistical Methods in Cancer Research, Vol. II: The Design and Analysis of
Cohort Studies, Lyon: IARC.
Carson, R.T.; Louviere, J.J; Anderson, D.A.; Arabie, P.; Bunch, D.; Hensher, D.A.; Johnson, R.M.; Kuhfeld,
W.F.; Steinberg, D.; Swait, J.; Timmermans, H.; and Wiley, J.B. (1994), “Experimental Analysis of Choice,”
Marketing Letters, 5(4), 351-368.
Gail, M.H., Lubin, J.H., and Rubinstein, L.V. (1981), “Likelihood calculations for matched case-control studies
and survival studies with tied death times,” Biometrika, 68, 703-707.
Hoffman, S.D. and Duncan, G.J. (1988), “Multinomial and conditional logit discrete-choice models in Demog-
raphy,” Demography, 25 (3), 415-427.
Kuhfeld, W.F., Tobias, R.D., and Garratt, M. (1994), “Efficient Experimental Design with Marketing Research
Applications,” Journal of Marketing Research, 31, 545-557.
Lazari, A.G. and Anderson, D.A. (1994), “Designs of Discrete Choice Set Experiments for Estimating Both
Attribute and Availability Cross Effects,” Journal of Marketing Research, 31, 375-383.
McFadden, D. (1973), “Conditional logit analysis of qualitative choice behavior,” in P. Zarembka (Ed.) Frontiers
in Econometrics, New York: Academic Press, Inc.
McKelvey, R.D. and Zavoina, W. (1975), “A statistical model for the analysis of ordinal level dependent vari-
ables,” Journal of Mathematical Sociology, 4, 103-120.
SAS Institute Inc. (1989), SAS/STAT User’s Guide, Vol. 1, Version 6, Fourth Edition, Cary: NC: SAS Institute
Inc.
SAS Institute Inc. (1992), SAS Technical Report P-229. SAS/STAT Software: Changes and Enhancements,
Release 6.07, Cary, NC: SAS Institute Inc.
SAS and SAS/STAT are trademarks or registered trademarks of SAS in the USA and other countries. indicates
USA registration.
386 TS-677E Multinomial Logit, Discrete Choice Modeling
Index
@@ 85 block= 312
accept defined 337 BLOCKED data set 313
accept option 281 285-286 333 336-339 blocking 209 238
A-efficiency 77 blocks 162 209
Age variable 230-231 blocks= defined 325 353
aggregate data 171-174 185-188 225-226 243 247- blocks= 135 353
249 383 blue bus 192
aliased 76 brand choice (aggregate data) example 173
aliasing structure 207 Brand variable 102-106 175 179-180 215 218-222
allcode defined 317 231 242-246 298 303 356-359
allocation study 237-247 branded defined 324
ALLOCS data set 305 branded 324
Alt variable 110 310-312 Breslow likelihood 191
- Alt- variable 359 brief 107-109 138 236
alt= defined 312 359 bundles of attributes 252 280
alt= 102-103 312 359 bus 192
alternative-specific effects 146-148 169 177 180 184 c = 2 - (i eq choice) 87
194 218 221 293 373-379 c variable 85-88 105 109 113 135 179-180 225 246
Ann 160 304 353-354
anneal= defined 340 c*c(2) 88 107
anneal= 281 340 c*c(3) 88
annealfun= defined 344 Can 160 198
annealing 124 cand= defined 315
anniter= defined 340 cand= 317
anniter= 340 candidate set 123 194 198 254 258 262-264 280 285-
arrays 92 100 112-114 131 164-166 173 185 223 242 288 292-293
264 375-377 380 canditer= defined 340
artificial data 75 166 223 canditer= 340-341
asymmetry 153 192 candy example 83
augmenting an existing design 269 canonical correlation 98
autocall macros 287 CB data set 326
availability cross effects 192-195 206 226 chair (generic attributes) example 252
available, not 347 check defined 317 337
bad variable 195 338 check the data entry 89
balance 77 95 163 214 check option 126 339
balance= defined 336 Chi-Square statistic 90
balance= 204-206 336-337 choice design 78-79 95 102-104
balanced and orthogonal 77 80-82 95 choice design efficiency 77 217-223 253-262 266 283
bestcov= defined 300 288 291-299
bestout= defined 300 choice design generation 255 258-262 266 289 292
bestout= 301 295-298 320-321
beta= defined 300 choice model, coding 105 136 140-144 148 169 175-
beta= 217 255 289 296 300 177 180 185-188 226 230 246
big designs 153 choice model, fitting 107 138-142 145 149 170-172
big= defined 314 343 175-177 183 187-188 226 234 247-249 374-
big= 314 317 343 382
bin of attributes 78 102 131 choice probabilities 92
binary coding 105-106 136 143 169 175 choice sets, minimum number 252
blank header 128 Choice variable 87
Block variable 133 239 247 307 312 349 choice-based conjoint 74
block= defined 312 %ChoicEff macro 74-75 215-220 226 252-267 275-
Index 387
277 280 283 287-299 307 310-312 320-321 design 106 136 169 175
351 387-389 design, differences 303 307 313 318 339
%ChoicEff macro documentation 288-303 design, methods compared 267
%ChoicEff macro versus the %MktEx macro 267 design
%ChoicEff macro, alternative swapping 261 267 evaluation 97 124 129 154 160 200-206 239 305
%ChoicEff macro, set swapping 264 267 generation 95-96 110 119 126-128 154-157 162
Choose variable 115 195 199 202-204 238 252-254 261 264 268-
choose 343 269 273 289 292 296-297 307 310 320-323
chosen alternative 87 327 332 345 348-352 357-358
class statement 206 315 318 saturated 82
class 105-106 136 139 143-144 148 169 175-177 size 94 117 153 156 202 237 253 336 360-363
180 206 216-218 225-226 244 252 255 296 testing 215
367 design= defined 354 359
classopts= defined 315 design= 103-105 133 353 356 359
Client variable 347 Dest variable 131
coded defined 302 detail defined 302
coding down 157 315 342 detfuzz= defined 344
coding the choice model 105 136 140-144 148 169 different designs 303 307 313 318 339
175-177 180 185-188 226 230 246 diminishing returns on iterations 198
coding dolist= defined 351
binary 105-106 136 169 175 dolist= 351-353
effects 143 dollar format 239
coding= defined 315 D-optimality 327
Color variable 357-358 drop= defined 301
column defined 368 drop= 295 301
column statement 366 dropping variables 106 136
confounded 76 duplicate runs 333
constant alternative 94 110 173 edit statement 366
converge= defined 301 effects coding 143
converge= 293-295 effects 143 296
coordinate-exchange algorithm 123 efficiency 77
CORR data set 326 efficiency of a choice design 77
Count variable 242-243 303 Efficiency variable 257
cov= defined 301 eigenvalues 77
cross effects 175 179-185 192-195 206 218 222 225- errors in running macros 288
226 229 233-234 %EvalEff macro 206
customizing PHREG output 79 364-367 examine= defined 315 336
customizing the multinomial logit output 79 examine= 98 126 315 336
cyclic design 291 examining the design 97 124 129 154 160 200-206
data entry 85-87 102 114 133 167 173 185 224 229 239 305
242 373 example
data entry, checking 89 brand choice (aggregate data) 173
data processing 115 144 147 215-216 242 245 249 candy 83
264 375-377 380 chair (generic attributes) 252
data, generating artificial 166 223 fabric softener 94
data= defined 301 304 312 325 351-353 food product (availability) 192
data= 88 104-105 109 217 239 245 255 289 301 304 prescription drugs (allocation) 237
312 324 347-348 351-354 vacation 116
D-efficiency 77 198-199 207 vacation (alternative-specific) 152
D-efficiency, 0 to 100 scale 77 80-82 206 exchange= defined 343
degree= 142 exchange= 338 341-343
demographic information 229 existing design, improving 268
DESIGN data set 306 317 332 339 experimental design
design key 102 defined 76
Design variable 118 257 evaluation 97 124 129 154 160 200-206 239 305
388 TS-677E Multinomial Logit, Discrete Choice Modeling
generation 95-96 110 119 126-128 154-157 162 Hadamard matrices 331-332 337 345-346
195 199 202-204 238 252-254 261 264 268- header, blank or null 128
269 273 289 292 296-297 307 310 320-323 holdouts= defined 343
327 332 345 348-352 357-358 holdouts= 269 273
saturated 82 host differences 303 307 313 318 339
size 94 117 153 156 202 237 253 336 360-363 HRLowerCL 367
testing 215 HRUpperCL 367
external attributes 229 (i eq choice) 87
extreme value type I distribution 192 i variable 338
f variable 269 id statement 106 136 169 175
fabric softener example 94 id= defined 312
facopts= defined 315 identity 106 140 175-177 180 218 226 367
factors 76 IIA 179 185 192 379-383
factors statement 317 imlopts= defined 344
factors= defined 312 315 325-326 improving an existing design 268
factors= 315-316 321 Income variable 230-231
failed initialization 333 independence 107
Federov, modified 123 289 independence from irrelevant alternatives 179 185
file statement 100 192
FINAL data set 352 Index variable 257 295
fitting the choice model 88-90 107 138-142 145 149 information matrix 77
170-172 175-177 183 187-188 226 234 247- init= defined 301 339
249 374-382 init= 126 217 268-269 275 291 295 301 337-339
fixed choice sets 269 343
fixed= defined 301 343 initblock= defined 312
fixed= 269 initialization failed 333
flags= defined 300 initialization switching 333
flags= 255 266 289 299-301 initvars= defined 301
food product (availability) example 192 initvars= 291 295 301
Form variable 110 135 171 input data 85
format statement 147 354 input statement 85
format= defined 326 input function 105 134
formats 92 95 99 112 167-169 173 185 212 216 int= defined 351
&forms variable 110 int= 254 289
fractional-factorial designs 76 interact= defined 316 337
FREQ data set 326 interact= 317
freq statement 172 187-188 226 247-249 interactions 76 146 155 171 193-194 208 214
Freq variable 187 intiter= defined 301
- FREQ- variable 171-172 225-226 intiter= 217 291 301-302
freq= defined 304 invalid page errors 288
freq= 246 304-305 iter= defined 302 306 312 316 341
freqs= defined 326 iter= 283 314-316
freqs= 326 iteration history 334
frequencies, n-way 326 j1 variable 338
frequency variable 171-173 185-188 j2 variable 338
FSUM data set 326 j3 variable 338
full-factorial design 194 justparse defined 364
G-efficiency 77 keep= defined 316 359
generate statement 316 keep= 215 316
generate= defined 316 KEY data set, %MktLab 212 239 346-351
generic attributes 138 KEY data set, %MktRoll 102-103 133 147 167 215
generic defined 324 244 264 292 296-297 310 320-322 344 357-
generic design 252-257 261-267 359
generic 324 key= defined 351 359
geometric mean 77 key= 103 211-212 215 239 287 344-350 353 356-
Index 389
seed= 95 255 289 303 307 313 318 339 subdesign 194 206
separators= 169 177 180 218 Subj variable 85 88-89 105-107 173-174 179-180
sequential algorithm 206 226
set statement 87 113 subject attributes 229
Set variable 85 88-89 104-107 110 113-115 171-173 submat= defined 303
179-180 187 217 245 257 275 312 360 subsequent choice 85-88 135 173
Set 313 summary table 88-89 188 229
set= defined 313 360 survival analysis 79 87 374
setvars= defined 354 switching initialization 333
setvars= 104 135 353 symsize= 344
Shape variable 357-358 Tab 160
Shelf variable 215-218 221 tabiter= defined 342
shelf-talker 192 211 214-215 229 tabiter= 281
Side variable 168-169 tabsize= defined 344
simulated annealing 124 160 target= defined 344
Size variable 357-358 - temporary- 100
size= defined 318 ties=breslow 79 87-88 107 188
source statement 366 time (computer), saving 171
source [Link] statement 365 trace 77
statement &- trgind variable 107-109 138-142 145 149 170-
class 206 315 318 172 175-177 180 183 187-188 226 234 247-
column 366 249
edit 366 -2 LOG L 90 179 188-190 383
factors 317 type= 109
file 100 types= defined 303
format 147 354 types= 303
freq 172 187 249 typevar= defined 303
generate 316 typevar= 303
id 106 136 169 175 unbalanced= defined 342
input 85 vacation (alternative-specific) example 152
label 354 vacation example 116
missing 211 values= defined 353
model 88 106-107 136-138 169 175-177 180 206 values= 350-353
264 289 299 317-318 variable label 88-90 99 105-106 128 136 140-144 169
output 106 136 169 175 175-177 180-188 212 218 226 230 350-352
put 167 366-367
set 87 113 variable name 367
source [Link] 365 variable
source 366 Age 230-231
strata 88 107 173 187 Alt 110 310-312
where 206 225 247 319 - Alt- 359
statements= defined 352 bad 195 338
step= defined 318 Block 133 239 247 307 312 349
step= 317-318 Brand 102-106 175 179-180 215 218-222 231
stmts= defined 354 242-246 298 303 356-359
stmts= 147 c 85-88 105 109 113 135 179-180 225 246 304
stopearly= defined 343 353-354
stopearly= 333 Choice 87
stopping early 333 Choose 115
Stove variable 211 Client 347
strata 88-89 107-109 171-173 185 189-191 374-376 Color 357-358
383 Count 242-243 303
strata statement 88 107 173 187 Design 118 257
structural zeros 91 143 151 Dest 131
Style=RowHeader 366 Efficiency 257
Index 393