Search code examples
rggplot2sjplot

How can I change the order of facets in plot_model without changing the underlying data?


I have a predicted marginal effects plot made with plot_model from sjPlot, displaying the predictions at selected levels of the variable height which I named to clarify they are -1 SD, mean, and +1 SD, respectively. Unfortunately, due to alphabetical ordering, when height includes both negative and positive values and the mean is a negative value closer to zero than -1 SD, the facets will not be ordered in the way listed before. Thus, I have to reorder them somehow. Since height is actually numeric and I only manually selected specific values of height to display in the plot, I don't see that I could achieve this by reordering the underlying data, since the variable is not a factor. Except maybe converting it to a factor and reordering all the levels? But I hope there's a more convenient solution that doesn't require modifying the underlying data.

library(dplyr)
library(sjPlot)

#specifying the model
model = lm(mass ~ gender*species*height, data = starwars[starwars$species == "Human" | starwars$species == "Droid" | starwars$species == "Twi'lek",])

#plotting predictions at three specified levels of height, let's pretend they're -1 SD, mean and +1 #SD
plot = plot_model(model, type = "pred", terms = c("species", "gender", "height [-2, -1, 1]"), ci.lvl=0.95) 


#renaming facets to specify that they represent -1 SD, mean, and +1 SD
plot$data$facet <- ifelse(plot$data$facet == "height = -2", "height = -2 (-1 SD)",
                             ifelse(plot$data$facet == "height = -1", "height = -1 (mean)",
                                    ifelse(plot$data$facet == "height = 1", "height = 1 (+1 SD)",  99)))

That's what the plot currently looks like:


Solution

  • You can do this by making the facet variable in the data a factor with the levels in the order you want.

    library(dplyr)
    library(sjPlot)
    
    #specifying the model
    model = lm(mass ~ gender*species*height, data = starwars[starwars$species == "Human" | starwars$species == "Droid" | starwars$species == "Twi'lek",])
    
    #plotting predictions at three specified levels of height, let's pretend they're -1 SD, mean and +1 #SD
    plot = plot_model(model, type = "pred", terms = c("species", "gender", "height [-2, -1, 1]"), ci.lvl=0.95) 
    #> Warning in predict.lm(model, newdata = data_grid, type = "response", se.fit =
    #> se, : prediction from rank-deficient fit; attr(*, "non-estim") has doubtful
    #> cases
    
    plot$data$facet <- factor(case_when(
      plot$data$facet == "height = -2" ~ "height = -2 (-1 SD)", 
      plot$data$facet == "height = -1" ~ "height = -1 (mean)", 
      plot$data$facet == "height = 1" ~ "height = 1 (+1 SD)", 
    ), levels=c("height = -2 (-1 SD)", "height = -1 (mean)", "height = 1 (+1 SD)"))
    
    plot
    

    Created on 2023-06-22 with reprex v2.0.2