Automating Statistical Tables: From Output to Final Manuscript

Creating statistical tables for a scientific article is one of those tasks that consumes a disproportionate amount of time. Copying values from SPSS or R output, pasting them into Word, formatting them according to APA guidelines (see our guide on how to report results in APA 7), adjusting the decimal places, adding asterisks for significance levels, verifying that you have not made any transcription errors. It is a tedious process, prone to errors, and above all, completely unnecessary in the current era. Tools exist that allow you to automate the generation of tables directly from the analysis results, saving hours of work and eliminating the possibility of copy errors.

In R, the ecosystem of packages for automatic table generation is especially rich. The gtsummary package is probably the most versatile for the majority of situations encountered in clinical and health psychology. It allows you to generate descriptive tables with statistics by group, regression tables with coefficients, confidence intervals, and p-values, and comparison tables with the appropriate statistical tests automatically selected based on the variable type. The output can be exported directly to Word, HTML, or LaTeX with a clean format that requires minimal adjustments.

Regression tables and complex models

For regression model tables, the sjPlot package with its tab_model() function is extraordinarily useful. It accepts one or several regression models (linear, logistic, mixed, among others) and generates a comparative table with standardized and unstandardized coefficients, confidence intervals, p-values, and model fit measures. What is particularly interesting is that you can pass several models to the same function and it produces a table where they are compared side by side, which is perfect for presenting nested or alternative models. The HTML output can be opened directly in Word, and the format is clean enough to require only minor style adjustments.

Another package worth mentioning is apaTables, designed specifically to generate tables in APA format. Its main virtue is simplicity: with a single line of code you can generate a correlation table with means, standard deviations, and confidence intervals for each correlation, all formatted according to the 7th edition of the APA guidelines and exported as a Word file. If you do not use R, you can also format individual results with our automatic APA formatter, and if what you need is the whole table, the universal APA table generator builds the t-test, ANOVA or chi-square table without a line of code. For analysis of variance, apa.aov.table() produces complete tables with sums of squares, degrees of freedom, F-values, p-values, and partial eta squared. If your primary goal is to comply with APA format without complications, this package is hard to beat.

Automation with R Markdown and Quarto

The true qualitative leap in table automation comes from integrating table generation within a reproducible document. R Markdown and its successor Quarto allow you to write the article text and the analysis code in the same document. When you compile the document, the tables are generated automatically from the data and inserted in the correct place in the manuscript. If the data change (because you add participants, correct a coding error, or a reviewer asks you to exclude certain cases), you only need to recompile the document and all tables are updated automatically.

This way of working completely eliminates the risk of inconsistencies between the text and the tables, a problem that is more frequent than it might seem. Anyone who has reviewed articles knows that it is common to find discrepancies between the values reported in the text and those in the tables, or between the table and the article abstract. When everything is generated from the same code and the same data, these inconsistencies are impossible. Furthermore, the reproducibility of the analysis improves dramatically, because any researcher with access to the code and data can regenerate exactly the same tables.

Practical tips for getting started

If you have never automated table generation, my suggestion is to start with something simple. Install gtsummary in R and try generating a descriptive table of your data with tbl_summary(). You will see that with very little code you get a professional table that would have taken you half an hour to create manually. Once you experience that time savings, the motivation to learn more will come naturally. The next natural step is to integrate these tables into an R Markdown document, and from there the workflow becomes increasingly efficient.

For SPSS users who do not want to migrate to R, there are also options. SPSS output can be exported to Word or Excel with reasonable formatting using the export options in the results viewer. It is not as flexible or elegant as the solutions in R, but it is considerably better than copying and pasting values one by one. JASP, for its part, generates tables in APA format natively, making it a good option for researchers who want well-formatted results without writing code. For a broader comparison, see our article on software tools for data analysis.

Choosing between papaja, flextable, and gt

Once you commit to a reproducible pipeline, the next question is which table-rendering engine to standardize on. There are three that I recommend depending on the use case. The papaja package is purpose-built for psychology: it produces a full APA 7 manuscript (title page, abstract, tables, figures, references) from a single R Markdown document. Its helpers apa_print() and apa_table() take the output of an analysis and return a properly formatted table with the correct statistic names, italicization rules, and decimal conventions. If your target output is a Word manuscript for a psychology journal, papaja is the path of least resistance.

The flextable package is more general-purpose and shines when you need precise control over Word output: merged cells, custom borders, multi-row headers, footnotes with footnote markers, and conditional formatting (bolding p-values below .05, for example). It integrates well with officer for programmatic Word document assembly, which is useful when you are producing reports for clinical trials, protocols, or theses that have strict template requirements. The gt package, from the RStudio team, is the modern choice for HTML and PDF output, with a grammar of tables that makes complex tables surprisingly readable in code. For Quarto documents targeting HTML, gt is hard to beat aesthetically.

Quarto, parameters, and fully reproducible reports

Quarto, the successor to R Markdown, has consolidated reproducible reporting into a single ecosystem that works across R, Python, and Julia. The most underused feature for applied researchers is parameterized reports. You can define parameters at the top of a Quarto document (for example, the path to the dataset, the dependent variable, the grouping factor) and then render the same document repeatedly with different inputs. A common scenario in consulting is producing the same descriptive and inferential tables for ten subscales of a questionnaire: instead of copying ten chunks of code, you write one parameterized document and render it ten times with quarto_render() in a loop. The output is consistent, auditable, and immune to copy-paste errors.

Quarto also makes journal-specific templates straightforward. Many publishers (Elsevier, JASP, APA) now provide Quarto or LaTeX templates that define journal styling. A document written for Psychological Methods can be re-rendered for a thesis chapter just by switching the YAML format directive. This kind of flexibility used to require manual reformatting at every stage of a paper's life cycle. With a reproducible pipeline, it becomes a one-line change.

Common pitfalls of automation

Automation is not magic. The most frequent pitfall I see is rounding inconsistencies. Different packages have different default decimal places, and APA expects p-values to two or three decimals, correlations to two, effect sizes to two, and so on. Set these globally with options(scipen = 999, digits = 3) or, better, configure them inside the table function itself to avoid surprises. A second pitfall is variable labeling: raw column names like q01_anxsum are unacceptable in a manuscript. Use the labelled package or gtsummary::set_variable_labels() to attach human-readable labels once, at the start of the script, and propagate them through every table automatically.

A third issue is the risk of opaque automation. If the table is generated by a chain of functions you do not fully understand, you may report results without realizing that, for example, the default test for a continuous variable across three groups in gtsummary is a Kruskal-Wallis, not an ANOVA. Always verify which tests your automated function is running, and override the defaults explicitly when needed. The point of automation is reproducibility, not abdication of statistical judgment. If you want to dig deeper into the broader tooling landscape, my article on software tools for data analysis compares the main ecosystems, and the comparison of SPSS vs R vs JASP helps decide where to invest your time.

Keep reading

All blog articles