Skip to content

Conversation

@ericmjl
Copy link
Member

@ericmjl ericmjl commented Dec 27, 2025

Summary

Implements the adorn_* family of functions from R janitor for formatting frequency tables (tabyls) into publication-ready tables. These functions are designed to be chained together in a fluent interface.

Closes #1557

Functions Implemented

1. adorn_totals(where="row", fill="-", na_rm=True, name="Total")

Add totals row and/or column to a DataFrame.

df.adorn_totals("both")
#   category  count1  count2  Total
# 0        A      10       5     15
# 1        B      20      15     35
# 2    Total      30      20     50

2. adorn_percentages(denominator="row", na_rm=True)

Convert counts to percentages (row-wise, column-wise, or overall).

df.adorn_percentages("row")
#   category    count1    count2
# 0        A  0.666667  0.333333
# 1        B  0.571429  0.428571

3. adorn_pct_formatting(digits=1, rounding="half to even", affix_sign=True)

Format decimal percentages as "XX.X%" strings.

df.adorn_percentages("row").adorn_pct_formatting()
#   category count1 count2
# 0        A  66.7%  33.3%
# 1        B  57.1%  42.9%

4. adorn_ns(position="rear", ns=None, format_func=None)

Append the original N counts to formatted percentage cells.

df.adorn_percentages("row").adorn_pct_formatting().adorn_ns()
#   category      count1      count2
# 0        A  66.7% (10)   33.3% (5)
# 1        B  57.1% (20)  42.9% (15)

5. adorn_title(placement="top", row_name=None, col_name=None)

Add variable name as title to a cross-tabulation.

6. adorn_rounding(digits=1, rounding="half to even")

Round numeric columns with configurable rounding method.

Full Pipeline Example

(df
    .adorn_totals("both")
    .adorn_percentages("row")
    .adorn_pct_formatting(digits=1)
    .adorn_ns()
)
#   category      count1      count2       Total
# 0        A  33.3% (10)   16.7% (5)  50.0% (15)
# 1        B  28.6% (20)  21.4% (15)  50.0% (35)
# 2    Total  30.0% (30)  20.0% (20)  50.0% (50)

Testing

  • Added 27 tests covering all functions
  • All tests pass
  • Code passes ruff linting and formatting checks

Implementation Notes

  • Functions work on any DataFrame, not just tabyls
  • Original counts are stored in DataFrame attrs for adorn_ns to access
  • Supports banker's rounding ("half to even") and standard rounding ("half up")
  • All functions preserve non-numeric columns

Implements the adorn_* family of functions from R janitor for
formatting frequency tables (tabyls) into publication-ready tables.

Functions implemented:
- adorn_totals: Add totals row and/or column to a DataFrame
- adorn_percentages: Convert counts to percentages (row/col/all)
- adorn_pct_formatting: Format percentages as 'XX.X%' strings
- adorn_ns: Append original N counts to percentage cells
- adorn_title: Add variable name as title to a cross-tabulation
- adorn_rounding: Round numeric columns with configurable method

All functions support fluent chaining for building pipelines like:
df.adorn_totals('both').adorn_percentages().adorn_pct_formatting().adorn_ns()

Closes #1557
@github-actions
Copy link

github-actions bot commented Dec 27, 2025

PR Preview Action v1.6.3

🚀 View preview at
https://pyjanitor-devs.github.io/pyjanitor/pr-preview/pr-1563/

Built to branch gh-pages at 2025-12-27 15:29 UTC.
Preview will be ready when the GitHub Pages deployment is complete.

@ericmjl ericmjl requested a review from samukweku December 27, 2025 15:09
- Fix adorn_ns to use positional indexing instead of comparing index labels
  to length, which correctly handles non-sequential indices and totals rows
- Fix adorn_totals fill parameter to apply to all non-numeric columns
  (not just string columns)
- Add thousand separator to adorn_ns default format function to match
  R janitor behavior
- Add 10 new tests covering NA handling, numeric first columns, custom ns
  DataFrame, totals row skipping, non-sequential indices, and fill parameter
@ericmjl ericmjl merged commit f1c42d7 into dev Dec 30, 2025
4 checks passed
@ericmjl
Copy link
Member Author

ericmjl commented Dec 30, 2025

Thank you, @samukweku!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feature: Implement adorn_* functions for tabyl formatting

3 participants