Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

method based reporting #41

Closed
jeroen opened this issue Feb 27, 2012 · 5 comments
Closed

method based reporting #41

jeroen opened this issue Feb 27, 2012 · 5 comments
Labels

Comments

@jeroen
Copy link

jeroen commented Feb 27, 2012

Currently rapport() always assumes a dataframe, similar to e.g. ggplot2. It would be nice if there would also be functionality that uses method-based reporting, similar to R's plot() and print() methods. There are a lot of advantages to levering R's class/method system. It will be easier to use for the user, and allow package developers to create report templates for their custom objects based on the class of the object, in the same way as they might define summary(), print() and plot() methods for their objects.

I think it would not be too hard to introduce this. You would start with a generic method:

report <- function (data, template, package ...) {
    UseMethod("report")
}

and define some basic reports for standard methods:

report.numeric <-function(data, template = "default", package="rapport", digits = 5, align = "right", ...){
    #the default is to use default_numeric.tpl from the package 'rapport'
    tpl <- system.file(paste(template, "numeric.tpl", paste="_"), package=package)
    stopifnot(file.exists(tpl));
    rapport(tpl, data=data, digits=digits, algin=align, ...);
}

You would define one or more, flexible templates standard templates for the standard R classes in e.g. report.data.frame. report.list, report.matrix, etc. This way the user can do:

report(cars);
report(cars, digits=10);
report(cars, template="descriptives", somecustomarg=TRUE);

Additionaly, this allows package developers to include reporting templates in their packages. Hence Douglas Bates could define a function like:

report.lmer <- function(data, template = "multilevel", package="lme4", plotranef=TRUE, descriptives=TRUE, ...){
   tpl <- system.file(template=template, package=package);
   stopifnot(file.exists(tpl));
   rapport(tpl, data=data, plotranef=plotranef, descriptives=descriptives ...);
}

So the advantage of this is not only that a user can do:

fm1 <- lmer(Reaction ~ Days + (Days|Subject), sleepstudy);
print(fm1);
report(fm1);

And get something nice 'out of the box' as defined by Douglas bates. If none of the attached packages are defining a report.lmer, it will natually fall back on report.list, that might try to do something standard. Also you can easily check the required arguments for a report for a certain class:

args(report.lmer)
@aL3xa
Copy link
Contributor

aL3xa commented Feb 28, 2012

Now that's what I call suggestion! =) @jeroenooms thanks for checking it out. This week is pretty busy both for @daroczig et moi, but surely we'll reconsider your suggestions as they seem very reasonable (as always) and very manageable too.

@jeroen
Copy link
Author

jeroen commented Feb 29, 2012

Sure, I'm drowning in work myself as well, just a suggestion to keep in the back of your mind :-)

@daroczig
Copy link
Member

daroczig commented Mar 1, 2012

That would be a cool feature indeed, thanks for that great suggestion @jeroenooms :)

As I am quite impressed with your detailed usage case/demo (despite the fact that I did not ever want to use rapport against anything except for data frames), I would love to start implementing this next week. Will give some feedback soon - maybe with a brand new git branch :)

Will discuss details with @aL3xa starting from Monday, but if you are also interested in this stuff, pls do not hesitate to hop in.

@daroczig
Copy link
Member

I started to implement this a few months ago, but stucked while thinking if this should be really rapport's task.

Meanwhile I started to separate the making R objects look cool for human beings calls to a separate package, which might fulfill your requirements. E.g.:


> pander(list(a = 'foo', b = list('bar')))


  * **a**: foo
  * **b**:

      * bar


<!-- end of list -->


> pander(mtcars[1:2,1:3])

--------------------------
              mpg cyl disp
------------- --- --- ----
Mazda RX4     21  6   160 

Mazda RX4 Wag 21  6   160 


> pander(table(mtcars$am, mtcars$gear))

--------
  3  4 5
- -- - -
0 15 4 0

1 0  8 5


> pander(lm(mtcars$hp~1))

------------------------------------------------
            Estimate Std. Error t value Pr(>|t|)
----------- -------- ---------- ------- --------
(Intercept) 1.5e+02   1.2e+01   1.2e+01 2.8e-13 


    Table: Fitting linear model: mtcars$hp ~ 1

While this pkg is under heavy development and new features are added daily (like "exported" tables could be emacs-like grid tables or simple ones besides the default multiline Pandoc format), I can imagine using pandoc/pander for showing R objects in human readable format - not to mention its potentials like exporting the resulting markdown to e.g. pdf, docx etc. This latter could be done via a brew like call or an ascii:report object stucture.

I would love to hear your feedback about this @jeroenooms, as I think package maintainers might write some pander.foo methods easier then providing templates for their custom classes.

@daroczig
Copy link
Member

I think pander does that after all, will tweak rapport further on user request.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants