margins.des

We often illustrate the implications of a regression model by graphing marginal means or fitted values from the model by levels of one or more predictors. Such graphs illustrate how the response changes as a function of predictors. This is a particularly useful strategy for explaining statistical interactions between independent variables.

Doing so entails creating a design matrix of response values for the independent variables. Software packages generally automate this process. Within R, the emmeans package allows you to set independent variable values, and then it has a few options for how to deal with variables that are not explicitly specified (e.g., proportional weighting, etc.). Stata does effectively the same thing, allowing users to specify values for some variables and imputing values for other variables. In either case, this process is automated, and just fitted values are reported. That is, users generally do not even look at the design matrix.

In the context of catregs, working with the design matrix may be necessary. Multi-category predictors and mathematically linked variables (interaction terms, squared-terms) may need to be adjusted (also true with emmeans). As such, it is good practice to examine the design matrix to ensure that the underlying data depict the patterns you want to illustrate. This is often overlooked.

margins.des makes the generation of such design matrices straightforward. Given a model object, margins.des pulls out the underlying data and sets all independent variables to their means. Users can alter this in two ways. First, users can set levels of independent variables. If multiple variables are listed, their categories are factorially crossed in the design matrix. Second, users can exclude variables from the design matrix. This is intended to be used with factor variables. Users exclude factor variables from the design matrix in this step, and then factors are proportionally weighted in the margins.dat function.

The first application of margins.des creates a design matrix varying the states of “woman.” It sets all covariates to their means by default. If we wanted to vary “woman” but look at only parents, we would use the second margins.des command.

library(catregs)
data("Mize19AH")
m1 <- glm(alcB ~woman*parrole + age + race2 + race3 + race4 + income + ed1 + ed2 + ed3 + ed4,family="binomial",data=Mize19AH)
margins.des(mod=m1,ivs=expand.grid(woman=c(0,1)))
##   woman   parrole      age     race2       race3      race4   income       ed1
## 1     0 0.4534479 28.41653 0.2189459 0.005804504 0.02995124 34.50605 0.1811005
## 2     1 0.4534479 28.41653 0.2189459 0.005804504 0.02995124 34.50605 0.1811005
##         ed2       ed3        ed4
## 1 0.4100302 0.2542373 0.09774785
## 2 0.4100302 0.2542373 0.09774785
margins.des(mod=m1,ivs=expand.grid(woman=c(0,1),parrole=1))
##   woman parrole      age     race2       race3      race4   income       ed1
## 1     0       1 28.41653 0.2189459 0.005804504 0.02995124 34.50605 0.1811005
## 2     1       1 28.41653 0.2189459 0.005804504 0.02995124 34.50605 0.1811005
##         ed2       ed3        ed4
## 1 0.4100302 0.2542373 0.09774785
## 2 0.4100302 0.2542373 0.09774785

Generally when illustrating statistical interaction effects we want to generate fitted values at factorially-crossed levels of independent variables. We use the base R function “expand.grid” inside the “ivs” option to do this. Below is an example for a 2x2 interaction:

margins.des(mod=m1,ivs=expand.grid(woman=c(0,1),parrole=c(0,1)))
##   woman parrole      age     race2       race3      race4   income       ed1
## 1     0       0 28.41653 0.2189459 0.005804504 0.02995124 34.50605 0.1811005
## 2     1       0 28.41653 0.2189459 0.005804504 0.02995124 34.50605 0.1811005
## 3     0       1 28.41653 0.2189459 0.005804504 0.02995124 34.50605 0.1811005
## 4     1       1 28.41653 0.2189459 0.005804504 0.02995124 34.50605 0.1811005
##         ed2       ed3        ed4
## 1 0.4100302 0.2542373 0.09774785
## 2 0.4100302 0.2542373 0.09774785
## 3 0.4100302 0.2542373 0.09774785
## 4 0.4100302 0.2542373 0.09774785

And here is a more complicated design matrix with a continuous variable.

