1 Required libraries

library(sjPlot)
library(ggplot2)

2 Prepare the dataset

data(mtcars)
set.seed(123)

df <- mtcars

# Create binary variables
df$manual <- as.factor(df$am)
levels(df$manual) <- c("Automatic", "Manual")

df$heavy <- as.factor(df$wt > median(df$wt))
levels(df$heavy) <- c("Light", "Heavy")

# Create categorical variable (3 levels) based on cylinders
df$cyl_cat <- as.factor(df$cyl)
levels(df$cyl_cat) <- c("Four", "Six", "Eight")

# Center numeric variables for interaction
df$hp_c <- as.numeric(scale(df$hp, center = TRUE, scale = FALSE))
df$disp_c <- as.numeric(scale(df$disp, center = TRUE, scale = FALSE))

3 Regression Models

This tutorial demonstrates different types of moderation analyses using R. We’ll use the modified mtcars dataset to explore four different types of interactions:

Model 1: Basic OLS Model

\(mpg \sim manual + heavy\)

model1 <- lm(mpg ~ manual + heavy, data = df)

Model 2: Binary × Binary Interaction

\(mpg \sim manual \times heavy\)

This model examines how the effect of transmission type on fuel efficiency is moderated by vehicle weight category.

model2 <- lm(mpg ~ manual * heavy, data = df)

Model 3: Categorical × Numeric Interaction

\(mpg \sim hp_c \times cyl\_cat\)

This model explores how the effect of horsepower on fuel efficiency is moderated by the number of cylinders.

model3 <- lm(mpg ~ hp_c * cyl_cat, data = df)

Model 4: Numeric × Numeric Interaction

\(mpg \sim hp_c \times disp_c\)

This model investigates how the effect of horsepower on fuel efficiency is moderated by engine displacement.

model4 <- lm(mpg ~ hp_c * disp_c, data = df)

4 Combined Regression Table

tab_model(model1, model2, model3, model4,
          show.ci = FALSE,
          show.se = TRUE,
          collapse.se = TRUE,  # Put SE below estimates in parentheses
          show.p = FALSE,
          p.style = "stars",
          emph.p = TRUE,
          string.pred = "Predictor",
          string.est = "Estimate",
          show.stat = FALSE,
          show.re.var = FALSE,
          show.intercept = TRUE,
          dv.labels = c("Basic", "Binary×Binary", 
                       "Cat×Num", "Num×Num"),
          title = "Comparison of Moderation Models")
Comparison of Moderation Models
  Basic Binary×Binary Cat×Num Num×Num
Predictor Estimate Estimate Estimate Estimate
(Intercept) 23.13 ***
(1.86)
22.52 ***
(2.07)
19.44 ***
(3.07)
18.20 ***
(0.74)
manual [Manual] 1.85
(2.06)
2.65
(2.39)
heavy [Heavy] -7.57 ***
(2.03)
-6.81 **
(2.33)
manual [Manual] × heavy
[Heavy]
-3.36
(4.89)
hp c -0.11 *
(0.05)
-0.03 *
(0.01)
cyl cat [Six] 0.12
(3.50)
cyl cat [Eight] -3.45
(3.34)
hp c × cyl cat [Six] 0.11
(0.07)
hp c × cyl cat [Eight] 0.10
(0.05)
disp c -0.03 ***
(0.01)
hp c × disp c 0.00 **
(0.00)
Observations 32 32 32 32
R2 / R2 adjusted 0.568 / 0.538 0.575 / 0.529 0.788 / 0.748 0.820 / 0.801
  • p<0.05   ** p<0.01   *** p<0.001

In Model 1 (Basic), we observe that both transmission type and vehicle weight significantly influence fuel efficiency (MPG). Specifically, manual transmission vehicles achieve 1.85 more MPG compared to automatic ones, though this difference is not statistically significant. Heavy vehicles consume significantly more fuel, showing 7.57 fewer MPG compared to lighter vehicles (p < 0.001). The model explains about 57% of the variance in fuel efficiency (R² = 0.568).

In Model 1, the intercept of 23.13 MPG represents the predicted fuel efficiency for a vehicle with the reference (baseline) characteristics - specifically, a light vehicle (not heavy) with automatic transmission (not manual). This baseline value is statistically significant (p < 0.001) as indicated by the three asterisks, and has a standard error of 1.86. This means that we would expect an automatic, light vehicle to achieve approximately 23.13 miles per gallon, all else being equal. This value serves as the starting point from which we can then calculate expected MPG values for other combinations of transmission and weight by adding or subtracting the respective coefficients.

In Model 2 (Binary×Binary), the interaction between transmission type and vehicle weight reveals an interesting pattern. Manual transmission vehicles generally achieve 2.65 more MPG than automatic ones, while heavy vehicles consume 6.81 more MPG than lighter ones (p < 0.01). The interaction term (-3.36) suggests that the fuel efficiency advantage of manual transmission is reduced in heavy vehicles, though this interaction effect is not statistically significant. The model’s explanatory power is similar to the basic model, with an R² of 0.575.

In Model 2, the intercept of 22.52 MPG represents the predicted fuel efficiency for a vehicle with the reference (baseline) characteristics in this interaction model - specifically, a light vehicle with automatic transmission. Like in Model 1, this is statistically significant (p < 0.01) with a standard error of 2.07. However, the interpretation in Model 2 needs to be considered alongside the interaction term. The intercept represents the baseline MPG when both categorical variables are at their reference levels (automatic transmission and light weight), but any predictions for other combinations of transmission and weight must take into account not only the main effects (2.65 for manual and -6.81 for heavy) but also the interaction term (-3.36). This means that the effect of changing transmission type depends on the weight category, and vice versa, making the interpretation more complex than in Model 1.

