{"id":16273257,"url":"https://github.com/mattansb/ggggeffects","last_synced_at":"2025-03-19T23:31:36.139Z","repository":{"id":109914768,"uuid":"361411875","full_name":"mattansb/ggggeffects","owner":"mattansb","description":"Geoms and stats for ggeffects","archived":false,"fork":false,"pushed_at":"2021-05-03T04:32:40.000Z","size":1299,"stargazers_count":8,"open_issues_count":1,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-17T12:21:56.399Z","etag":null,"topics":["ggplot2","plotting","rstats"],"latest_commit_sha":null,"homepage":"","language":"R","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mattansb.png","metadata":{"files":{"readme":"README.Rmd","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-04-25T11:39:38.000Z","updated_at":"2024-04-28T17:45:28.000Z","dependencies_parsed_at":null,"dependency_job_id":"b333e5d1-afbb-455e-8f98-f47099a6e2f8","html_url":"https://github.com/mattansb/ggggeffects","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mattansb%2Fggggeffects","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mattansb%2Fggggeffects/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mattansb%2Fggggeffects/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mattansb%2Fggggeffects/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mattansb","download_url":"https://codeload.github.com/mattansb/ggggeffects/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244524930,"owners_count":20466524,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ggplot2","plotting","rstats"],"created_at":"2024-10-10T18:23:26.774Z","updated_at":"2025-03-19T23:31:36.133Z","avatar_url":"https://github.com/mattansb.png","language":"R","funding_links":[],"categories":[],"sub_categories":[],"readme":"---\noutput: \n  github_document:\n    toc: false\n    fig_width: 10.08\n    fig_height: 6\nvignette: \u003e\n  \\usepackage[utf8]{inputenc}\n  %\\VignetteEngine{knitr::rmarkdown}\neditor_options: \n  chunk_output_type: console\n---\n\n\n```{r setup, include=FALSE}\nknitr::opts_chunk$set(echo = TRUE)\n\nlibrary(dplyr)\nlibrary(mgcv)\nset.seed(114433)\n```\n\n# `ggggeffects`\n\nThe goal of `ggggeffects` is to allow for a `ggplot2` syntax for the actual plotting of the data-grid provided by [`ggeffects`](https://strengejacke.github.io/ggeffects).\n\nI built this because I love [`ggeffects`](https://strengejacke.github.io/ggeffects), but I wanted more control over the plotting.\n\n```{r load_ggge}\nlibrary(ggggeffects)\n```\n\n## Installation\n\n```r\n# install.packages(\"remotes\")\nremotes::install_github(\"mattansb/ggggeffects\")\n```\n\n## Examples\n\nFit a model from the `mtcars` data:\n\n```{r mtcars_model}\nfit \u003c- lm(mpg ~ factor(carb) + am + disp + hp, mtcars)\n```\n\n### Full `ggplot2` Customizability\n\n```{r compare}\ngge \u003c- ggpredict(fit, terms = c(\"carb\", \"am\"))\n\n# Compare\nplot(gge)\n\n# To:\nautoplot(gge) +\n  geom_CI_bar() +\n  geom_expected_point()\n```\n\nThe default plot is better looking than the ugly `ggplot2` default, however `ggggeffects` is fully customisable, as would be expected (also note that the `am` is retained as a numeric variable):\n\n```{r custom1}\nam_labeller \u003c- as_labeller(c(\"0\" = \"Automatic\", \"1\" = \"Manual\"))\n\nautoplot(\n  gge, \n  aes(color = factor(am), fill = after_scale(color)),\n  cols = vars(am), \n  labeller = labeller(am = am_labeller)\n) +\n  # Expected + CI\n  geom_CI_bar(type = \"linerange\", color = \"black\", position = position_dodge(0.3)) +\n  geom_expected_point(size = 3, position = position_dodge(0.3)) +\n  # Scales and theme\n  scale_color_brewer(NULL, labels = c(\"Automatic\", \"Manual\"), type = \"qual\") +\n  theme_bw() +\n  labs(x = \"No. Cylinders\", y = \"Miles/Gallon\")\n```\n\nHere is another example, with a continuous variable on x:\n\n```{r custom2}\ngge \u003c- ggpredict(fit, c(\"disp [all]\", \"hp [meansd]\", \"am\"))\n\nautoplot(\n  gge,\n  aes(color = NULL, fill = NULL),\n  rows = vars(hp),\n  labeller = labeller(am = as_labeller(c(\"0\" = \"Automatic\", \"1\" = \"Manual\")),\n                      hp = label_both)\n) +\n  # Expected + CI\n  geom_CI_ribbon(fill = NA, color = \"black\", linetype = \"dashed\") +\n  geom_expected_line() +\n  theme_bw() +\n  labs(y = \"Miles/Gallon\", x = \"Displacement\")\n\nhp_breaks \u003c- setNames(as.numeric(levels(gge$group)), c(\"-sd\", \"mean\", \"+sd\"))\n\n(p \u003c- autoplot(gge, labeller = labeller(am = as_labeller(c(\"0\" = \"Automatic\", \"1\" = \"Manual\")))) +\n    # Expected + CI\n    geom_CI_ribbon() +\n    geom_expected_line() +\n    # Scales and theme\n    scale_color_viridis_c(\"Horsepower\", breaks = hp_breaks,\n                          limits = c(50, 330),\n                          aesthetics = c(\"color\", \"fill\")) +\n    theme_bw() +\n    labs(y = \"Miles/Gallon\", x = \"Displacement\"))\n```\n\n### Adding Raw/Residualized Data\n\nWe can use `layer_fit_data()` to add the raw data to the plot! It's so simple!\n\n```{r with_data}\np + layer_fit_data(shape = 21, color = \"black\")\n```\n\nWe can also create partial residual plots with `layer_fit_data(residuals = TRUE)`:\n\n```{r with_residuals}\np + layer_fit_data(residuals = TRUE, shape = 21, color = \"black\")\n```\n\nWe can even plot them side by side:\n```{r with_both}\np +\n  # Data\n  layer_fit_data(aes(shape = \"Raw\"), \n                 size = 2) +\n  layer_fit_data(aes(shape = \"Residualized\"), residuals = TRUE,\n                 size = 3,\n                 position = position_nudge(x = 10)) +\n  # Scales and theme\n  scale_shape_manual(NULL, values = c(4, 16))\n```\n\nThese can also be used with other stats:\n\n```{r more_stats_geoms, warning=FALSE}\ngge \u003c- ggpredict(fit, terms = c(\"disp [100:500, by = 70]\", \"carb\"))\n\nautoplot(gge, \n         aes(color = as.numeric(levels(carb))[carb],\n             fill = as.numeric(levels(carb))[carb])) + \n  facet_wrap(vars(carb)) + \n  # Expected + CI\n  geom_CI_ribbon() + \n  geom_expected_line() +\n  # Boxplot of partial residuals\n  layer_fit_data(aes(group = interaction(disp, carb)), \n                 residuals = TRUE,\n                 fill = NA, color = \"black\",\n                 geom = \"boxplot\", stat = \"boxplot\") + # \u003c\u003c\u003c\u003c\n  # Scales and theme\n  scale_color_binned(\"No. Carburetors\", aesthetics = c(\"color\", \"fill\"),\n                     breaks = unique(mtcars$carb),\n                     limits = c(0.5, 8.5),\n                     type = \"viridis\", option = \"B\", begin = 0.1,\n                     guide = guide_colorsteps(even.steps = FALSE)) +\n  labs(y = \"Miles/Gallon\", x = \"Displacement\") + \n  theme_ggeffects()\n\n\ngge \u003c- ggpredict(fit, terms = c(\"hp [all]\", \"am\"))\n\nautoplot(gge, aes(color = factor(am), fill = after_scale(color)), \n         cols = vars(am),\n         labeller = labeller(am = as_labeller(c(\"0\" = \"Automatic\", \"1\" = \"Manual\")))) + \n  # Expected\n  geom_expected_line(size = 1) +\n  # Partial residuals\n  layer_fit_data(residuals = TRUE, alpha = 0.6) + \n  # Smoothed line\n  layer_fit_data(residuals = TRUE, \n                 geom = \"line\", stat = \"smooth\",  # \u003c\u003c\u003c\u003c\n                 linetype = \"dashed\", color = \"red\") +\n  # Scales and theme\n  scale_color_brewer(\"Transmission\", type = \"qual\", \n                     labels = c(\"Automatic\", \"Manual\"),\n                     aesthetics = c(\"color\", \"fill\")) +\n  theme_bw() +\n  labs(y = \"Miles/Gallon\", x = \"Horsepower\")\n```\n\n### Raster Plots\n\nWe can also plot bi-variate raster plots:\n\n```{r raster_2Dplot}\nmod \u003c- lm(Volume ~ poly(Girth, 3) * Height, data = trees)\n\ngge \u003c- ggpredict(mod, c(\"Girth [n=25]\", \"Height [n=25]\"))\n\nautoplot(gge, aes(x = Girth, y = Height,\n                  color = NULL, group = NULL, # need to override\n                  fill = predicted)) +\n  # Expected values\n  geom_raster() +\n  geom_contour(aes(z = predicted),\n               color = \"white\") +\n  # Data\n  layer_fit_data(shape = 21, color = \"white\", size = 2) +\n  # Scales and theme\n  scale_fill_viridis_c(\"Volume\", option = \"A\") +\n  theme_bw()\n```\n\nThis is especially useful for plotting multi-variate smooth terms in GAMs:\n\n```{r raster_GAM}\nlibrary(mgcv)\n\neg \u003c- gamSim(2, n = 5000, scale = .5)\n\nb5 \u003c- gam(y ~ s(x, z, k = 20), data = eg$data)\n\nplot(b5)\n\n# Compare to\n\ngge \u003c- ggpredict(b5, c(\"x [n=45]\", \"z [n=45]\"))\n\nautoplot(gge, aes(x = x, y = z, \n                  color = NULL, group = NULL, # need to override\n                  fill = predicted)) +\n  # Expected values + CI\n  geom_raster() +\n  geom_contour(aes(z = predicted), color = \"white\", size = 1, \n               breaks = seq(0, 0.6, by = 0.1)) +\n  geom_contour(aes(z = predicted - std.error, color = \"+1SE\"),\n               linetype = \"dashed\", \n               breaks = seq(0, 0.6, by = 0.1)) +\n  geom_contour(aes(z = predicted + std.error, color = \"-1SE\"),\n               linetype = \"dashed\", \n               breaks = seq(0, 0.6, by = 0.1)) +\n  # Scales and theme\n  scale_fill_viridis_c(\"y\", option = \"B\") +\n  scale_color_manual(NULL, values = c(\"red\", \"green\")) + \n  theme_minimal()\n```\n\n\n### Collapsing Across Random Variables\n\nHere is an example from MLM Stroop data:\n\n```{r stroop}\nlibrary(dplyr)\n\ndata(\"stroop\", package = \"afex\")\n\nset.seed(42)\n\nsome_stroop_data \u003c- stroop %\u003e%\n  filter(study == 1 \u0026 acc == 1, trialnum \u003c 60) %\u003e%\n  sample_n(1000) %\u003e%\n  mutate(\n    pno = factor(pno),\n    level1_cov = rnorm(n())\n  ) %\u003e%\n  group_by(pno) %\u003e%\n  mutate(level2_cov = rnorm(1)) %\u003e%\n  ungroup()\n\nm \u003c- lme4::lmer(rt ~ condition + congruency + level1_cov + level2_cov +\n                  (congruency | pno) + ( 1 | trialnum),\n                data = some_stroop_data)\n\n\ngge \u003c- ggemmeans(m, c(\"congruency\", \"condition\"))\n\n\np \u003c- autoplot(gge) +\n  # Expected values + CI\n  geom_CI_bar(width = .2, color = \"black\", position = position_dodge(0.7)) +\n  geom_expected_line(position = position_dodge(0.7)) +\n  geom_expected_point(color = \"black\", \n                      position = position_dodge(0.7), size = 3) +\n  # Scales and theme\n  scale_color_brewer(type = \"qual\", palette = 2, aesthetics = c(\"color\", \"fill\")) +\n  theme_classic() +\n  labs(y = \"rt\")\n```\n\nTo collapse across a grouping variable, we set `collapse.by` to `TRUE`:\n\n```{r collapsTRUE}\np +\n  layer_fit_data(collapse.by = TRUE, \n                 position = position_jitterdodge(0.1,,0.7), alpha = 0.3)\n```\n\nOr specify by name:\n\n```{r collapse_trialnum}\np +\n  # Data\n  layer_fit_data(collapse.by = \"trialnum\", \n                 position = position_jitterdodge(0.1,,0.7), alpha = 0.3)\n```\n\nWe can combine and mix as we please:\n\n```{r collapse_both}\np +\n  # Data\n  layer_fit_data(collapse.by = \"pno\", \n                 aes(shape = \"pno\", x = as.numeric(congruency) + .05),\n                 position = position_jitterdodge(0.1,,0.7), alpha = 0.3) +\n  layer_fit_data(collapse.by = \"trialnum\", \n                 aes(shape = \"trialnum\", x = as.numeric(congruency) - .05),\n                 position = position_jitterdodge(0.1,,0.7), alpha = 0.3) +\n  # Scales and theme\n  scale_shape_manual(\"Random var\", values = c(21, 22))\n```\n\n\nWe can do the same for residualized data, or with a continuous variable on x (though this only really works nicely if the covariate is on level 2+) - or both:\n\n```{r collapse_rez_contX}\ngge \u003c- ggemmeans(m, c(\"level2_cov [all]\", \"congruency\", \"condition\"))\n\nautoplot(gge) +\n  # Expected values + CI\n  geom_CI_ribbon() +\n  geom_expected_line() +\n  # Data\n  layer_fit_data(collapse.by = \"pno\", residuals = TRUE,\n                 alpha = 0.4, shape = 16) +\n  # Scales and theme\n  scale_color_viridis_d(end = 0.4, aesthetics = c(\"color\", \"fill\")) +\n  theme_classic()\n```\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmattansb%2Fggggeffects","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmattansb%2Fggggeffects","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmattansb%2Fggggeffects/lists"}