# What statistical test does -contrast- use after regression in Stata?

I am using the -contrast- command to generate p-values for trend test in Stata. I've reviewed the documentation on contrast but cannot find information on what statistical test is being used behind the scenes and thus how to interpret the p-values associated with linear versus quadratic versus joint.

Background on my code: my model outcome is no_dm_dmg_v2, and my exposure is mtdnaquint, which is the quintiles of a biomarker and input as an indicator (i.) with reference Q5 (b5).

logistic no_dm_dmg_v2 ib5.mtdnaquint_new mtdnacnage male black


Output

Logistic regression                             Number of obs     =      9,124
LR chi2(7)        =     407.12
Prob > chi2       =     0.0000
Log likelihood = -3550.0948                     Pseudo R2         =     0.0542

------------------------------------------------------------------------------
no_dm_dmg_v2 | Odds Ratio   Std. Err.      z    P>|z|     [95% Conf. Interval]
-------------+----------------------------------------------------------------
mtdnaquint |
1  |   .5521241   .0525977    -6.24   0.000     .4580866     .665466
2  |   .6958681   .0682745    -3.70   0.000     .5741323     .843416
3  |   .8617032   .0858859    -1.49   0.135     .7087915    1.047604
4  |   .9143168   .0917151    -0.89   0.372     .7511257    1.112963
|
mtdnacnage |    .952226   .0051524    -9.05   0.000     .9421808    .9623783
male |   .8150846   .0503448    -3.31   0.001     .7221495    .9199798
black |   .3192515   .0208311   -17.50   0.000     .2809261    .3628054
_cons |   193.5929    63.4069    16.08   0.000     101.8821    367.8586
------------------------------------------------------------------------------

contrast p.mtdnaquint_new, noeffects

Contrasts of marginal linear predictions

Margins      : asbalanced

------------------------------------------------
|         df        chi2     P>chi2
-------------+----------------------------------
mtdnaquint |
(linear)  |          1       46.41     0.0000
(cubic)  |          1        0.05     0.8261
(quartic)  |          1        0.30     0.5814
Joint  |          4       51.46     0.0000
------------------------------------------------


When I use the reference coding (r.), I understand that the p-values for each level are that level compared to the reference, and are the same as the Wald p-values in the regression output (since I used i.mtdnaquint_new).

contrast r.mtdnaquint_new, noeffects

Contrasts of marginal linear predictions

Margins      : asbalanced

------------------------------------------------
|         df        chi2     P>chi2
-------------+----------------------------------
mtdnaquint |
(1 vs 5)  |          1       38.88     0.0000
(2 vs 5)  |          1       13.66     0.0002
(3 vs 5)  |          1        2.23     0.1353
(4 vs 5)  |          1        0.80     0.3718
Joint  |          4       51.46     0.0000
------------------------------------------------


Is the joint p-value in the contrast r. output the same as doing a test that all of the beta's = 0? Is it testing a linear trend?

• I flagged this question for moderator intervention as it is not off-topic. It was originally posted on Stack Overflow but suggested to be migrated here as it is concerned with the interpretation of statistical output and not programming. May 24, 2018 at 14:40
• You may also benefit from posting your question in the General forum of Statalist. Just make sure you mention that your question is cross-posted on here too. May 25, 2018 at 8:41

Here are examples showing this in Stata for OLS, but the intuition carries over to the logit index function coefficients.

Both of these are doing Wald tests. Let's do the second one first. You are testing that the linear index function inside the logit is the same for all groups each relative to the base value, so that is the same test that all the coefficients are zero (excluding the constant). The joint tests that all these differences are the same:

cls
net from http://www.stata-press.com/data/ivrm/
net get ivrm
use "pain.dta", clear
reg pain i.dosegrp
test 2.dosegrp
test 3.dosegrp
test 4.dosegrp
test 5.dosegrp
test 6.dosegrp
test 2.dosegrp 3.dosegrp 4.dosegrp 5.dosegrp 6.dosegrp

