Tables so Beautifully Fine-Tuned You Will Believe It's Magic

The introduction of the 'broom' package has made converting model objects into data frames as simple as a single function. While the 'broom' package focuses on providing tidy data frames that can be used in advanced analysis, it deliberately stops short of providing functionality for reporting models in publication-ready tables. 'pixiedust' provides this functionality with a programming interface intended to be similar to 'ggplot2's system of layers with fine tuned control over each cell of the table. Options for output include printing to the console and to the common markdown formats (markdown, HTML, and LaTeX). With a little 'pixiedust' (and happy thoughts) tables can really fly.

Travis-CI Build Status Coverage Status

After tidying up your analyses with the broom package, go ahead and grab the pixiedust. Customize your table output and write it to markdown, HTML, LaTeX, or even just the console. pixiedust makes it easy to customize the appearance of your tables in all of these formats by adding any number of "sprinkles", much in the same way you can add layers to a ggplot.

fit <- lm(mpg ~ qsec + factor(am) + wt + factor(gear), data = mtcars)
dust(fit) %>% 
  sprinkle(col = 2:4, round = 3) %>% 
  sprinkle(col = 5, fn = quote(pvalString(value))) %>% 
  sprinkle_colnames(term = "Term", 
                    estimate = "Estimate", 
                     std.error = "SE",
                     statistic = "T-statistic", 
                     p.value = "P-value") %>%
#>            Term Estimate    SE T-statistic P-value
#> 1   (Intercept)    9.365 8.373       1.118    0.27
#> 2          qsec    1.245 0.383       3.252   0.003
#> 3   factor(am)1    3.151 1.941       1.624    0.12
#> 4            wt   -3.926 0.743      -5.286 < 0.001
#> 5 factor(gear)4   -0.268 1.655      -0.162    0.87
#> 6 factor(gear)5    -0.27 2.063      -0.131     0.9

Customizing with Sprinkles

