```
library(palmerpenguins) # penguins data
library(car) # Type 3 anova
library(marginaleffects) # Exploring interactions
library(ggplot2)
```

# Interpreting interactions

Creating models and checking their assumptions are the first steps to running an analysis, but once you have a beautiful, valid model, what next?

Interpreting models can be tricky as some results aren’t intuitive (i.e. often interactions, or non-Gaussian models), and to get the most out of your model, you’ll want to understand both what parameters are important (or significant), as well as *how* they are important (effects size and direction).

You may also want to run a post-hoc analysis to dive deeper into the effects of categorical predictors.

Here we’ll take a quick look at interactions.

### Interpreting Interactions

Let’s see if there is an interaction between flipper length and bill depth on bill length. This may not be a terribly sensible example (and note that we’re skipping the all important step of checking our model!), but it should hopefully illustrate these tools.

First let’s create a linear model.

`m <- lm(bill_length_mm ~ flipper_length_mm * bill_depth_mm, data = penguins)`

We can explore the results by looking at the `summary()`

table

`summary(m)`

```
Call:
lm(formula = bill_length_mm ~ flipper_length_mm * bill_depth_mm,
data = penguins)
Residuals:
Min 1Q Median 3Q Max
-10.6952 -2.5439 -0.2036 2.4788 19.9132
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 72.14404 49.77162 1.450 0.1481
flipper_length_mm -0.18476 0.24265 -0.761 0.4469
bill_depth_mm -5.31449 2.93076 -1.813 0.0707 .
flipper_length_mm:bill_depth_mm 0.02917 0.01439 2.027 0.0434 *
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Residual standard error: 3.991 on 338 degrees of freedom
(2 observations deleted due to missingness)
Multiple R-squared: 0.4703, Adjusted R-squared: 0.4656
F-statistic: 100 on 3 and 338 DF, p-value: < 2.2e-16
```

Or with an `Anova()`

table (here, from the car package, so we can get type III)

`Anova(m, type = "III")`

```
Anova Table (Type III tests)
Response: bill_length_mm
Sum Sq Df F value Pr(>F)
(Intercept) 33.5 1 2.1011 0.14812
flipper_length_mm 9.2 1 0.5798 0.44694
bill_depth_mm 52.4 1 3.2882 0.07067 .
flipper_length_mm:bill_depth_mm 65.5 1 4.1103 0.04341 *
Residuals 5384.2 338
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
```

Okay, in our standard interpretation, we would say that yes, there is an interaction (p = 0.043).

With continuous variables, the summary table is often a bit more informative, as we can interpret the estimates. In this case, we can interpret the interaction as: for every 1 mm increase in flipper length, the effect of a 1 mm increase on bill depth increases by 0.029.

Hmm, not incredibly intuitive!

The marginalmeans package can be used to explore models with interactions via “conditional marginal effects” and predictions

#### Conditional marginal effects

These are really nice way of visualizing the verbal interpretation we made above.

We’ll use the `plot_slopes()`

function to plot the effect of one variable on the slope of the other (i.e. an interaction!).

Here, we look at the effect of bill depth on the slope of flipper length (i.e. the effect of flipper length on our response, bill length).

The Y-axis represents the slope of the effect of flipper length on bill depth.

```
plot_slopes(m, variables = "flipper_length_mm", condition = "bill_depth_mm") +
theme_minimal() +
labs(y = "Slope of flipper length")
```

This figure is a visualization of our interaction parameter, but also puts things into the proper context and includes confidence intervals!

Here we see that a) the slope is always positive, b) becomes stronger for increasing bill depth.

### Plotting predictions

We can plot the predictions to get a visual of this interaction.

```
plot_predictions(m, condition = list("flipper_length_mm", "bill_depth_mm"),
point = 0.5)
```

