Function to plot means and confidence intervals for several independent variables

library(tidyverse)
library(ggpubr)

Attaching package: ‘ggpubr’

The following object is masked from ‘package:cowplot’:

    get_legend
library(broom)
calculate_t_ci <- function(.x) {
  t.test(.x, conf.int = TRUE) %>% 
    tidy() %>% 
    select(estimate, conf.low, conf.high)
}

plot_means <- function(.tbl, .resp, ...) {
  vars <- enquos(...)
  
  x <- vars[[1]]
  
  .tbl <- .tbl %>% 
    mutate(across(c(...), as.factor))
  
  ci <- .tbl %>% 
    group_by(...) %>% 
    summarise(calculate_t_ci({{.resp}}), .groups = "keep")
  
  gg <- ggplot(.tbl, aes(x = {{x}}, y = {{.resp}}, color = {{x}})) 
  
  
  if (length(vars) == 2) {
    y <- vars[[2]] 
    gg <- gg + facet_wrap(vars({{y}}), nrow = 1) 
    }
  
  if (length(vars) == 3) {
    y <- vars[[2]] 
    z <- vars[[3]] 
    gg <- gg + facet_wrap(vars({{y}}, {{z}}), nrow = 1) 
  }
  
  if (length(vars) == 4) {
    y <- vars[[2]] 
    z <- vars[[3]] 
    w <- vars[[4]]
    gg <- gg + facet_wrap(vars({{y}}, {{z}}, {{w}}), nrow = 2) 
  }
  
  gg +
    geom_sina(maxwidth = .5) +
    geom_crossbar(data = ci, 
                  aes(y = estimate, ymin= conf.low , ymax = conf.high))
    
}

You need to specify the data set, the response variable and then separate the independent variables by commas.

plot_means(mtcars, mpg, vs)

plot_means(mtcars, mpg, vs, am)

LS0tCnRpdGxlOiAiUGxvdCBtZWFucyIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKRnVuY3Rpb24gdG8gcGxvdCBtZWFucyBhbmQgY29uZmlkZW5jZSBpbnRlcnZhbHMgZm9yIHNldmVyYWwgaW5kZXBlbmRlbnQgdmFyaWFibGVzCgpgYGB7cn0KbGlicmFyeSh0aWR5dmVyc2UpCmxpYnJhcnkoZ2dwdWJyKQpsaWJyYXJ5KGJyb29tKQpgYGAKCmBgYHtyfQpjYWxjdWxhdGVfdF9jaSA8LSBmdW5jdGlvbigueCkgewogIHQudGVzdCgueCwgY29uZi5pbnQgPSBUUlVFKSAlPiUgCiAgICB0aWR5KCkgJT4lIAogICAgc2VsZWN0KGVzdGltYXRlLCBjb25mLmxvdywgY29uZi5oaWdoKQp9CgpwbG90X21lYW5zIDwtIGZ1bmN0aW9uKC50YmwsIC5yZXNwLCAuLi4pIHsKICB2YXJzIDwtIGVucXVvcyguLi4pCiAgCiAgeCA8LSB2YXJzW1sxXV0KICAKICAudGJsIDwtIC50YmwgJT4lIAogICAgdW5ncm91cCgpICU+JSAKICAgIG11dGF0ZShhY3Jvc3MoYyguLi4pLCBhcy5mYWN0b3IpKQogIAogIGNpIDwtIC50YmwgJT4lIAogICAgZ3JvdXBfYnkoLi4uKSAlPiUgCiAgICBzdW1tYXJpc2UoY2FsY3VsYXRlX3RfY2koe3sucmVzcH19KSwgLmdyb3VwcyA9ICJrZWVwIikKICAKICBnZyA8LSBnZ3Bsb3QoLnRibCwgYWVzKHggPSB7e3h9fSwgeSA9IHt7LnJlc3B9fSwgY29sb3IgPSB7e3h9fSkpIAogIAogIAogIGlmIChsZW5ndGgodmFycykgPT0gMikgewogICAgeSA8LSB2YXJzW1syXV0gCiAgICBnZyA8LSBnZyArIGZhY2V0X3dyYXAodmFycyh7e3l9fSksIG5yb3cgPSAxKSAKICAgIH0KICAKICBpZiAobGVuZ3RoKHZhcnMpID09IDMpIHsKICAgIHkgPC0gdmFyc1tbMl1dIAogICAgeiA8LSB2YXJzW1szXV0gCiAgICBnZyA8LSBnZyArIGZhY2V0X3dyYXAodmFycyh7e3l9fSwge3t6fX0pLCBucm93ID0gMSkgCiAgfQogIAogIGlmIChsZW5ndGgodmFycykgPT0gNCkgewogICAgeSA8LSB2YXJzW1syXV0gCiAgICB6IDwtIHZhcnNbWzNdXSAKICAgIHcgPC0gdmFyc1tbNF1dCiAgICBnZyA8LSBnZyArIGZhY2V0X3dyYXAodmFycyh7e3l9fSwge3t6fX0sIHt7d319KSwgbnJvdyA9IDIpIAogIH0KICAKICBnZyArCiAgICBnZW9tX3NpbmEobWF4d2lkdGggPSAuNSkgKwogICAgZ2VvbV9jcm9zc2JhcihkYXRhID0gY2ksIAogICAgICAgICAgICAgICAgICBhZXMoeSA9IGVzdGltYXRlLCB5bWluPSBjb25mLmxvdyAsIHltYXggPSBjb25mLmhpZ2gpKQogICAgCn0KYGBgCgoKCllvdSBuZWVkIHRvIHNwZWNpZnkgdGhlIGRhdGEgc2V0LCB0aGUgcmVzcG9uc2UgdmFyaWFibGUgYW5kIHRoZW4gc2VwYXJhdGUgdGhlIGluZGVwZW5kZW50IHZhcmlhYmxlcyBieSBjb21tYXMuICAKCgpgYGB7cn0KcGxvdF9tZWFucyhtdGNhcnMsIG1wZywgdnMpCmBgYAoKCmBgYHtyfQpwbG90X21lYW5zKG10Y2FycywgbXBnLCB2cywgYW0pCmBgYAoKCg==