Tables can be customized by row, column, or even by a single cell by adding sprinkles to the dust object. The table below shows the currently planned and implemented sprinkles. In the "implemented" column, an 'x' indicates a customization that has been implemented, while a blank cell suggests that the customization is planned but has not yet been implemented. In the remaining columns, an 'x' indicates that the sprinkle is already implemented for the output format; an 'o' indicates that implementation is planned but not yet completed; and a blank cell indicates that the sprinkle will not be implemented (usually because the output format doesn't support the option).

sprinkle implemented console markdown html latex
bg x x x
bg_pattern x x x
bg_pattern_by x x x
bold x x x x x
bookdown x x
border_collapse x x x
border x x x
border_thickness x x x
border_units x x x
border_style x x x
border_color x x x
caption x x x x x
colnames x x x x x
discrete x x x
discrete_colors x x x
float x x
fn x x x x x
font_color x x x
font_family x x
font_size x x x
font_size_units x x x
gradient x x x
gradient_colors x x x
gradient_cut x x x
gradient_n x x x
gradient_na x x x
halign x x x
height x x x
height_units x x x
hhline x x
italic x x x x x
justify x x x
label x x x
longtable x x x x x
merge x x x x x
na_string x x x x x
padding x x
replace x x x x x
round x x x x x
rotate_degree x x x
sanitize x
sanitize_args x
tabcolsep x
valign x x x
width x x x
width_units x x x

A Brief Example

To demonstrate, let's look at a simple linear model. We build the model and generate the standard summary.

fit <- lm(mpg ~ qsec + factor(am) + wt + factor(gear), data = mtcars)
#> Call:
#> lm(formula = mpg ~ qsec + factor(am) + wt + factor(gear), data = mtcars)
#> Residuals:
#>     Min      1Q  Median      3Q     Max 
#> -3.5064 -1.5220 -0.7517  1.3841  4.6345 
#> Coefficients:
#>               Estimate Std. Error t value Pr(>|t|)    
#> (Intercept)     9.3650     8.3730   1.118  0.27359    
#> qsec            1.2449     0.3828   3.252  0.00317 ** 
#> factor(am)1     3.1505     1.9405   1.624  0.11654    
#> wt             -3.9263     0.7428  -5.286 1.58e-05 ***
#> factor(gear)4  -0.2682     1.6555  -0.162  0.87257    
#> factor(gear)5  -0.2697     2.0632  -0.131  0.89698    
#> ---
#> Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
#> Residual standard error: 2.55 on 26 degrees of freedom
#> Multiple R-squared:  0.8498, Adjusted R-squared:  0.8209 
#> F-statistic: 29.43 on 5 and 26 DF,  p-value: 6.379e-10

While the summary is informative and useful, it is full of "stats-speak" and isn't necessarily in a format that is suitable for publication or submission to a client. The broom package provides the summary in tidy format that, serendipitously, it a lot closer to what we would want for formal reports.

#>            term   estimate std.error  statistic      p.value
#> 1   (Intercept)  9.3650443 8.3730161  1.1184792 2.735903e-01
#> 2          qsec  1.2449212 0.3828479  3.2517387 3.168128e-03
#> 3   factor(am)1  3.1505178 1.9405171  1.6235455 1.165367e-01
#> 4            wt -3.9263022 0.7427562 -5.2861251 1.581735e-05
#> 5 factor(gear)4 -0.2681630 1.6554617 -0.1619868 8.725685e-01
#> 6 factor(gear)5 -0.2697468 2.0631829 -0.1307430 8.969850e-01

It has been observed by some, however, that even this summary isn't quite ready for publication. There are too many decimal places, the p-value employ scientific notation, and column titles like "statistic" don't specify what type of statistic. These kinds of details aren't the purview of broom, however, as broom is focused on tidying the results of a model for further analysis (particularly with respect to comparing slightly varying models).

The pixiedust package diverts from broom's mission here and provides the ability to customize the broom output for presentation. The initial dust object returns a table that is similar to the broom output.

dust(fit) %>%
#>            term   estimate std.error  statistic   p.value
#> 1   (Intercept)  9.3650443 8.3730161  1.1184792 0.2735903
#> 2          qsec  1.2449212 0.3828479  3.2517387 0.0031681
#> 3   factor(am)1  3.1505178 1.9405171  1.6235455 0.1165367
#> 4            wt -3.9263022 0.7427562 -5.2861251  1.58e-05
#> 5 factor(gear)4  -0.268163 1.6554617 -0.1619868 0.8725685
#> 6 factor(gear)5 -0.2697468 2.0631829  -0.130743  0.896985

Where pixiedust shows its strength is the ease of which these tables can be customized. The code below rounds the columns estimate, std.error, and statistic to three decimal places each, and then formats the p.value into a format that happens to be one that I like.

x <- dust(fit) %>% 
  sprinkle(col = 2:4, round = 3) %>% 
  sprinkle(col = 5, fn = quote(pvalString(value))) %>%
#>            term estimate std.error statistic p.value
#> 1   (Intercept)    9.365     8.373     1.118    0.27
#> 2          qsec    1.245     0.383     3.252   0.003
#> 3   factor(am)1    3.151     1.941     1.624    0.12
#> 4            wt   -3.926     0.743    -5.286 < 0.001
#> 5 factor(gear)4   -0.268     1.655    -0.162    0.87
#> 6 factor(gear)5    -0.27     2.063    -0.131     0.9

Now we're almost there! Let's change up the column names, and while we're add it, let's add some "bold" markers to the statistically significant terms in order to make them stand out some (I say "bold" because the console output doesn't show up in bold, but with the markdown tags for bold text. In a rendered table, the text would actually be rendered in bold).

x <- x %>% 
  sprinkle(col = c("estimate", "p.value"), 
           row = c(2, 4), 
           bold = TRUE) %>% 
  sprinkle_colnames(term = "Term", 
                estimate = "Estimate", 
                std.error = "SE",
                statistic = "T-statistic", 
                p.value = "P-value") %>%
#>            Term   Estimate    SE T-statistic     P-value
#> 1   (Intercept)    9.365   8.373       1.118      0.27  
#> 2          qsec  **1.245** 0.383       3.252   **0.003**
#> 3   factor(am)1    3.151   1.941       1.624      0.12  
#> 4            wt **-3.926** 0.743      -5.286 **< 0.001**
#> 5 factor(gear)4   -0.268   1.655      -0.162      0.87  
#> 6 factor(gear)5    -0.27   2.063      -0.131       0.9

A cool, free tip!

The markdown output from pixiedust is somewhat limited due to the limitations of Rmarkdown itself. If/when more features become available for Rmarkdown output, I'll be sure to include them. But what can you do if you really want all of the flexibility of the HTML tables but need the MS Word document?

With a little help from the Gmisc package, you can have the best of both worlds. Gmisc isn't available on CRAN yet, but if you're willing to install it from GitHub, you can render a docx file. Install Gmisc with


Then use in your YAML header

output: Gmisc::docx_document

When you knit your document, it knits as an HTML file, but I've had no problems with the rendering when I right-click the file and open with MS Word.

Read more at (but note that this blog post was written about the Grmd package before it was moved into the Gmisc package).


0.8.4 (2018-06-29)

  • Added gaze function to produce model summaries side-by-side (#80)
  • Small adjustments to work with upcoming version of broom.

0.8.3 (2018-03-22)

  • Repaired recycling in several sprinkles. Sprinkles that permit more than one value will return an error if given multiple values and recycle = "none". The user must explicitly designate if recycling should be done over rows or columns.
  • Mapped "slidy" output to HTML.
  • Added several tests, bring test coverage up to 96%

0.8.2 (2018-02-23)

  • Added caption_number sprinkle, allowing numbering of tables to be turned off (#108)
  • Changed the license in order to redistribute code from the Hmisc package.
  • Added fixed_header sprinkle. Allows HTML tables to have a fixed header over a scrollable body.
  • Added lots of tests.
  • Added knit_print method to allow printing in Rmarkdown documents to operate more smoothly (#96).
  • Fixed text wrapping around left and right justified HTML tables (#107)
  • Added tabcolsep argument to \code{dust}

0.8.0 (2017-08-26)

  • Backward Compatibility Break: the border_collapse argument was changed to a character argument. This allows the full options available in HTML. The new default is border_collapse = "collapse", which is the equivalent of border_collapse = TRUE. Backward compatibility will be broken only if the border_collapse argument was changed.
  • All sprinkles have individual functions to perform their specific task. Now sprinkle(bg = "blue") may also be done via sprinkle_bg(bg = 'blue'). Although this isn't a much of a change to the user, it makes infrastructure changes possible that will make the codebase easier to support.
  • Added the discrete and discrete_colors sprinkles. (Issue #56)
  • Added the gradient, gradient_n, gradient_cut, and gradient_colors sprinkles. (Issue #56)
  • Fix hexadecimal color transparency bug (Issue #66)
  • Added get_dust_part to assist with generation of custom headers and footers (Issue #72)
  • Removed CSS styling for tables from the vignettes. (Issue #69)
  • Reduced spacing between table and caption in the LaTeX longtable environment.
  • Fixes to support dplyr 0.5.0 (thanks to David Kretch)
  • Better control over when to print to interactive environment viewer. (Issue #88)

0.7.5 (26 August 2016)

  • Add pixiemap for applying differing sprinkles across a dust_list
  • Add the argument logical_rows for dynamically locating rows to sprinkle
  • Include a link to the pixiedust webpage for documentation augmentation.

0.7.4 (17 June 2016)

  • Guard against changes to options()$scipen (Issue #62)
  • Remove remaining use of ArgumentCheck and replace with checkmate

0.7.3 (10 June 2016)

  • Fixed rotation in HTML tables
  • Created a new argument for print_dust_html (Issue #57) to give the user control over the amount of white space following HTML tables.
  • The replace sprinkle is now applied during printing. It had been applied in sprinkle, which violated the philosophy of not changing the content of the data frame until the last possible moment.
  • Added some extra unit tests.

0.7.2 (19 May 2016)

  • Fixed the padding specification in HTML tables.

0.7.1 (4 May 2016)

  • the sprinkles bg, border_color and font_color now interpret "transparent" as a valid color. In HTML, it is interpreted as "rgba(255,255,255,0)"; in LaTeX it is interpreted as "".
  • New Sprinkle: sanitize. Defaults to FALSE and replaces automatic sanitization of text in LaTeX output via Hmisc::latexTranslate. This is not backward compatible with 0.7.0, but is consistent with earlier versions of pixiedust. You must opt in to sanitization now.
  • New Sprinkle: sanitize_args. Takes a list of arguments to pass to Hmisc::latexTranslate, allowing sanitization to be extended to character sets defined by the user.

0.7.0 (15 April 2016)

  • Backward compatibility: The way pixiedust deals with colors has changed. If you are using custom defined colors in your LaTeX preamble, these will no longer work. pixiedust will only accept colors names in colors(), or in the rgb, rgba, #RRGGBB, or #RRDDBBAA formats. This only affects LaTeX output, and provides a better interface for ensuring all HTML and LaTeX output are as similar as possible.
  • Added justification for tables. Use the justify argument in dust and the justify sprinkle to move the table to the left, or right side of the page. Defaults to centered.
  • Added auto-detection of the print method. When a document is being knit, the output format is read from knitr::opts_knit$get(""). If this resolves to NULL, the value of getOption("pixiedust_print_method") is used.
  • Added docx as a valid print method, which is synonymous with markdown.
  • labels for HTML and LaTeX tables are automatically generated when label = NULL. First, an attempt is made to generate a label from the chunk label, and if that fails, a label is generated from getOption("pixie_count")
  • Added default horizontal alignments for HTML tables
  • Added default rounding for numerical values. If the user does not give a value, the value of getOption("digits") is used. This effectively prints as many decimal places as would be printed in the console.
  • Sprinkle recycling is added with recycle argument.
  • Fixed coordinate pairs is added with fixed argument.
  • Added recognition of all colors in colors()

0.6.3 (8 April 2016)

  • Converted dust, sprinkle functions, and print to S3 methods. This allows for lists of data frames to be processed as separate tables.
  • Added dust.grouped_df to give the option of ungrouping a grouped_df object, or splitting it.
  • Added the bookdown attribute (and sprinkle) to allow use with the bookdown package.
  • Added labeling.
  • Added caption, hhline, and float as sprinkles.
  • Changed the default colors for bg_pattern to "#FFFFFF#" and "#DDDDDD". The gray in this pattern is a little lighter and should do better when printed in black and white.

0.6.2 (15 March 2016)

  • Implemented a new printing method that makes use of the hhline LaTeX package. This allows borders to be drawn over background colors. In the existing method, the cell borders are hidden by background colors. The hhline method can be used by setting options(pixiedust_latex_hhline = TRUE).

0.6.1 (8 January 2016)

  • Table Captions are now implemented.
  • Added parameter to place LaTeX tables in a float environment. This was necessary to make table captions functional in non-longtable situations.

0.6.0 (09 December 2015)

  • LaTeX output is fully implemented
  • tabrowsep element was removed from the dust object since it apparently isn't a real thing.
  • Implemented rotated text.
  • Pushed version to 0.6.0

0.5.6 (06 December 2015)

  • Finished the borders for LaTeX output. This completes the baseline LaTeX output.

0.5.5 (04 December 2015)

  • Revamped the LateX output again, pretty much started over entirely. But now the only thing missing is cell borders, and my previous work will accommodate those.
  • Added tablewidth, tabcolsep, and tabrowsep elements to the dust object. tablewidth allows the user to define cell width in terms of a percentage of the total expected table width. Not really recommended, but at least preserves some continuity between HTML and LaTeX output.
  • tabcolsep and tabrowsep control the distance between columns and rows in tables, but this feature isn't yet implemented.
  • Documentation is lacking on tablewidth, tabcolsep, and tabrowsep

0.5.4 (10 November 2015)

  • Added the font_family sprinkle for HTML output

0.5.3 (5 November 2015)

  • Due to a great deal of difficulty getting the last couple of features to play nicely, I decided to take a different approach to the LaTeX output. Most features are available, but I have yet to include column widths, column heights, or multirow output.
  • An option is added to the print method that turns off the knitr::asis_output return. The motivation behind this was to be able to use the HTML code in shiny applications.

0.5.2 (4 November 2015)

  • Longtable support is added
  • Documentation on cell borders is up to date

0.5.1 (3 November 2015)

  • Cell borders. Documentation still needs review.

0.5.0 (Change Log Highlights since last CRAN Release)

  • pixiedust no longer uses the + operator.
    Please use %>% instead.
  • Complete support for HTML tables is available.
  • Limited support for LaTeX tables is available.
  • New vignette: Advanced Magic.
  • Added the replace sprinkle to replace values in table columns, rows, or cells.
  • Added the longtable sprinkle: allows tables to be printed in multiple sections.
  • Added the na_string sprinkle.
  • Added support for multirow headers and footers.
  • Added support for multicell output using the merge sprinkle.
  • Added an option glance_foot, which places model summary statistics in the foot of a table.
  • Added options for including variables labels and more detailed descriptions of factors and levels.
  • Introduces "medleys", functions that can apply multiple sprinkles to a dust object in a single line.
  • Adds method

0.4.3-0 (13 October 2015)

  • The majority of LaTeX sprinkles are available, with the exception of borders, longtable, merging cells, and rotated text.

0.4.2-0 (5 October 2015)

  • Added basic medleys
  • Adds method. Closes Issue #33

0.4.1-0 (1 October 2015)

  • Started LaTeX Output

0.4.0-0 (25 September 2015)

  • Fixed a bug described in Issue #26
  • Changes to Advance Magic vignette use a linear model and glance statistics for examples.

0.3.1-0 (18 September 2015)

  • Glance footer is implemented. Vignettes need to be updated
  • Variable labels and levels are implemented (well ahead of schedule!). Vignettes need to be updated

0.3.0-0 (15 September 2015)

  • Multi-cell output for HTML is fully supported.
  • Data frame row names may be captured in the output with dust argument keep_rownames
  • A new sprinkle is added. na_string defaults to "", and controls how NA is printed in tables.

0.2.0-1 (31 August 2015)

  • Multi-cell output is functional for HTML, Markdown, and Console output
  • A poor example is added to the advancedMagic vignette, but a better example is really needed.

0.1.1-7 (17 August 2015)

  • Finished the Advanced Magic vignette, which serves as the tests for advanced output since I haven't bothered to code a way to check the results directly.
  • Configure the repository for coveralls.
  • Adds covr and Hmisc to Suggests:

0.1.1-6 (12 August 2015)

  • Removed 'longtable' option from print.dust and made it a sprinkle. This allows it to be used without having to explicitly call print.
  • Implemented longtable capacity. Users may now break tables into multiple divisions of either a default size (25 rows for console, markdown, or HTML) or a user-specified number of rows.
  • Began an "advanced magic" vignette to demonstrate the capabilities of longtable and eventually multicolumn and multirow support. Similar vignettes will be needed for console, markdown, and html output, though not all of them will need to be bundled with the package.
  • Added the roundSafe helper function to allow rounding to succeed while skipping true character values.

0.1.1-5 (11 August 2015)

  • Added the longtable option to print.dust. Not yet active, but lays the groundwork for multipage tables.
  • Added multirow headers and footers (but not interfoot)
  • Added the redust function for adding and/or switching table components. For example, adding a multirow header, or a foot.

0.1.1-4 (5 August 2015)

  • Added the replace sprinkle to replace values in table columns, rows, or cells. This closes Issue #12

0.1.1-3 (4 August 2015)

  • Optimizations related to removing ifelse calls.
  • Initial values for table attributes are now stored as "" instead of NA. This increases the object size, but cuts down on the processing time.
  • Removed object element from the dust object. In Issue #13, matthieugomez pointed out that very large models could create storage space problems. There's no sense in keeping an extra copy of the model object.
  • Removed the +.dust method and rewrote the sprinkles as pipable functions. This resolves Issue #8

0.1.1 (3 August 2015)

  • Added the necessary fields to DESCRIPTION to get the vignettes to build.

0.1.0 (1 August 2015)

  • CRAN checks are passed. Prepared for release.

0.0.0-9 (31 July 2015)

  • Finished tests
  • Finished vignettes

0.0.0-8 (30 July 2015)

  • Finished HTML rendering
  • Adds pixiedust vignette
  • Removes old vignettes

0.0.0-7 (29 July 2015)

  • Replace nearly all dust bunny functions with sprinkle
  • Replace dust_print_method with sprinkle_print_method
  • Replace dust_colnames with sprinkle_colnames
  • It occurred to me as I studied the code base that instead of rows and cols in the ... argument of the dust bunnies, it made more sense to add the dust bunnies in ... with formal arguments for row and col. I also came up with the idea of naming the package pixiedust and sprinkling the dust around. It sounded like fun so let's hope CRAN lets me get away with it.
  • All functionality has been rewritten to support the pixiedust paradigm, but new tests and vignettes need to be written to confirm that it all works.
  • R CMD check has NOT been run.

0.0.0-6 (28 July 2015)

  • Adds dust_rotate_text

0.0.0-5 (27 July 2015)

  • Adds dust_cell_valign
  • Adds dust_border_collapse
  • Adds dust_table_border
  • Adds dust_cell_border
  • Adds dust_cell_padding

0.0.0-4 (26 July 2015)

  • Improved the Dustbunnies vignette to use a color coded table indicating which dust bunnies are planned, available, and functional for different printing methods.
  • Dropped leading zeroes from the version number.
  • Adds dust_font_color, dust_font_size
  • Adds dust_cell_height, dust_cell_width

0.0.0-003 (25 July 2015)

  • Adds halign and valign attributes to dust$obj. valign is not yet implemented.
  • Adds dust_cell_halign
  • Adds dust_head_halign
  • Adds dustbunnies vignette
  • Removed the col_names attribute of the dust object and replaced it with the head object. The head object is a data frame holding the attributes of the table header.
  • Renamed the obj attributes of the dust object to body.
  • Adds a lot of tests
  • Adds dust_cell_bg and dust_bg_pattern

0.0.0-002 (24 July 2015)

  • 'col_namesattribute is now named. The names are the original column names from thebroom` output.
  • Adds dust_fn
  • Adds dust_bold
  • Adds dust_italic
  • Adds dust_print_format
  • Imports knitr
  • Imports lazyWeave::pvalString

0.0.0-001 (23 July 2015)

  • Adds dust and print.dust.
  • Only the method for printing to the console is available.
  • +.dust added
  • dust_colnames added

Reference manual

It appears you don't have a PDF plugin for this browser. You can click here to download the reference manual.


0.9.1 by Benjamin Nutter, 9 months ago

Report a bug at

Browse source code at

Authors: Benjamin Nutter [aut, cre] , David Kretch [ctb]

Documentation:   PDF Manual  

GPL (>= 2) license

Imports broom, checkmate, htmltools, knitr, labelVector, magrittr, reshape2, scales

Suggests dplyr, rmarkdown, testthat

Imported by HydeNet.

See at CRAN