nutterb / pixiedust

Tables So Beautifully Fine-Tuned You Will Believe It's Magic.
179 stars 18 forks source link

How should `pixiedust` handle `grouped_df` objects #47

Closed nutterb closed 8 years ago

nutterb commented 8 years ago

A user e-mailed me with a question about grouped_df objects and how pixiedust handles them. At the very least, I need to put in a check to stop grouped_df objects from throwing a "Duplicate identifiers" error. But there's still an interesting question of how these objects should be handled and how to decide to if the object should be ungrouped or if it should be split (and if split, how to apply subsequent sprinkles to each component.

I think the best of all worlds would be (yet) another argument in dust, perhaps ungroup=TRUE. When TRUE, a grouped_df is ungrouped and life goes on as normal. when ungroup=FALSE, split the data frame by the grouping variables, and then teach sprinkle to apply each of the sprinkles to each element in the list. Then again, the apply over the list could be problematic since the number of rows in each element could be different.

library(pixiedust) library(broom) library(dplyr)

Grouped <- group_by(mtcars, am) %>% do(tidy(lm(mpg ~ qsec + wt + factor(cyl), data = .)))

* pixiedust doesn't like "grouped_df"

dust(Grouped)

* If you want the full table, simply ungrouping it will do

* But I'll file an issue. pixiedust should handle this

* more elegantly than it does.

dust(ungroup(Grouped))

* If you want separate tables for each grouping,

* you're probably better off breaking this into a

* list

EachModel <- split(Grouped, list(Grouped$am))

* Now you can apply sprinkles with lapply

lapply(EachModel, dust) %>% lapply(sprinkle, cols = 3:5, round = 3) %>% lapply(sprinkle, cols = 6, fn = quote(pvalString(value))) %>% lapply(print) %>% invisible()

nutterb commented 8 years ago

I'm going to introduce methods to pixiedust.

The current dust method will become dust.default.

The other important method will be dust.list, which will simply run dust in an lapply. It will first check that all of the objects in the list inherit the data.frame class. It returns an object of class dust_list

There will also be a dust.grouped_df class that will come with an argument which determines if the object should be ungrouped or split. If ungrouped, it will then call dust.default, otherwise it will call dust.list.

Each of the sprinkles will become a method as well, with dust.default, and dust.dust_list.

An additional print method print.dust_list will also be necessary, but can probably just use lapply

nutterb commented 8 years ago

Just to wrap up loose ends, I did not keep the restriction thst every element in the list needed to be a data frame. But we can dust lists now.