Search code examples
rggplot2interaction

R, ggplot2, jtools: How to amend three-way Johnson-Neyman interaction chart


I have a three-way interaction that I am probing using Johnson-Neyman analysis in the jtools package. I have generated a plot (which uses ggplot2) and am trying to amend parts of the plot. I have succeeded in amending some parts but not others.

Here is what I would like to amend:

1) I am trying to specify a vertical line separately for each chart (at the moment my code places the line at xintercept=0.403 on both charts); and

2) I am trying to remove the box/borders surrounding the headings for each chart (which currently read "Low M" and "High M"). To be clear, I want to remove the box/border whilst retaining the labels.

#Import data.
df <- structure(list(Y_Variable = c(1, 2, 1, 1.8, 1, 1, NA, 2, 1, 1, 
                                    3.2, 1, 3, 4.2, 2, 1.8, 1, 3.6, 1, 5.4, 1, 2, 1, 1.4, 1, 1, 1.4, 
                                    1, 1, 1, 1, 1, 1, 1, 3.8, 2.2, 1, 3.2, 1, 2.8, 4, 3.6, 1, 1, 
                                    3.4, 1, 2, 4, 1, 2.4, NA, 1, 2.6, 1, 1, 1, 1, 3.4, 1.4, 1, 4, 
                                    2.6, 2, NA, 4, 1, 3, 3.2, 1, 4.6, 1, 1.2, 3, 1, 1.2, NA, 1, 2.6, 
                                    2.6, 1, 1, 3.8, 1, 1, 4.8, 1.8, 1, 2, 4.4, 1, 1.8, 4.2, 2.4, 
                                    3.4, 1.6, 1, 2.8, 1, 4.6, 1.2, 3.4, 2.2, 3.4, 1, 2.2, 5.2, 2.6, 
                                    1, 2.8, 1, 3, 3.2, 3, 2.2, 3, 1, 3, 2, 1, 1, 1.6, 1, 1.2, 1, 
                                    3.2, 1.8, 1.4, 1, 1, 1.8, 2.8, 1, 2, NA, 1, 2.6, 2.6, 1, 4.6, 
                                    3.8, 3.2, 1, 2.5, 1, 1, 7, 2, 2.2, 2.2, 2),
                     X_Variable = c(-0.229752333333333,0.186914333333334, -0.729752333333333, 0.936914333333334, -0.479752333333333, 
                                    -1.646419, 0.770247666666667, -0.729752333333333, -0.729752333333333, 
                                    -0.646419, 0.103581, 0.853581, -0.313085666666666, 0.936914333333334, 
                                    0.603581, 0.103581, 1.27024766666667, 0.436914333333334, -1.22975233333333, 
                                    1.27024766666667, -1.06308566666667, -1.56308566666667, -0.229752333333333, 
                                    0.270247666666667, -0.979752333333333, -1.146419, -0.563085666666666, 
                                    1.103581, -0.229752333333333, 0.353581, -1.81308566666667, 0.520247666666667, 
                                    -1.81308566666667, 0.270247666666667, 1.52024766666667, 0.770247666666667, 
                                    -0.813085666666666, 0.103581, -0.646419, 0.103581, 1.28539918181818, 
                                    1.18691433333333, -1.31308566666667, 0.353581, 0.353581, 1.18691433333333, 
                                    -0.896419, 1.603581, 0.103581, 0.186914333333334, -0.313085666666666, 
                                    -1.72975233333333, 0.603581, -0.563085666666666, -0.0630856666666664, 
                                    0.376308272727273, 0.103581, 0.936914333333334, -1.06308566666667, 
                                    -1.31308566666667, 1.103581, 1.93691433333333, 1.603581, 1.27024766666667, 
                                    0.603581, -0.563085666666666, 2.27024766666667, 2.68691433333333, 
                                    -0.729752333333333, 1.46721736363636, -0.396419, 0.353581, 1.103581, 
                                    -0.896419, -0.729752333333333, 0.686914333333334, -1.896419, 
                                    0.436914333333334, 1.18691433333333, -1.396419, -0.396419, 0.686914333333334, 
                                    -0.146419, -0.979752333333333, 0.270247666666667, -1.146419, 
                                    -0.0630856666666664, 3.18691433333333, 0.186914333333334, -0.896419, 
                                    -0.979752333333333, 1.68691433333333, 2.02024766666667, 0.270247666666667, 
                                    0.520247666666667, -1.47975233333333, 1.103581, 1.103581, 1.43691433333333, 
                                    -0.396419, 0.770247666666667, 0.103581, -0.729752333333333, 0.270247666666667, 
                                    0.520247666666667, 0.186914333333334, 0.853581, -0.813085666666666, 
                                    -0.313085666666666, -0.350964454545454, 0.270247666666667, -0.396419, 
                                    0.853581, 0.353581, 1.52024766666667, -0.813085666666666, -0.146419, 
                                    -1.06308566666667, -1.81308566666667, -1.31308566666667, 0.0202476666666667, 
                                    1.02024766666667, -1.22975233333333, -1.22975233333333, -0.146419, 
                                    -0.896419, -1.56308566666667, -1.396419, 0.853581, -0.313085666666666, 
                                    -0.563085666666666, -0.563085666666666, 0.270247666666667, -0.896419, 
                                    -0.813085666666666, 0.603581, 0.353581, 0.853581, 2.103581, 1.103581, 
                                    0.103581, -1.22975233333333, 0.830853727272727, 0.270247666666667, 
                                    0.603581, 2.27024766666667, -0.313085666666666, -0.479752333333333, 
                                    0.353581, 1.46721736363636),
                     Z_Variable = c(0.206736, -0.593264,1.006736, -3.793264, 2.006736, 1.006736, 0.00673600000000008, 
                                    1.006736, -0.393264, 0.406736, 0.206736, -0.993264, 0.00673600000000008, 
                                    -1.993264, 0.406736, 1.006736, -3.993264, -0.393264, 1.406736, 
                                    -2.793264, 1.006736, 2.006736, 0.00673600000000008, -0.993264, 
                                    2.006736, 1.206736, 1.006736, -0.193264, 2.006736, 1.006736, 
                                    1.206736, -1.193264, 1.006736, 0.406736, -0.993264, 0.606736, 
                                    1.006736, 0.00673600000000008, 0.606736, 0.806736, 0.406736, 
                                    -0.393264, 2.006736, 1.006736, 0.406736, 0.00673600000000008, 
                                    0.00673600000000008, -2.193264, 0.406736, 0.206736, 1.406736, 
                                    1.006736, 0.00673600000000008, -3.393264, 0.00673600000000008, 
                                    -2.993264, -0.193264, 0.00673600000000008, 1.006736, 1.006736, 
                                    -2.393264, 0.606736, 1.006736, 0.406736, -2.193264, 1.006736, 
                                    -0.793264, -3.393264, 1.006736, 0.506736, -0.793264, 0.406736, 
                                    -1.993264, 0.00673600000000008, -0.993264, -0.593264, 1.006736, 
                                    -0.793264, -3.193264, 1.006736, 0.406736, -1.393264, -1.793264, 
                                    2.006736, 1.206736, 1.006736, -1.393264, -3.993264, -1.793264, 
                                    0.206736, 0.806736, -1.993264, 2.006736, -1.993264, 0.00673600000000008, 
                                    -0.593264, -2.993264, 1.006736, -0.393264, -2.193264, -3.793264, 
                                    -0.593264, 1.006736, 0.406736, -1.193264, -0.993264, -0.193264, 
                                    1.006736, 0.00673600000000008, 1.006736, 0.806736, -3.993264, 
                                    0.206736, -0.393264, -3.393264, 1.206736, 0.606736, -1.393264, 
                                    0.606736, -0.993264, 0.806736, -2.193264, 0.406736, 1.006736, 
                                    1.006736, 1.206736, 1.006736, 1.006736, -0.793264, 1.406736, 
                                    -2.193264, -0.393264, 1.006736, 1.806736, 1.206736, 0.00673600000000008, 
                                    1.006736, 0.406736, -0.593264, 0.00673600000000008, 1.006736, 
                                    0.806736, -0.593264, 2.006736, 1.006736, 0.673402666666667, 1.006736, 
                                    -2.193264, 0.206736, 1.006736),
                     M_Variable = c(-0.102748, -0.602748, 
                                    -0.102748, -1.352748, 1.897252, -0.102748, -1.352748, 1.647252, 
                                    -0.852748, 1.147252, 0.147252, -0.102748, -0.102748, -2.102748, 
                                    -1.352748, 1.647252, -2.602748, -0.102748, -0.102748, 0.147252, 
                                    0.897252, 1.397252, -0.352748, -0.102748, -0.102748, 0.147252, 
                                    0.397252, -0.102748, 0.647252, 0.647252, 0.897252, -2.102748, 
                                    1.147252, 0.647252, -1.602748, -0.352748, -1.602748, -0.102748, 
                                    -0.852748, 0.397252, 1.397252, -3.102748, 2.147252, 0.897252, 
                                    0.897252, 0.397252, -0.102748, -2.102748, -0.352748, -0.102748, 
                                    1.397252, -0.102748, 0.397252, 0.147252, -1.852748, -2.102748, 
                                    -1.602748, 0.147252, 0.397252, 0.647252, -1.102748, 1.397252, 
                                    1.397252, 1.147252, -0.102748, 1.897252, -1.102748, -2.602748, 
                                    -0.602748, 0.397252, -0.102748, -0.602748, -1.102748, -0.102748, 
                                    -1.102748, -0.102748, 0.897252, -0.352748, -1.102748, 0.897252, 
                                    0.647252, -2.352748, -1.352748, 0.897252, 0.397252, -0.102748, 
                                    -0.102748, -3.102748, -2.102748, -1.102748, 1.397252, -1.102748, 
                                    1.897252, -2.352748, -0.102748, -0.102748, -2.102748, -0.102748, 
                                    -1.102748, 0.147252, -2.602748, 0.647252, 1.647252, -0.102748, 
                                    -0.852748, -0.102748, -0.602748, 0.397252, -2.102748, 1.897252, 
                                    1.147252, -0.102748, -0.352748, 0.147252, -0.102748, 0.397252, 
                                    0.147252, -2.102748, -2.102748, -0.102748, 0.897252, -1.602748, 
                                    0.397252, 1.897252, -2.102748, 0.897252, -0.102748, 1.897252, 
                                    -0.602748, 0.397252, -2.102748, 0.397252, -0.102748, 1.897252, 
                                    -1.352748, 0.397252, 0.647252, 0.897252, 0.397252, 0.147252, 
                                    0.397252, 1.897252, 0.397252, 1.397252, 0.897252, -0.352748, 
                                    1.897252, -1.102748, -2.102748, 0.647252)),
                row.names = c(NA,-150L),
                class = "data.frame")