Here we can see the various lines (slopes) representing the effect of flipper length on bill length across different bill depths. We see that the effect (slope) increases as bill depth increases (compare the line with bill depth at 21.5 to the one with bill depth at 13.1). This is another visual representation of what we stated above, with additional context. In addition to seeing that all the slopes are positive, and the changes make them stronger, we see this in relation to the original data.

I find this kind of plot useful for sharing your results as it shows the raw data along with the model results and a clear explanation of what that interaction really means.

### Conclusions

Interpreting interactions can be much simpler with visual aids, and it’s a good idea to use these figures not only for your benefit but for the benefit of anyone you’re sharing your work with.

You can make these figures by hand, but using marginalmeans will make it much easier (if slightly less customizable).

### Further Reading

- https://vincentarelbundock.github.io/marginaleffects/
- https://www.andrewheiss.com/blog/2022/05/20/marginalia/#tldr-overall-summary-of-all-these-marginal-effects-approaches

### Session Info

`devtools::session_info()`

```
─ Session info ───────────────────────────────────────────────────────────────
setting value
version R version 4.3.1 (2023-06-16)
os Ubuntu 22.04.3 LTS
system x86_64, linux-gnu
ui X11
language en_CA:en
collate en_CA.UTF-8
ctype en_CA.UTF-8
tz America/Winnipeg
date 2023-09-04
pandoc 3.1.1 @ /usr/lib/rstudio/resources/app/bin/quarto/bin/tools/ (via rmarkdown)
─ Packages ───────────────────────────────────────────────────────────────────
package * version date (UTC) lib source
abind 1.4-5 2016-07-21 [1] CRAN (R 4.3.0)
backports 1.4.1 2021-12-13 [1] CRAN (R 4.3.0)
cachem 1.0.8 2023-05-01 [1] CRAN (R 4.3.0)
callr 3.7.3 2022-11-02 [1] CRAN (R 4.3.0)
car * 3.1-2 2023-03-30 [1] CRAN (R 4.3.0)
carData * 3.0-5 2022-01-06 [1] CRAN (R 4.3.0)
checkmate 2.2.0 2023-04-27 [1] CRAN (R 4.3.0)
cli 3.6.1 2023-03-23 [1] CRAN (R 4.3.0)
colorspace 2.1-0 2023-01-23 [1] CRAN (R 4.3.0)
crayon 1.5.2 2022-09-29 [1] CRAN (R 4.3.0)
data.table 1.14.8 2023-02-17 [1] CRAN (R 4.3.0)
devtools 2.4.5 2022-10-11 [1] CRAN (R 4.3.0)
digest 0.6.31 2022-12-11 [1] CRAN (R 4.3.0)
dplyr 1.1.2 2023-04-20 [1] CRAN (R 4.3.0)
ellipsis 0.3.2 2021-04-29 [1] CRAN (R 4.3.0)
evaluate 0.20 2023-01-17 [1] CRAN (R 4.3.0)
fansi 1.0.4 2023-01-22 [1] CRAN (R 4.3.0)
farver 2.1.1 2022-07-06 [1] CRAN (R 4.3.0)
fastmap 1.1.1 2023-02-24 [1] CRAN (R 4.3.0)
fs 1.6.2 2023-04-25 [1] CRAN (R 4.3.0)
generics 0.1.3 2022-07-05 [1] CRAN (R 4.3.0)
ggplot2 * 3.4.2 2023-04-03 [1] CRAN (R 4.3.0)
glue 1.6.2 2022-02-24 [1] CRAN (R 4.3.0)
gtable 0.3.3 2023-03-21 [1] CRAN (R 4.3.0)
htmltools 0.5.5 2023-03-23 [1] CRAN (R 4.3.0)
htmlwidgets 1.6.2 2023-03-17 [1] CRAN (R 4.3.0)
httpuv 1.6.9 2023-02-14 [1] CRAN (R 4.3.0)
insight 0.19.2 2023-05-23 [1] CRAN (R 4.3.0)
jsonlite 1.8.4 2022-12-06 [1] CRAN (R 4.3.0)
knitr 1.42 2023-01-25 [1] CRAN (R 4.3.0)
labeling 0.4.2 2020-10-20 [1] CRAN (R 4.3.0)
later 1.3.0 2021-08-18 [1] CRAN (R 4.3.0)
lifecycle 1.0.3 2022-10-07 [1] CRAN (R 4.3.0)
magrittr 2.0.3 2022-03-30 [1] CRAN (R 4.3.0)
marginaleffects * 0.12.0 2023-05-20 [1] CRAN (R 4.3.0)
memoise 2.0.1 2021-11-26 [1] CRAN (R 4.3.0)
mime 0.12 2021-09-28 [1] CRAN (R 4.3.0)
miniUI 0.1.1.1 2018-05-18 [1] CRAN (R 4.3.0)
munsell 0.5.0 2018-06-12 [1] CRAN (R 4.3.0)
palmerpenguins * 0.1.1 2022-08-15 [1] CRAN (R 4.3.0)
pillar 1.9.0 2023-03-22 [1] CRAN (R 4.3.0)
pkgbuild 1.4.0 2022-11-27 [1] CRAN (R 4.3.0)
pkgconfig 2.0.3 2019-09-22 [1] CRAN (R 4.3.0)
pkgload 1.3.2 2022-11-16 [1] CRAN (R 4.3.0)
prettyunits 1.1.1 2020-01-24 [1] CRAN (R 4.3.0)
processx 3.8.1 2023-04-18 [1] CRAN (R 4.3.0)
profvis 0.3.7 2020-11-02 [1] CRAN (R 4.3.0)
promises 1.2.0.1 2021-02-11 [1] CRAN (R 4.3.0)
ps 1.7.5 2023-04-18 [1] CRAN (R 4.3.0)
purrr 1.0.1 2023-01-10 [1] CRAN (R 4.3.0)
R6 2.5.1 2021-08-19 [1] CRAN (R 4.3.0)
Rcpp 1.0.10 2023-01-22 [1] CRAN (R 4.3.0)
remotes 2.4.2 2021-11-30 [1] CRAN (R 4.3.0)
rlang 1.1.1 2023-04-28 [1] CRAN (R 4.3.0)
rmarkdown 2.21 2023-03-26 [1] CRAN (R 4.3.0)
rstudioapi 0.14 2022-08-22 [1] CRAN (R 4.3.0)
scales 1.2.1 2022-08-20 [1] CRAN (R 4.3.0)
sessioninfo 1.2.2 2021-12-06 [1] CRAN (R 4.3.0)
shiny 1.7.4 2022-12-15 [1] CRAN (R 4.3.0)
stringi 1.7.12 2023-01-11 [1] CRAN (R 4.3.0)
stringr 1.5.0 2022-12-02 [1] CRAN (R 4.3.0)
tibble 3.2.1 2023-03-20 [1] CRAN (R 4.3.0)
tidyselect 1.2.0 2022-10-10 [1] CRAN (R 4.3.0)
urlchecker 1.0.1 2021-11-30 [1] CRAN (R 4.3.0)
usethis 2.2.0 2023-06-06 [1] CRAN (R 4.3.0)
utf8 1.2.3 2023-01-31 [1] CRAN (R 4.3.0)
vctrs 0.6.2 2023-04-19 [1] CRAN (R 4.3.0)
withr 2.5.0 2022-03-03 [1] CRAN (R 4.3.0)
xfun 0.39 2023-04-20 [1] CRAN (R 4.3.0)
xtable 1.8-4 2019-04-21 [1] CRAN (R 4.3.0)
yaml 2.3.7 2023-01-23 [1] CRAN (R 4.3.0)
[1] /home/steffi/R/x86_64-pc-linux-gnu-library/4.3
[2] /usr/local/lib/R/site-library
[3] /usr/lib/R/site-library
[4] /usr/lib/R/library
──────────────────────────────────────────────────────────────────────────────
```