Report Generation

John Harrold & Anson Abraham

2019-10-14

Introduction

Reporting is implemented using the officer package. Officer provides a lot of control over the generation of both Word and PowerPoint documents. If you feel comfortable programming in R, you can simply use that package directly. Currently ubiquity has support for generating PowerPoint output. Trying to keep track of different slide layouts and their indices can be cumbersome. The following functions have been created to allow slides to be created easily:

The workshop (http://workshop.ubiquity.grok.tv) provides an example of how to use these functions. To make a copy of an example script run the following:

library(ubiquity)
fr = workshop_fetch(section="Reporting", overwrite=TRUE)

This should create the following script

Creating a report

The first step is to initialize a report:

system_new(file_name="system.txt", system_file="mab_pk", overwrite = TRUE)
cfg = build_system(system_file = "system.txt")
cfg = system_report_init(cfg)

Content type

With the report created we can begin adding slides. There are several diffent slide formats with different placeholders for content. Each placehodler can contian a different type of content (text, list, image file, etc). The following list provides a the available content types followed by the format of the content:

Adding slides

First you may want to add a title slide to the presentation:

cfg = system_report_slide_title(cfg, 
           title     = "Generating Inline Reports",
           sub_title = "A Working Example")

Next you may want to add an overview of your analysis. The content slide provides one placeholder that you can fill with any of the above content types.

cfg = system_report_slide_content(cfg, 
           title     = "Single text area",   
           content   = "This vignette provides examples of how to add different types of slide content" )

The default content type is text, but you may want to add a list. Lists are formatted as vectors with paired elements. The first element contains the indention level and the second element contains the actual text:

lcont = c(1, "Top level item", 
          2, "This is a sub bullet",
          2, "This is another sub bullet")
cfg = system_report_slide_content(cfg, 
           title        = "Lists are pretty straight forward",      
           content_type = "list",
           content      = lcont)

If you are running simulations and want to dump ggplot figures to a file, that is pretty easy as well. Here we will simulate a single dose:

parameters = system_fetch_parameters(cfg)
cfg = system_zero_inputs(cfg)
cfg = system_set_bolus(cfg, state = "At",
                           times  = c(  0.0),
                           values = c(400.0))

cfg=system_set_option(cfg, group  = "simulation",
                           option = "output_times",
                           value  = seq(0,60,.1))

som = run_simulation_ubiquity(parameters, cfg)

Then we can plot the response in ggplot:

myfig = ggplot() + 
        geom_line(data=som$simout, aes(x=ts.days,   y=C_ng_ml), color="red")  +
        xlab("Time (days)")+
        ylab("C (ng/ml) (units)")
myfig = gg_log10_yaxis(myfig, ylim_min=1e3, ylim_max=1e5)
myfig = prepare_figure("present", myfig)

Then that figure can be added to a slide:

cfg = system_report_slide_content(cfg, 
           title        = "ggplot objects can be inserted directly", 
           content_type = "ggplot",
           content      = myfig)

You can also pull image content from files as well using the imagefile content type.

cfg = system_report_slide_content(cfg, 
           title        = "Images can be inserted from files", 
           sub_title    = "But the image should have the same aspect ratio as the placeholder", 
           content_type = "imagefile",
           content      = system.file("ubinc", "images", "report_image.png", package="ubiquity"))

The benefit of using ggplot is that it will automatically size the image to the dimensions of the placeholder. To use an image file the image file needs to have the same aspect ratio as the placeholder you want to put it in.

Tabular data can be include too. The simplest method is to use the table content type and supply a list with an element named table containing a data frame with the tabular information you want to display:

tcont = list()
tcont$table = parameters
cfg = system_report_slide_content(cfg, 
           title        = "Simple Tables", 
           content_type = "table",    
           content      = tcont)

This may not be the most attractive way to display tabular information, and for smaller tables it may be a bit poorly formatted. As an alternative the flextable package can be used by specifying that content type:

tcont = list()
tcont$table = parameters
cfg = system_report_slide_content(cfg, 
           title        = "Flextables", 
           content_type = "flextable",    
           content      = tcont)

To provide a little more formatting, two column masters are provides. The content_type argument indicates the type of text that can be included. It should be either "list" or "text". If the left or right content is to contain a table or figure it can be overwritten.

cfg = system_report_slide_two_col(cfg,
       title                  = "Two columns of lists",      
       sub_title              = NULL, 
       content_type           = "list", 
       left_content           = lcont,
       right_content_type     = "flextable",
       right_content          = tcont)

You can specify column headers if you like. These be text, imagefile, ggplot, table or flextable.

cfg = system_report_slide_two_col(cfg,
       title                  = "ggplot vs imagefile",      
       sub_title              = NULL, 
       content_type           = "list", 
       left_content_header    = "Image file",
       left_content_type      = 'imagefile',
       left_content           = system.file("ubinc", "images", "report_image.png", package="ubiquity"),
       right_content_header   = "ggplot object",
       right_content_type     = "ggplot",
       right_content          = myfig)

Saving slides

Finally, after you have added all of your sldies, you will want to put them in a file:

system_report_save(cfg, output_file = "report_vignette.pptx")

Using custom template

To use a custom template for your organization you need to do the follwoing:

  1. Create a template with the appropriate slide masters
  2. Create a layout file with mapping information
  3. From this template you need to map the indices in the slide to elements the ubiquity reporting functions expect to find
  4. Initialize a report indicating that you want to use this new template and add elements to the report

Creating the template for your organization:

Using your organizational template create slide masters below with the content elements to the right. The title and subtitle elements of the title_slide and section_slide should be of the type ctrTitle and subTitle, respecitvely. For the rest of the slides the title elements should be of the type title, and the other elements should simply be of type body. The format of the body elements should be plain text unless identified parenthetically below.

Master layout name Content Elements
title_slide title, subtitle
section_slide title, subtitle
content_text title, subtitle, main content
content_list title, subtitle, main content (list)
two_content_list title, subtitle, left, right, left body (list), right body (list)
two_content_text title, subtitle, left, right, left body, right body
two_content_header_list title, subtitle, left header, right header, left body (list), right body (list)
two_content_header_text title, subtitle, left header, right header, left body, right body
title_only title

Creating the layout file for the template

Each element in a master is identified with an index number (index) and placeholder label (ph_label). These values are asigned as the master slide is built, so it can be difficult to find this information through PowerPoint. If you named your template mytemplate.pptx, then you can have ubiquity produce a slide deck with the masters annotated so you can identify these values:

This should create a file called layout.pptx that has the layout name of each slide master in the title. Both the ph_label and index of each element will be identified. These slides should look something like:

Master slide layouts

Master slide layouts

Mapping your layout to ubiquity functions

To map your layout information you should use the myOrg template:

This should create the file myOrg.R in the current directory. You can edit this file and go to the function named org_pptx_meta. This returns the variable meta which contains this mapping information. You need to look at the information in layout.pptx and make sure it matches the information returned in meta.

Using your own template

To use your own template you simply need to source the myOrg.R file at the top of your script and then initialize the report using your own template (mytemplate.pptx) and the meta information returned from org_pptx_meta.

Now you can use the other reporting functions to add slides to the default report.