#Set basic inputs.
decimals <- 3
stddev <- 1

#Run model.
lms2 <- lm(Y_Variable~X_Variable*Z_Variable*M_Variable, data=df, na.action=na.exclude)

#Generate Johnson-Neyman plot.
lms2.plot <- interact_plot(lms2, pred="X_Variable", modx="Z_Variable", mod2="M_Variable",
                           x.label="X Label", y.label="Y Label",
                           modxvals=c((mean(df$Z_Variable, na.rm=TRUE)-(sd(df$Z_Variable, na.rm=TRUE)*stddev)),
                                      (mean(df$Z_Variable, na.rm=TRUE)+(sd(df$Z_Variable, na.rm=TRUE)*stddev))),
                           modx.labels=c("Low Z", "High Z"),
                           mod2.values=c((mean(df$M_Variable, na.rm=TRUE)-(sd(df$M_Variable, na.rm=TRUE)*stddev)),
                                         (mean(df$M_Variable, na.rm=TRUE)+(sd(df$M_Variable, na.rm=TRUE)*stddev))),
                           mod2.labels=c("Low M", "High M"),
                           colors=c("#333333", "#999999"),
                           int.width = 0.682, vary.lty=FALSE, interval=TRUE)
lms2.plot <- lms2.plot+
             coord_cartesian(xlim=c(-2.00, 4.00), ylim=c(0.00, 6.00))+
             scale_x_continuous(breaks=seq(-2.00, 4.00, 1.00))+
             scale_y_continuous(breaks=seq(0.00, 6.00, 1.00))+
             theme_classic()+
             theme(legend.title=element_blank(), legend.position="top",
                   panel.grid.major=element_line(colour="grey", size=0.5, 3))
