Jan
Jan

Reputation: 61

Plotting interaction graph solely based on slope

I'm trying to draw a publication ready graph (ideally with ggplot), based on the results of a structural equation model (semTools) with a latent interaction using the probe2WayMC function. The results of the corresponding wald-test look e.g. like this:

enter image description here

The package also contains a plotting-function yielding the following graph:

enter image description here

However, I want to be able to customize this graph, ideally via ggplot2, to use it for a publication. Does anybody have an idea on how to do that?

Thanks in advance!

Upvotes: 0

Views: 318

Answers (1)

cookesd
cookesd

Reputation: 1336

After looking at the documentation for probe2WayMC you can transorm the plotProbe functionality to ggplot fairly simple. This function should do the trick. It outputs the ggplot version of the graph and the data used to plot it (you can then do any ggplot manipulations on the graph to make your publication ready plot.

# Function to plot #####
make_ggplot_from_res <- function(model_res,xlim=c(0,1)){
  # make slope and intercept matrices dfs to enable merging

  slope_df = data.frame(model_res$SimpleSlope,check.names=F)
  if (is.null(model_res$SimpleIntcept)){
    # set intercepts to 0 if none provided per documentation https://www.rdocumentation.org/packages/semTools/versions/0.5-2/topics/probe2WayMC
    intcept_df = slope_df %>% dplyr::mutate(Intcept = 0)
} else{
  intcept_df = data.frame(model_res$SimpleIntcept,check.names=F)
}
  var_name = colnames(intcept_df)[1] # get the name of the independent variable
  
  # combine the slope and intercept data and make segment endpoints
  plot_df = intcept_df %>% dplyr::select(c(!!var_name,'Intcept')) %>%
    dplyr::left_join(slope_df %>% dplyr::select(c(!!var_name,'Slope')),
              by=var_name) %>%
    # make segment endpoints for geom_segment
    dplyr::mutate(x_start=xlim[1],x_end=xlim[2],
           y_start = Intcept + Slope*x_start,
           y_end = Intcept + Slope*x_end)
  
  # make graph
  g = ggplot(plot_df) +
    geom_segment(mapping=aes(x=x_start,y=y_start,
                             xend=x_end,yend=y_end,linetype=factor(!!sym(var_name),
                                                                   levels=intcept_df[[var_name]])),
                 data=plot_df,color='red') +
    labs(linetype=var_name,y='Dependent Variable',
         x='Independent Variable')
  # return graph and df used to plot
  return(list('graph'=g,'df'=plot_df))
}

Here's a plot using the plotProbe function and the function above using the sample model from the documentation

plotProbe plot enter image description here


### Sample data
dput(res)
# list(SimpleIntcept = structure(c(-1, 0, 1, -0.295017001131069,
#                                  0.0999899491957403, 0.49499689952255, 0.0186534001703637, 0.0128351046903715,
#                                  0.0186533983268727, -15.8157225190391, 7.79034932771136, 26.5365533319171,
#                                  0, 0, 0), .Dim = c(3L, 5L), .Dimnames = list(NULL, c("f2", "Intcept",
#                                                                                       "SE", "Wald", "p"))),
#      SimpleSlope = structure(c(-1, 0, 1, 0.223827421273507,
#                                0.41762342244764, 0.611419423621773, 0.0169660243758487, 0.0136308937056807,
#                                0.0182349913093169, 13.1926853525053, 30.6380074164612, 33.5300090496548,
#                                0, 0, 0), .Dim = c(3L, 5L), .Dimnames = list(NULL, c("f2", "Slope",
#                                                                                     "SE", "Wald", "p"))))

### Call to function and draw plot
graph_and_df = make_ggplot_from_res(res,xlim=c(-1,1))
graph_and_df$graph

Upvotes: 2

Related Questions