contrast r.dosegrp, noeffects


The polynomial contrast is more involved. Trend analysis partitions the sum of squares for the model into portions due to linear trend, quadratic trend, cubic trend, and so on. If there are $K$ groups, it is possible to look at up to $K - 1$ trends. Here's an example with $K=6$ on the same data as above.

Trend analysis is performed using coefficients of orthogonal polynomials. For 6 levels, they look like:

             g1  g2  g3  g4 g5   g6
Linear      -5  -3  -1   1   3   5
Quadratic    5  -1  -4  -4  -1   5
Cubic       -5   7   4  -4  -7   5
Quartic      1  -3   2   2  -3   1
Quintic     -1   5 -10  10  -5   1


One way to perform trend analysis is to use the coefficients of orthogonal polynomials to weight the group sums to compute sums of squares for each of the trends. An alternative is to apply the coefficients of orthogonal polynomials directly to the observations and to analyze using regression. This creates a set of variables such that the "effects" of all the preceding variable have been removed from each variable:

net from http://www.stata-press.com/data/ivrm/
net get ivrm
use "pain.dta", clear

/* (1) Automated Polynomial Contrasts */
regress pain i.dosegrp
contrast p.dosegrp, noeffects

/* (2) Slightly More Manual With User-Defined Contrasts on the levels of dosegrp */
contrast {dosegrp -5  -3  -1   1   3   5}  ///
{dosegrp  5  -1  -4  -4  -1   5}  ///
{dosegrp -5   7   4  -4  -7   5}  ///
{dosegrp  1  -3   2   2  -3   1}  ///
{dosegrp -1   5 -10  10  -5   1}  ///
{dosegrp -1   5 -10  10  -5   1}, noeffects

/* (3) Regression method where Stata creates the varibles for you */
orthpoly dosegrp, deg(5) generate(op*)
regress pain op*
test op1 // linear
test op3 // cubic
test op4 // quartic
test op5 // quintic
test op1 op2 op3 op4 op5 // joint

/* (4) Very Manual Way Using Regression Where You Hard Code Everything */
forvalues i=1/5 {
gen oi' = .
}

replace o1 = -5 if dosegrp == 1
replace o2 =  5 if dosegrp == 1
replace o3 = -5 if dosegrp == 1
replace o4 =  1 if dosegrp == 1
replace o5 = -1 if dosegrp == 1

replace o1 = -3 if dosegrp == 2
replace o2 = -1 if dosegrp == 2
replace o3 =  7 if dosegrp == 2
replace o4 = -3 if dosegrp == 2
replace o5 =  5 if dosegrp == 2

replace o1 =  -1 if dosegrp == 3
replace o2 =  -4 if dosegrp == 3
replace o3 =   4 if dosegrp == 3
replace o4 =   2 if dosegrp == 3
replace o5 = -10 if dosegrp == 3

replace o1 =  1 if dosegrp == 4
replace o2 = -4 if dosegrp == 4
replace o3 = -4 if dosegrp == 4
replace o4 =  2 if dosegrp == 4
replace o5 = 10 if dosegrp == 4

replace o1 =  3 if dosegrp == 5
replace o2 = -1 if dosegrp == 5
replace o3 = -7 if dosegrp == 5
replace o4 = -3 if dosegrp == 5
replace o5 = -5 if dosegrp == 5

replace o1 = 5 if dosegrp == 6
replace o2 = 5 if dosegrp == 6
replace o3 = 5 if dosegrp == 6
replace o4 = 1 if dosegrp == 6
replace o5 = 1 if dosegrp == 6

tw connected o1 dosegrp, sort
tw connected o2 dosegrp, sort
tw connected o3 dosegrp, sort
tw connected o4 dosegrp, sort
tw connected o5 dosegrp, sort

reg pain o1 o2 o3 o4 o5
test o1 // linear
`