Solved – What statistical test does -contrast- use after regression in Stata

contrastslogisticp-valuestatatrend

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
(quadratic)  |          1        2.93     0.0372
    (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?

Best Answer

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 op2 // quadratic
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 o`i' = .
}

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
test o2 // quadratic
test o3 // cubic
test o4 // quartic
test o5 // quintic
test o1 o2 o3 o4 o5 // joint
Related Question