In Model 3 (Cat×Num), we examine how the relationship between horsepower and fuel efficiency varies across different cylinder categories. For each unit increase in horsepower, fuel efficiency decreases by 0.11 MPG (p < 0.05). Six-cylinder vehicles show slightly better fuel efficiency (0.12 MPG) compared to four-cylinder ones, while eight-cylinder vehicles consume more fuel (-3.45 MPG), though these differences are not statistically significant. The interaction terms (0.11 for Six cylinders and 0.10 for Eight cylinders) suggest that the negative effect of horsepower on fuel efficiency is slightly mitigated in vehicles with more cylinders. This model explains substantially more variance than the previous models (R² = 0.788).

In Model 4 (Num×Num), we investigate the interaction between horsepower and engine displacement. Both horsepower and displacement individually show significant negative effects on fuel efficiency (-0.03 MPG per unit increase in displacement, p < 0.001; -0.03 MPG per unit increase in horsepower, p < 0.05). The significant interaction term (0.00, p < 0.01) suggests a very slight moderating effect where the negative impact of horsepower on fuel efficiency is marginally reduced as displacement increases. This model explains the highest proportion of variance in fuel efficiency (R² = 0.820), indicating it provides the best fit among all four models.

5 Combined Coefficient Plot

plot_models(model1, model2, model3, model4,
           grid = FALSE,
           axis.labels = c("Manual × Heavy",
                          "Heavy (vs Light)",
                          "Manual (vs Auto)",
                          "hp_c × disp_c",
                          "disp_c",
                          "hp_c",
                          "hp_c × Eight",
                          "hp_c × Six",
                          "Eight (vs Four)",
                          "Six (vs Four)"),
           vline.color = "black",
           legend.title = "Models",
           m.labels = c("Basic", "Binary×Binary", 
                       "Cat×Num", "Num×Num")) +
  theme_minimal() +
  theme(panel.grid.minor = element_blank(),
        plot.title = element_text(hjust = 0, size = 11),
        legend.position = "top",
        axis.text = element_text(color = "black"),
        axis.title = element_text(color = "black"),
        panel.border = element_rect(color = "black", fill = NA))

6 Interaction Plots

6.1 Binary × Binary Interaction

Using effects

# Calculate the effect
effect_plot <- effects::effect("manual:heavy", model2, 
                               xlevels = list(manual = levels(df$manual),
                                              heavy = levels(df$heavy)))

# Convert effects object to data frame
effect_df <- as.data.frame(effect_plot)

# Create ggplot
p <- ggplot(effect_df, aes(x = manual, y = fit, color = heavy)) +
  geom_point(position = position_dodge(width = 0.1)) +
  geom_line(aes(group = heavy), position = position_dodge(width = 0.1)) +
  geom_errorbar(aes(ymin = lower, ymax = upper), 
                width = 0.1, 
                position = position_dodge(width = 0.1)) +
  labs(title = "Interaction between Transmission and Weight",
       x = "Transmission Type",
       y = "Miles per Gallon",
       color = "heavy") +
  theme_bw()

p

Using sjPlot

plot_model(model2, type = "int", 
          line.plot = TRUE,
          ci.lvl = 0.95,
          axis.title = c("Transmission Type", "Miles per Gallon"),
          title = "Predicted MPG by Transmission and Weight (sjPlot)",
          colors = c("#00BFC4", "#F8766D"),
          show.legend = TRUE,
          grid = FALSE) +
  theme_minimal() +
  theme(panel.grid.minor = element_blank(),
        plot.title = element_text(hjust = 0, size = 11),
        legend.position = "right",
        axis.text = element_text(color = "black"),
        axis.title = element_text(color = "black"),
        panel.border = element_rect(color = "black", fill = NA))

6.2 Categorical × Numeric Interaction

plot_model(model3, type = "pred", 
          terms = c("hp_c", "cyl_cat"),
          title = "Interaction between Horsepower and Cylinders") +
  theme_minimal() +
  theme(panel.grid.minor = element_blank(),
        plot.title = element_text(hjust = 0, size = 11),
        legend.position = "right",
        axis.text = element_text(color = "black"),
        axis.title = element_text(color = "black"),
        panel.border = element_rect(color = "black", fill = NA))

6.3 Numeric × Numeric Interaction

plot_model(model4, type = "int",
           title = "Interaction between Horsepower and Displacement") +
  theme_minimal() +
  theme(panel.grid.minor = element_blank(),
        plot.title = element_text(hjust = 0, size = 11),
        legend.position = "right",
        axis.text = element_text(color = "black"),
        axis.title = element_text(color = "black"),
        panel.border = element_rect(color = "black", fill = NA))

7 Interpretation

  1. In the basic model, we see the independent effects of transmission type and weight category on fuel efficiency.

  2. The binary-binary interaction reveals how the effect of transmission type on MPG differs between light and heavy cars.

  3. The categorical-numeric interaction shows how the relationship between horsepower and MPG varies across different cylinder categories.

  4. The numeric-numeric interaction demonstrates how the effect of horsepower on MPG changes at different levels of engine displacement.

Key findings can be observed from both the coefficient plots and interaction plots, allowing for a comprehensive understanding of the moderation effects in our models.