lms2.plot <- lms2.plot+
             geom_vline(xintercept=0.403)
lms2.plot

Solution

  • We start with some parts of your plot, lms2.plot. I used interact_plot from the package interactions, because interact_plot is deprecated in jtools. Should give you the same results.

    lms2.plot <- interact_plot(lms2, pred="X_Variable", modx="Z_Variable", mod2="M_Variable",
                               x.label="X Label", y.label="Y Label",
                               modxvals=c((mean(df$Z_Variable, na.rm=TRUE)-(sd(df$Z_Variable, na.rm=TRUE)*stddev)),
                                          (mean(df$Z_Variable, na.rm=TRUE)+(sd(df$Z_Variable, na.rm=TRUE)*stddev))),
                               modx.labels=c("Low Z", "High Z"),
                               mod2.values=c((mean(df$M_Variable, na.rm=TRUE)-(sd(df$M_Variable, na.rm=TRUE)*stddev)),
                                             (mean(df$M_Variable, na.rm=TRUE)+(sd(df$M_Variable, na.rm=TRUE)*stddev))),
                               mod2.labels=c("Low M", "High M"),
                               colors=c("#333333", "#999999"),
                               int.width = 0.682, vary.lty=FALSE, interval=TRUE)
    lms2.plot <- lms2.plot+
                 coord_cartesian(xlim=c(-2.00, 4.00), ylim=c(0.00, 6.00))+
                 scale_x_continuous(breaks=seq(-2.00, 4.00, 1.00))+
                 scale_y_continuous(breaks=seq(0.00, 6.00, 1.00))
    

    To control where to place the xintercept, you need to create a separate dataframe that contains xintercept and the variable for splitting facet, which is called mod2_group.

    > head(lms2.plot$data)
    # A tibble: 6 x 8
      Y_Variable Z_Variable M_Variable X_Variable  ymax  ymin modx_group mod2_group
           <dbl>      <dbl>      <dbl>      <dbl> <dbl> <dbl> <fct>      <fct>     
    1      0.793      -1.55      -1.34      -1.90  1.17 0.416 Low Z      Low M     
    2      0.832      -1.55      -1.34      -1.85  1.20 0.462 Low Z      Low M     
    

    So we create a dataframe for xintercept and add them

    test <- data.frame(mod2_group=c("Low M","High M"),xintercept=c(1,3))
    lms2.plot + geom_vline(data=test,aes(xintercept=xintercept))
    

    Last part, to remove the borders. Once you use theme_classic(), calls to modify the panel using theme() will not work. Seems like a work around is to define a new classic:

    theme_classic2 <- function(base_size = 12, base_family = ""){
      theme_bw(base_size = base_size, base_family = base_family) %+replace%
        theme(
          legend.title= element_blank(),
          panel.border     = element_blank(),
          axis.line        = element_line(colour = "black"),
          panel.grid.major=element_line(colour="grey", size=0.5, 3),
          panel.grid.major.x = element_blank(),
          panel.grid.major.y = element_blank(),
          panel.grid.minor = element_blank(),
          panel.grid.minor.x = element_blank(),
          panel.grid.minor.y = element_blank(),
          strip.background = element_blank(),
          legend.key       = element_blank()
        )
    }
    

    Now we put them together and plot:

    lms2.plot + 
    geom_vline(data=test,aes(xintercept=xintercept))+
    theme_classic2()
    

    enter image description here