margins.des(mod=m1,ivs=expand.grid(woman=c(0,1),income=seq(0,150,10)))
##    woman income   parrole      age     race2       race3      race4       ed1
## 1      0      0 0.4534479 28.41653 0.2189459 0.005804504 0.02995124 0.1811005
## 2      1      0 0.4534479 28.41653 0.2189459 0.005804504 0.02995124 0.1811005
## 3      0     10 0.4534479 28.41653 0.2189459 0.005804504 0.02995124 0.1811005
## 4      1     10 0.4534479 28.41653 0.2189459 0.005804504 0.02995124 0.1811005
## 5      0     20 0.4534479 28.41653 0.2189459 0.005804504 0.02995124 0.1811005
## 6      1     20 0.4534479 28.41653 0.2189459 0.005804504 0.02995124 0.1811005
## 7      0     30 0.4534479 28.41653 0.2189459 0.005804504 0.02995124 0.1811005
## 8      1     30 0.4534479 28.41653 0.2189459 0.005804504 0.02995124 0.1811005
## 9      0     40 0.4534479 28.41653 0.2189459 0.005804504 0.02995124 0.1811005
## 10     1     40 0.4534479 28.41653 0.2189459 0.005804504 0.02995124 0.1811005
## 11     0     50 0.4534479 28.41653 0.2189459 0.005804504 0.02995124 0.1811005
## 12     1     50 0.4534479 28.41653 0.2189459 0.005804504 0.02995124 0.1811005
## 13     0     60 0.4534479 28.41653 0.2189459 0.005804504 0.02995124 0.1811005
## 14     1     60 0.4534479 28.41653 0.2189459 0.005804504 0.02995124 0.1811005
## 15     0     70 0.4534479 28.41653 0.2189459 0.005804504 0.02995124 0.1811005
## 16     1     70 0.4534479 28.41653 0.2189459 0.005804504 0.02995124 0.1811005
## 17     0     80 0.4534479 28.41653 0.2189459 0.005804504 0.02995124 0.1811005
## 18     1     80 0.4534479 28.41653 0.2189459 0.005804504 0.02995124 0.1811005
## 19     0     90 0.4534479 28.41653 0.2189459 0.005804504 0.02995124 0.1811005
## 20     1     90 0.4534479 28.41653 0.2189459 0.005804504 0.02995124 0.1811005
## 21     0    100 0.4534479 28.41653 0.2189459 0.005804504 0.02995124 0.1811005
## 22     1    100 0.4534479 28.41653 0.2189459 0.005804504 0.02995124 0.1811005
## 23     0    110 0.4534479 28.41653 0.2189459 0.005804504 0.02995124 0.1811005
## 24     1    110 0.4534479 28.41653 0.2189459 0.005804504 0.02995124 0.1811005
## 25     0    120 0.4534479 28.41653 0.2189459 0.005804504 0.02995124 0.1811005
## 26     1    120 0.4534479 28.41653 0.2189459 0.005804504 0.02995124 0.1811005
## 27     0    130 0.4534479 28.41653 0.2189459 0.005804504 0.02995124 0.1811005
## 28     1    130 0.4534479 28.41653 0.2189459 0.005804504 0.02995124 0.1811005
## 29     0    140 0.4534479 28.41653 0.2189459 0.005804504 0.02995124 0.1811005
## 30     1    140 0.4534479 28.41653 0.2189459 0.005804504 0.02995124 0.1811005
## 31     0    150 0.4534479 28.41653 0.2189459 0.005804504 0.02995124 0.1811005
## 32     1    150 0.4534479 28.41653 0.2189459 0.005804504 0.02995124 0.1811005
##          ed2       ed3        ed4
## 1  0.4100302 0.2542373 0.09774785
## 2  0.4100302 0.2542373 0.09774785
## 3  0.4100302 0.2542373 0.09774785
## 4  0.4100302 0.2542373 0.09774785
## 5  0.4100302 0.2542373 0.09774785
## 6  0.4100302 0.2542373 0.09774785
## 7  0.4100302 0.2542373 0.09774785
## 8  0.4100302 0.2542373 0.09774785
## 9  0.4100302 0.2542373 0.09774785
## 10 0.4100302 0.2542373 0.09774785
## 11 0.4100302 0.2542373 0.09774785
## 12 0.4100302 0.2542373 0.09774785
## 13 0.4100302 0.2542373 0.09774785
## 14 0.4100302 0.2542373 0.09774785
## 15 0.4100302 0.2542373 0.09774785
## 16 0.4100302 0.2542373 0.09774785
## 17 0.4100302 0.2542373 0.09774785
## 18 0.4100302 0.2542373 0.09774785
## 19 0.4100302 0.2542373 0.09774785
## 20 0.4100302 0.2542373 0.09774785
## 21 0.4100302 0.2542373 0.09774785
## 22 0.4100302 0.2542373 0.09774785
## 23 0.4100302 0.2542373 0.09774785
## 24 0.4100302 0.2542373 0.09774785
## 25 0.4100302 0.2542373 0.09774785
## 26 0.4100302 0.2542373 0.09774785
## 27 0.4100302 0.2542373 0.09774785
## 28 0.4100302 0.2542373 0.09774785
## 29 0.4100302 0.2542373 0.09774785
## 30 0.4100302 0.2542373 0.09774785
## 31 0.4100302 0.2542373 0.09774785
## 32 0.4100302 0.2542373 0.09774785

In practice, define an object using margins.des. Examine it and alter it as needed. Then generate fitted values using margins.dat.