Beautiful equations in R Markdown and Quarto

Author

Philippe Massicotte

Published

August 5, 2022

When writing dynamic documents in R (either R Markdown or Quarto), it can be useful to display model equations. I recently discovered equatiomatic, a very nice package that can do the job.

Photo by Artturi Jalli on Unsplash

The package can be installed from CRAN using install.packages("equatiomatic"). To explore the package’s functionalities, we will build a simple linear model using mtcars data (most examples are taken from the equatiomatic vignette website).

library(equatiomatic)

# Create a simple linear model
mod2 <- lm(mpg ~ ., mtcars)
broom::tidy(mod2)
#> # A tibble: 11 × 5
#>    term        estimate std.error statistic p.value
#>    <chr>          <dbl>     <dbl>     <dbl>   <dbl>
#>  1 (Intercept)  12.3      18.7        0.657  0.518 
#>  2 cyl          -0.111     1.05      -0.107  0.916 
#>  3 disp          0.0133    0.0179     0.747  0.463 
#>  4 hp           -0.0215    0.0218    -0.987  0.335 
#>  5 drat          0.787     1.64       0.481  0.635 
#>  6 wt           -3.72      1.89      -1.96   0.0633
#>  7 qsec          0.821     0.731      1.12   0.274 
#>  8 vs            0.318     2.10       0.151  0.881 
#>  9 am            2.52      2.06       1.23   0.234 
#> 10 gear          0.655     1.49       0.439  0.665 
#> 11 carb         -0.199     0.829     -0.241  0.812

There are different ways to display the model equation. The most basic way is to call the extract_eq() function. This will display the equation without the fitted coefficients.

extract_eq(mod2)

mpg=α+β1(cyl)+β2(disp)+β3(hp)+β4(drat)+β5(wt)+β6(qsec)+β7(vs)+β8(am)+β9(gear)+β10(carb)+ϵ

As we can see, this equation is pretty long. It would be best to wrap it over multiple lines. This can be controlled using wrap = TRUE.

extract_eq(mod2, wrap = TRUE)

mpg=α+β1(cyl)+β2(disp)+β3(hp) +β4(drat)+β5(wt)+β6(qsec)+β7(vs) +β8(am)+β9(gear)+β10(carb)+ϵ

The number of terms per line is controlled with terms_per_line.

extract_eq(mod2, wrap = TRUE, terms_per_line = 2)

mpg=α+β1(cyl) +β2(disp)+β3(hp) +β4(drat)+β5(wt) +β6(qsec)+β7(vs) +β8(am)+β9(gear) +β10(carb)+ϵ

There is a lot of styling customization that can be performed.

extract_eq(mod2, wrap = TRUE, greek_colors = "red", subscript_colors = "blue")

mpg=α+β1(cyl)+β2(disp)+β3(hp) +β4(drat)+β5(wt)+β6(qsec)+β7(vs) +β8(am)+β9(gear)+β10(carb)+ϵ

One can use use_coefs = TRUE to extract the fitted coefficients.

extract_eq(mod2, wrap = TRUE, use_coefs = TRUE)

mpg^=12.30.11(cyl)+0.01(disp)0.02(hp) +0.79(drat)3.72(wt)+0.82(qsec)+0.32(vs) +2.52(am)+0.66(gear)0.2(carb)

Many types of models are supported by equatiomatic. Further information can be found on the equatiomatic website.

