How the tables turned

Author
Published

November 30, 2025

Meme of Link from The lEgend of Zelda: Windwaker. The camera is zoomed right up under his chin, his face filling the screen. There's an on-screen instruction to press the 'A' button to 'let go'.

tl;dr

{a11ytables} is dead, long live {aftables}.

Regret?

A while back I presented ‘Panic! In The Toolshed’ about how public-sector data scientists should share code to prevent wheel reinvention.

I gave the example of my {a11ytables} R package, which has helped to publish spreadsheets of official statistics that follow best practices.

It got harder to find time to maintain the package. I hemmed-and-hawed about its existence and procrastinated two concept packages to make up for its weaknesses.

But then the weight was lifted!

Rehome

The Analysis Function at the Office for National Statistics (ONS) now host and maintain the package. I can’t think of a better home.

Transferring the package GitHub repository was a bit of a dance, passing from the co-analysis org to my personal account and finally the best-practice-and-impact org. I fretted about archiving and forking instead, but a transfer appears not to have caused issues.

As part of this move, the package has been renamed {aftables}. The ‘af’ stands for ‘Analysis Function’ and echoes the related {afcharts} package that helps produce best-practice visualisations.

As a parting gift, I used my {gex} package to make a quick hex logo that echoes the {afcharts} logo:

Hex logo for aftables. Multicoloured squares on the lower half echo the cells of a spreadsheet. The name of the package is above the squares. Reminiscent of the hex logo for afcharts and uses the same colour palette.

This renaming hasn’t had a major impact as far as I can tell. The team published a launch blog; I updated colleagues via the cross-government Slack; and GitHub auto-rereoutes from co-analysis/a11ytables to best-practice-and-impact/aftables.

The team has already made updates and submitted successfully to CRAN in these past few months, which I definitely didn’t have the energy to tackle.

So now you can just install.packages("aftables") to try it out. Simply lovely.

Relief

So thank you to the Analysis Function team, particularly Olivia and Zach; to Matt and Tim for their early contributions; and to everyone who has used the package and provided feedback.

Panic? What panic?

Environment

Session info
Last rendered: 2025-11-30 17:03:05 GMT
R version 4.5.1 (2025-06-13)
Platform: aarch64-apple-darwin20
Running under: macOS Sequoia 15.6.1

Matrix products: default
BLAS:   /Library/Frameworks/R.framework/Versions/4.5-arm64/Resources/lib/libRblas.0.dylib 
LAPACK: /Library/Frameworks/R.framework/Versions/4.5-arm64/Resources/lib/libRlapack.dylib;  LAPACK version 3.12.1

locale:
[1] en_GB.UTF-8/en_GB.UTF-8/en_GB.UTF-8/C/en_GB.UTF-8/en_GB.UTF-8

time zone: Europe/London
tzcode source: internal

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

loaded via a namespace (and not attached):
 [1] htmlwidgets_1.6.4 compiler_4.5.1    fastmap_1.2.0     cli_3.6.5        
 [5] tools_4.5.1       htmltools_0.5.8.1 yaml_2.3.10       rmarkdown_2.29   
 [9] knitr_1.50        jsonlite_2.0.0    xfun_0.52         digest_0.6.37    
[13] rlang_1.1.6       evaluate_1.0.4   

Footnotes

  1. We talk a lot about reproducibility of our work, as we should, but Rhian gave a good talk at the NHS RPySOC 2025 conference about the power of reusability.↩︎

  2. {a11ytables2} aimed to use a more pipeable approach and to upgrade the package from {openxlsx} to {openxlsx2} (which the Analysis Function team have already done in {aftables}!), while {yamlsheets} attempted to use a text-based YAML ‘blueprint’ file to declare spreadsheet content.↩︎

  3. The fact I was using phrases like ‘panic’, ‘kill’ and ‘rebuild’ in earlier posts about {a11ytables} tells you something about the entirely self-imposed torment I was inflicting on myself.↩︎

Reuse

CC BY-NC-SA 4.0