An open API service indexing awesome lists of open source software.

https://github.com/matt-dray/a11ytables2

:1234::two: [WIP] R package: generate best-practice stats spreadsheets for publication
https://github.com/matt-dray/a11ytables2

accessibility openxlsx2 reproducible-analytical-pipeline rstats spreadsheet uk-gov-data-science

Last synced: about 1 month ago
JSON representation

:1234::two: [WIP] R package: generate best-practice stats spreadsheets for publication

Awesome Lists containing this project

README

        

---
output: github_document
---

```{r, include = FALSE}
knitr::opts_chunk$set(
collapse = TRUE,
comment = "#",
fig.path = "man/figures/README-",
out.width = "100%"
)
```

# {a11ytables2}

[![Project Status: Concept – Minimal or no implementation has been done yet, or the repository is only intended to be a limited example, demo, or proof-of-concept.](https://www.repostatus.org/badges/latest/concept.svg)](https://www.repostatus.org/#concept)

## Purpose

Generate spreadsheet publications that follow [best-practice guidance from the UK Government's Analysis Function](https://analysisfunction.civilservice.gov.uk/policy-store/releasing-statistics-in-spreadsheets/).

This package is a work-in-progress concept to experiment with new methods for [the {a11ytables} package](https://github.com/co-analysis/a11ytables). It may never be fully-featured or complete.

## Install

Install from GitHub via {remotes}:

```{r}
#| label: install-github
#| eval: false
remotes::install_github("matt-dray/a11ytables2")
```

## Workflow

The basic workflow involves building a 'blueprint': a list object that contains all the information needed to create an output workbook.

First, let's define some demo data that represents a table of statistical data to be published.

```{r}
#| label: dummy-data
mtcars_x <- mtcars[6:10, 1:5]
mtcars_x[2, 2] <- "[note 1]"
```

Now we can create our list blueprint (`new_blueprint()`) and build it up sheet by sheet, with specialised functions to add each sheet required by the best-practice standards (`append_cover()`, `append_contents()`, `append_notes()`, `append_tables()`). Each function has its own checks and arguments.

```{r}
#| label: blueprint
library(a11ytables2)

blueprint <-
new_blueprint() |> # initiate blueprint list
append_cover(
title = "I am a Test Workbook",
sections = list( # element names are headers, vector elements are new lines
"First Section" = "This is some text.",
"Second Section" = c("This is some text.", "This is some more text."),
"Third Section" = c("This is some text.", "This is some more text", "Even more."),
"Fourth Section" = "This is some text."
)
) |>
append_contents(
table = data.frame(
Tab = c("Notes", "Table_1"),
Description = c("The notes page.", "The first table [note 5].")
)
) |>
append_notes(
table = data.frame(
Note = c("[note 1]", "[note 2]"),
Description = c("This is a note.", "This is another note")
)
) |>
append_tables(
sheet_name = "Table_1", # will appear as the tab name in the workbook
title = "The Title 1 [note 3]",
subtitle = "The subtitle 1",
custom = c( # arbitrary pre-table information
x = "A custom row",
y = "Another custom row",
"A third."
),
source = "The source.",
tables = mtcars_x
) |>
append_tables( # this worksheet has two tables
sheet_name = "Table_2",
title = "The Title 2",
subtitle = "The subtitle 2",
source = "The source 2.",
tables = list( # provide multiple tables in list format
"Subtable 2.1" = mtcars[1:5, 1:5],
"Subtable 2.2" = mtcars_x
)
)
```

Click to see the structure of the blueprint object.

```{r}
#| label: structure
str(blueprint, 3)
```

Once we have the blueprint list, we can add spreadsheet structure and style by converting to an {openxlsx2} wbWorkbook-class object:

```{r}
#| label: generate-workbook
wb <- generate_workbook(blueprint)
wb
```

We can then apply some further manipulation to our wbWorkbook-class object to finesse it for our needs. For example, we can set the number format to 'General' for Table 1:

```{r}
#| label: numfmt
wb$add_numfmt(sheet = "Table_1", dims = "A10:E14", numfmt = "General")
```

And finally we can open a temporary copy of the workbook for inspection:

```{r}
#| label: open
#| eval: false
wb |> openxlsx2::wb_open()
```

Use `openxlsx2::wb_save()` instead to save to disk.

## Comparison to {a11ytables}

Improvements in {a11ytables2} compared to {a11ytables} include:

* [{openxlsx2}](https://janmarvin.github.io/openxlsx2/) for the back-end, rather than [{openxlsx}](https://ycphs.github.io/openxlsx/index.html)
* greater user control by building up with an `append_*()` function family
* greater flexibility to provide arbitrary pre-table content via `custom()` argument
* support for multiple tables per sheet

## Related projects

Actively-used packages include:

* [{a11ytables}](https://github.com/co-analysis/a11ytables) for R
* [{rapid.spreadsheets}](https://github.com/RAPID-ONS/rapid.spreadsheets) for R
* ['gptables'](https://github.com/best-practice-and-impact/gptables) for Python

Another experimental project that builds on {a11ytables}:

* [{yamlsheets}](https://github.com/matt-dray/yamlsheets) for R