Session info
#> ─ Session info ───────────────────────────────────────────────────────────────────────────────────────────────────────
#>  setting  value
#>  version  R version 4.4.0 (2024-04-24)
#>  os       Ubuntu 24.04 LTS
#>  system   x86_64, linux-gnu
#>  ui       X11
#>  language en_CA:en
#>  collate  en_CA.UTF-8
#>  ctype    en_CA.UTF-8
#>  tz       America/Toronto
#>  date     2024-05-02
#>  pandoc   3.1.3 @ /usr/bin/ (via rmarkdown)
#> 
#> ─ Packages ───────────────────────────────────────────────────────────────────────────────────────────────────────────
#>  ! package      * version date (UTC) lib source
#>  P backports      1.4.1   2021-12-13 [?] RSPM (R 4.4.0)
#>  P broom          1.0.5   2023-06-09 [?] RSPM (R 4.4.0)
#>  P cachem         1.0.8   2023-05-01 [?] RSPM (R 4.4.0)
#>  P cli            3.6.2   2023-12-11 [?] RSPM (R 4.4.0)
#>  P devtools       2.4.5   2022-10-11 [?] RSPM
#>  P digest         0.6.35  2024-03-11 [?] RSPM (R 4.4.0)
#>  P dplyr          1.1.4   2023-11-17 [?] RSPM (R 4.4.0)
#>  P ellipsis       0.3.2   2021-04-29 [?] RSPM (R 4.4.0)
#>  P equatiomatic * 0.3.1   2024-05-02 [?] Github (datalorax/equatiomatic@39e8c3e)
#>  P evaluate       0.23    2023-11-01 [?] RSPM (R 4.4.0)
#>  P fansi          1.0.6   2023-12-08 [?] RSPM (R 4.4.0)
#>  P fastmap        1.1.1   2023-02-24 [?] RSPM (R 4.4.0)
#>  P fs             1.6.4   2024-04-25 [?] CRAN (R 4.4.0)
#>  P generics       0.1.3   2022-07-05 [?] RSPM (R 4.4.0)
#>  P glue           1.7.0   2024-01-09 [?] RSPM (R 4.4.0)
#>  P htmltools      0.5.8.1 2024-04-04 [?] RSPM (R 4.4.0)
#>  P htmlwidgets    1.6.4   2023-12-06 [?] RSPM
#>  P httpuv         1.6.15  2024-03-26 [?] RSPM (R 4.4.0)
#>  P jsonlite       1.8.8   2023-12-04 [?] RSPM (R 4.4.0)
#>  P knitr          1.46    2024-04-06 [?] RSPM (R 4.4.0)
#>  P later          1.3.2   2023-12-06 [?] RSPM (R 4.4.0)
#>  P lifecycle      1.0.4   2023-11-07 [?] RSPM (R 4.4.0)
#>  P magrittr       2.0.3   2022-03-30 [?] RSPM (R 4.4.0)
#>  P memoise        2.0.1   2021-11-26 [?] RSPM (R 4.4.0)
#>  P mime           0.12    2021-09-28 [?] RSPM (R 4.4.0)
#>  P miniUI         0.1.1.1 2018-05-18 [?] RSPM (R 4.4.0)
#>  P pillar         1.9.0   2023-03-22 [?] RSPM (R 4.4.0)
#>  P pkgbuild       1.4.4   2024-03-17 [?] RSPM (R 4.4.0)
#>  P pkgconfig      2.0.3   2019-09-22 [?] RSPM (R 4.4.0)
#>  P pkgload        1.3.4   2024-01-16 [?] RSPM
#>  P processx       3.8.4   2024-03-16 [?] RSPM (R 4.4.0)
#>  P profvis        0.3.8   2023-05-02 [?] RSPM
#>  P promises       1.3.0   2024-04-05 [?] RSPM (R 4.4.0)
#>  P ps             1.7.6   2024-01-18 [?] RSPM (R 4.4.0)
#>  P purrr          1.0.2   2023-08-10 [?] RSPM (R 4.4.0)
#>  P quarto       * 1.4     2024-03-06 [?] RSPM
#>  P R.cache        0.16.0  2022-07-21 [?] RSPM
#>  P R.methodsS3    1.8.2   2022-06-13 [?] RSPM
#>  P R.oo           1.26.0  2024-01-24 [?] RSPM
#>  P R.utils        2.12.3  2023-11-18 [?] RSPM
#>  P R6             2.5.1   2021-08-19 [?] RSPM (R 4.4.0)
#>  P Rcpp           1.0.12  2024-01-09 [?] RSPM (R 4.4.0)
#>  P remotes        2.5.0   2024-03-17 [?] RSPM
#>  P renv           1.0.7   2024-04-11 [?] RSPM (R 4.4.0)
#>  P rlang          1.1.3   2024-01-10 [?] RSPM (R 4.4.0)
#>  P rmarkdown      2.26    2024-03-05 [?] RSPM (R 4.4.0)
#>  P rstudioapi     0.16.0  2024-03-24 [?] RSPM
#>  P sessioninfo    1.2.2   2021-12-06 [?] RSPM
#>  P shiny          1.8.1.1 2024-04-02 [?] RSPM (R 4.4.0)
#>  P stringi        1.8.3   2023-12-11 [?] RSPM (R 4.4.0)
#>  P stringr        1.5.1   2023-11-14 [?] RSPM (R 4.4.0)
#>  P styler       * 1.10.3  2024-04-07 [?] RSPM
#>  P tibble         3.2.1   2023-03-20 [?] RSPM (R 4.4.0)
#>  P tidyr          1.3.1   2024-01-24 [?] RSPM (R 4.4.0)
#>  P tidyselect     1.2.1   2024-03-11 [?] RSPM (R 4.4.0)
#>  P urlchecker     1.0.1   2021-11-30 [?] RSPM
#>  P usethis        2.2.3   2024-02-19 [?] RSPM
#>  P utf8           1.2.4   2023-10-22 [?] RSPM (R 4.4.0)
#>  P vctrs          0.6.5   2023-12-01 [?] RSPM (R 4.4.0)
#>  P xfun           0.43    2024-03-25 [?] RSPM (R 4.4.0)
#>  P xtable         1.8-4   2019-04-21 [?] RSPM (R 4.4.0)
#>  P yaml           2.3.8   2023-12-11 [?] RSPM (R 4.4.0)
#> 
#>  [1] /tmp/RtmpC4S8Ab/renv-use-libpath-2e3df224e3b7d5
#>  [2] /home/filoche/.cache/R/renv/sandbox/linux-ubuntu-noble/R-4.4/x86_64-pc-linux-gnu/a71ef467
#> 
#>  P ── Loaded and on-disk path mismatch.
#> 
#> ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────