Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Type: Package
Package: modelbased
Title: Estimation of Model-Based Predictions, Contrasts and Means
Version: 0.13.0.7
Version: 0.13.0.8
Authors@R:
c(person(given = "Dominique",
family = "Makowski",
Expand Down
10 changes: 7 additions & 3 deletions R/options.R
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@
#' - `options(modelbased_full_labels = FALSE)` will remove redundant
#' (duplicated) labels from rows.
#'
#' - `options(easystats_display_format = <value>)` will set the default format
#' for the `display()` methods. Can be one of `"markdown"`, `"html"`, or
#' `"tt"`. See [`display.estimate_contrasts()`] for details.
#'
#' **For plotting**
#'
#' - `options(modelbased_join_dots = <logical>)` will set a default value for
Expand All @@ -45,7 +49,7 @@
#' the `alpha` argument of the `ribbon` geom. Should be a number between `0`
#' and `1`.
#'
#' - `options(easystats_display_format = <value>)` will set the default format
#' for the `display()` methods. Can be one of `"markdown"`, `"html"`, or
#' `"tt"`. See [`display.estimate_contrasts()`] for details.
#' - `options(modelbased_tinyplot_dodge = <number>)` will set a default value
#' for the `dodge` argument (spacing between geoms) when using
#' `tinyplot::plt()`. Should be a number between `0` and `1`.
NULL
8 changes: 6 additions & 2 deletions R/tinyplot.R
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
# now need to extract the aesthetics and data and use it to create a tinyplot
# object
aes <- .find_aes(x, model_info, numeric_as_discrete)
data <- aes$data

Check warning on line 48 in R/tinyplot.R

View workflow job for this annotation

GitHub Actions / lint-changed-files / lint-changed-files

file=R/tinyplot.R,line=48,col=3,[object_overwrite_linter] 'data' is an exported object from package 'utils'. Avoid re-using such symbols.
aes <- aes$aes

# save additional arguments, once for theming and once for the plot
Expand All @@ -63,7 +63,7 @@
}

# Don't plot raw data for transformed responses with no back-transformation
transform <- attributes(x)$transform

Check warning on line 66 in R/tinyplot.R

View workflow job for this annotation

GitHub Actions / lint-changed-files / lint-changed-files

file=R/tinyplot.R,line=66,col=3,[object_overwrite_linter] 'transform' is an exported object from package 'base'. Avoid re-using such symbols.

if (isTRUE(model_info$is_linear) && !isTRUE(transform)) {
# add information about response transformation
Expand Down Expand Up @@ -107,8 +107,12 @@

# dodging -------------------------------

# Set dodge value for grouped point or pointrange plots.
# The value 0.07 was chosen to reduce overlap in this context; adjust via
Comment thread
strengejacke marked this conversation as resolved.
# option if needed.
dodge_value <- getOption("modelbased_tinyplot_dodge", 0.07)
if (!is.null(aes$color) && aes$type %in% c("pointrange", "point")) {
dots$dodge <- 0.1
dots$dodge <- dodge_value
}

## TODO: legend labels?
Expand Down Expand Up @@ -144,7 +148,7 @@
}

# add layer
plot_args$draw <- {

Check warning on line 151 in R/tinyplot.R

View workflow job for this annotation

GitHub Actions / lint-changed-files / lint-changed-files

file=R/tinyplot.R,line=151,col=23,[unnecessary_nesting_linter] Reduce the nesting of this statement by removing the braces {}.
tinyplot::tinyplot(
# we need the original response name for the data points
# so we update the formula for the plot description
Expand All @@ -162,7 +166,7 @@
}

# plot it!
do.call(tinyplot::tinyplot, plot_args)
suppressWarnings(do.call(tinyplot::tinyplot, plot_args))
}

#' @exportS3Method tinyplot::tinyplot
Expand Down
4 changes: 4 additions & 0 deletions R/visualisation_recipe.R
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,11 @@
#' will set a default value for the `alpha` argument of the `ribbon` geom.
#' Should be a number between `0` and `1`.
#'
#' - `modelbased_tinyplot_dodge`: `options(modelbased_tinyplot_dodge = <number>)`
#' will set a default value for the `dodge` argument (spacing between geoms)
#' when using `tinyplot::plt()`. Should be a number between `0` and `1`.
#'
#' @examplesIf all(insight::check_if_installed(c("marginaleffects", "see", "ggplot2"), quietly = TRUE)) && getRversion() >= "4.1.0"

Check warning on line 77 in R/visualisation_recipe.R

View workflow job for this annotation

GitHub Actions / lint-changed-files / lint-changed-files

file=R/visualisation_recipe.R,line=77,col=121,[line_length_linter] Lines should not be more than 120 characters. This line is 131 characters.
#' library(ggplot2)
#' library(see)
#' # ==============================================
Expand Down
9 changes: 6 additions & 3 deletions man/modelbased-options.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions man/visualisation_recipe.estimate_predicted.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions pkgdown/_pkgdown.yml
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@ navbar:
- text: "Visualization"
- text: "Plotting estimated marginal means"
href: articles/plotting.html
- text: "Plotting estimated marginal means with tinyplot"
href: articles/plotting_tinyplot.html
- text: "Visualize effects and interactions"
href: articles/estimate_relation.html
- text: "The modelisation approach"
Expand Down
1 change: 1 addition & 0 deletions vignettes/overview_of_vignettes.Rmd
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ All package vignettes are available at [https://easystats.github.io/modelbased/]
### Visualization

* [Plotting estimated marginal means](https://easystats.github.io/modelbased/articles/plotting.html)
* [Plotting estimated marginal means with tinyplot](https://easystats.github.io/modelbased/articles/plotting_tinyplot.html)
* [Visualize effects and interactions](https://easystats.github.io/modelbased/articles/estimate_relation.html)
* [The Modelisation Approach to Statistics](https://easystats.github.io/modelbased/articles/modelisation_approach.html)

Expand Down
177 changes: 177 additions & 0 deletions vignettes/plotting_tinyplot.Rmd
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
---
title: "Plotting estimated marginal means with tinyplot"
output: rmarkdown::html_vignette
vignette: >
%\VignetteIndexEntry{Plotting estimated marginal means with tinyplot}
%\VignetteEngine{knitr::rmarkdown}
%\VignetteEncoding{UTF-8}
bibliography: bibliography.bib
---

```{r set-options, echo = FALSE}
knitr::opts_chunk$set(
collapse = TRUE,
comment = "#>",
dev = "png",
out.width = "100%",
fig.width = 7,
fig.height = 4,
dpi = 300,
message = FALSE,
warning = FALSE,
package.startup.message = FALSE
)

options(modelbased_join_dots = FALSE)
options(modelbased_select = "minimal")

pkgs <- c("marginaleffects", "tinyplot")
if (!all(insight::check_if_installed(pkgs, quietly = TRUE))) {
knitr::opts_chunk$set(eval = FALSE)
}
if (getRversion() < "4.1.0") {
knitr::opts_chunk$set(eval = FALSE)
}
```

This vignette provides a quick overview with different examples that show how to plot estimated marginal means, like [in this vignette](https://easystats.github.io/modelbased/articles/plotting.html), however, here we use the [`{tinyplot}`](https://grantmcdermott.com/tinyplot/) package instead of `{ggplot2}` to create the plots.

## One predictor - categorical

The simplest case is possibly plotting one categorical predictor. Predicted values for each level and its confidence intervals are shown.

```{r}
library(modelbased)
library(tinyplot)

data(efc, package = "modelbased")
efc <- datawizard::to_factor(efc, c("e16sex", "c172code", "e42dep"))

m <- lm(neg_c_7 ~ e16sex + c172code + barthtot, data = efc)
estimate_means(m, "c172code") |> plt()
```

## One predictor - numeric

For numeric predictors, the range of predictions at different values of the focal predictor are plotted, the uncertainty is displayed as confidence band.

```{r}
estimate_means(m, "barthtot") |> plt()
```

## Two predictors - categorical

For two categorical predictors, the first focal predictors is plotted along the x-axis, while the levels of the second predictor are mapped to different colors.

```{r}
m <- lm(neg_c_7 ~ e16sex * c172code + e42dep, data = efc)
estimate_means(m, c("e16sex", "c172code")) |> plt()
```

## Two predictors - numeric * categorical

For two predictors, where the first is numeric and the second categorical, range of predictions including confidence bands are shown, with the different levels of the second (categorical) predictor mapped to colors again.

```{r}
m <- lm(neg_c_7 ~ barthtot * c172code + e42dep, data = efc)
estimate_means(m, c("barthtot", "c172code")) |> plt()
```

In general, plots can be further modified using functions or arguments from the **tinyplot** package. Thereby, other themes, color scales, faceting and so on, can be applied.
Comment thread
strengejacke marked this conversation as resolved.

```{r}
estimate_means(m, c("barthtot", "c172code")) |>
plt(facet = ~c172code)

estimate_means(m, c("barthtot", "c172code")) |>
plt(palette = "okabe")
```

## Two predictors - categorical * numeric

If the numeric predictor is the _second_ focal term, its values are still mapped to colors, however, by default to a continuous (gradient) scale, because a range of representative values for that numeric predictor is used by default.

Focal predictors specified in `estimate_means()` are passed to `insight::get_datagrid()`. If not specified otherwise, representative values for numeric predictors are evenly distributed from the minimum to the maximum, with a total number of `length` values covering that range.

I.e., by default, arguments `range = "range"` and `length = 10` in `insight::get_datagrid()`, and thus for numeric predictors, a _range_ of _length_ values is used to estimate predictions.

```{r}
# by default, `range = "range"` and `length = 10`
estimate_means(m, c("c172code", "barthtot")) |> plt()
```

That means that the `length` argument can be used to control how many values (lines) for the numeric predictors are chosen.

```{r}
estimate_means(m, c("c172code", "barthtot"), length = 20) |> plt()
```

Another option would be to use `range = "grid"`, in which case the mean and +/- one standard deviation around the mean are chosen as representative values for numeric predictors.

```{r}
estimate_means(m, c("c172code", "barthtot"), range = "grid") |> plt()
```

It is also possible to specify representative values, at which the estimated marginal means of the outcome should be plotted. Again, consult the documentation at `?insight::get_datagrid` for further details.
Comment thread
strengejacke marked this conversation as resolved.

```{r}
estimate_means(
m,
c(
"c172code = c('low level of education', 'high level of education')",
"barthtot = c(30, 50, 80)"
)
) |> plt()

estimate_means(m, c("c172code", "barthtot = [fivenum]")) |> plt()
```

## Three numeric predictors

The default plot-setting for three numeric predictors can be rather confusing.

```{r}
m <- lm(neg_c_7 ~ c12hour * barthtot * c160age, data = efc)
estimate_means(m, c("c12hour", "barthtot", "c160age")) |> plt()
```

Instead, it is recommended to use `length`, create a "reference grid", or again specify meaningful values directly in the `by` argument.

```{r}
estimate_means(m, c("c12hour", "barthtot", "c160age"), length = 2) |> plt()

estimate_means(m, c("c12hour", "barthtot", "c160age"), range = "grid") |> plt()
```

## Three categorical predictors

Multiple categorical predictors are usually less problematic, since discrete color scales and faceting are used to distinguish between factor levels.

```{r}
m <- lm(neg_c_7 ~ e16sex * c172code * e42dep, data = efc)
estimate_means(m, c("e16sex", "c172code", "e42dep")) |> plt()
```

## Smooth plots

Remember that by default a range of ten values is chosen for numeric focal predictors. While this mostly works well for plotting linear relationships, plots may look less smooth for certain models that involve quadratic or cubic terms, or splines, or for instance if you have GAMs.

```{r}
m <- lm(neg_c_7 ~ e16sex * c12hour + e16sex * I(c12hour^2), data = efc)
estimate_means(m, c("c12hour", "e16sex")) |> plt()
```

In this case, simply increase the number of representative values by setting `length` to a higher number.

```{r}
estimate_means(m, c("c12hour", "e16sex"), length = 200) |> plt()
```

```{r echo=FALSE}
# reset options
options(
modelbased_join_dots = NULL,
modelbased_estimate = NULL,
modelbased_select = NULL
)
```
Loading