--- title: "Fitting an ERGM and Viewing the Output with tabulergm" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{Fitting an ERGM and Viewing the Output with tabulergm} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r setup, include = FALSE} knitr::opts_chunk$set( collapse = TRUE, comment = "#>" ) ``` ## Overview This vignette demonstrates how to: 1. Fit an ERGM using the **ergm** package. 2. Produce a publication-ready Markdown table with `tabulergm_table(format = "markdown")`. 3. Render the table inline in a Quarto or R Markdown document using `results: asis`. 4. Replace the shipped term titles, descriptions, and citations for a single table. 5. Interactively preview the table in the RStudio viewer (or a browser) with `tabulergm_view()`. ## Setup ```{r load-packages, message = FALSE, warning = FALSE} library(ergm) library(tabulergm) ``` ## Fitting the model We use the Florentine marriage network, which ships with **ergm**, and fit a simple model with an `edges` term and a `nodematch` term for wealth quartile. ```{r fit-model, message = FALSE, warning = FALSE} data(florentine) model <- ergm( flomarriage ~ edges + nodematch("wealth"), control = control.ergm(seed = 42) ) summary(model) ``` ## Creating a Markdown table Calling `tabulergm_table()` with `format = "markdown"` returns a `knitr_kable` object. Adding the chunk option `results: asis` (or `results = "asis"` in R Markdown) causes knitr to emit the table verbatim, so the Markdown renderer (Quarto, Pandoc, GitHub, etc.) formats it properly. Math notation in the **math** column is automatically wrapped in `$...$` so that Pandoc can render it reliably in table cells across output formats, including Word. Network figures in the **figure** column are emitted with Markdown image syntax. > **Quarto tip:** use `#| results: asis` (or `results = "asis"` in R Markdown) > on the chunk so that knitr emits the table verbatim instead of quoting it. ```{r markdown-table, results = "asis"} tabulergm_table( model, include_math = TRUE, include_description = TRUE, format = "markdown" ) ``` ## Customizing titles, descriptions, and citations Each term carries a short `title` and a plain-language `description`, taken from `tabulergm`'s term dictionary and falling back to the `ergm` term database for terms the dictionary does not cover. Add the `title` column with `include_title = TRUE`, and replace either field for a single table with the `override.*` arguments: ```{r overrides, results = "asis"} tabulergm_table( model, include_title = TRUE, include_description = TRUE, override.title = c(edges = "Density"), override.desc = c(edges = "Baseline propensity to form ties."), format = "markdown" ) ``` `override.math`, `override.figure`, and `override.citation` work the same way, and the single `override` argument sets several fields at once: ```{r overrides-bulk, eval = FALSE} tabulergm_table( model, override = list( edges = list(title = "Density", desc = "Baseline tie propensity."), nodematch = list(citation = "doi:10.1146/annurev.soc.27.1.415") ) ) ``` Override names are matched against the term name first and the coefficient name second, so an expanded coefficient such as `nodematch.wealth.3` can be targeted on its own. Terms with a citation show a `(key)` marker next to their description, and the matching `[key] identifier` line is appended below the table. Citations are stored as a DOI, arXiv id, PubMed id, or URL rather than a formatted reference, so readers can import them into their own bibliography software: ```{r citations, results = "asis"} tabulergm_table( flomarriage ~ gwesp(0.5, fixed = TRUE) + gwdegree(0.5, fixed = TRUE), format = "markdown" ) ``` ## Inspecting a formula without a fitted model You can also pass a bare formula to inspect term metadata before fitting: ```{r formula-table, results = "asis"} tabulergm_table( flomarriage ~ edges + nodematch("wealth") + triangle, format = "markdown" ) ``` ## The term dictionary `tabulergm` ships math and network drawings for commonly used ERGM terms, including directed variants and mode-specific bipartite terms (`b1*` terms summarize the first mode, and `b2*` terms summarize the second mode). The table below covers every term currently included in the dictionary; terms with both directed and undirected definitions (`edges`, `gwesp`, `gwdsp`) display the undirected version: ```{r term-dictionary, results = "asis"} dictionary_terms <- network ~ edges + mutual + triangle + gwesp(0.5, fixed = TRUE) + gwdsp(0.5, fixed = TRUE) + gwdegree(0.5, fixed = TRUE) + altkstar(2, fixed = TRUE) + nodematch("attr") + nodefactor("attr") + nodemix("attr") + nodecov("attr") + absdiff("attr") + edgecov("cov") + transitiveties + cyclicalties + nodeicov("attr") + nodeocov("attr") + gwb1dsp(0.5, fixed = TRUE) + gwb2dsp(0.5, fixed = TRUE) + b1factor("type") + b2factor("group") + b1nodematch("type") + b2nodematch("group") + b1starmix(2, "type") + b2starmix(2, "group") tabulergm_table(dictionary_terms, format = "markdown") ``` ```{r term-coverage, include = FALSE} # Fails the render if a term in inst/terms/ is missing from the table above yml_terms <- unique( sub( "\\.(un)?directed\\.yml$", "", list.files(system.file("terms", package = "tabulergm")) ) ) stopifnot(all(yml_terms %in% parse_ergm_formula(dictionary_terms)$term)) ``` ## Interactive preview with `tabulergm_view()` During an interactive session you can call `tabulergm_view()` to open the table in the RStudio viewer pane or the system browser: ```{r view-demo, eval = FALSE} tabulergm_view(model, include_math = TRUE, include_description = TRUE) ``` `tabulergm_view()` builds a self-contained HTML page that loads MathJax from a CDN, so LaTeX math and embedded network figures render immediately without any additional setup.