5 R Markdown

5.1 Scheduling

R Markdown reports that are published with source code can be re-executed by RStudio Connect. See section 3.4.2 to learn how to publish with source code.

Re-executing content can either be done manually or on a schedule. After navigating to the “Schedule” pane in the configuration window, you might see “The source code for this content was not published. The output cannot be refreshed.” If this is the case, then you will need to publish source code before it is possible to schedule your content.

Schedule pane with no source code

Similarly, Shiny applications or R Markdown documents with a Shiny runtime (Shiny documents) cannot be scheduled. Shiny assets show the latest data each time they are refreshed.

Schedule pane for a Shiny document

In other cases the Schedule pane provides options to schedule your asset for execution on RStudio Connect.

Schedule pane showing all options

5.1.1 Date and Time

The start date and time defaults to the current user’s date, time, and time zone. The schedule will be built off of this date and time. Take care to keep in mind how daylight savings time (DST) might affect the actual execution time of the report.

If you choose a start date and time in the past, execution will begin at the first future execution that satisfies “Schedule Type,” measured from the time that changes are saved.

5.1.2 Schedule Type

The schedule type and related fields will determine how frequently the R Markdown document is executed by RStudio Connect. Using the “Date and Time” above as an anchor, “Schedule Type” defines the time interval between executions.

The following interval configurations are all supported:

  • defined in minutes
    • e.g.: “every 15 minutes”
    • e.g.: “every 90 minutes”
  • defined in hours
    • e.g.: “every 3 hours”
    • e.g.: “every 25 hours”
  • defined in days
    • e.g.: “every 2 days”
    • e.g.: “every 40 days”
  • every weekday
    • e.g.: “Monday, Tuesday, Wednesday, Thursday, Friday”
  • defined in weeks (on select days of the week)
    • e.g.: “every 2 weeks on Tuesday and Thursday”
    • e.g.: “every 8 weeks on Friday”
  • semi-monthly (1st and 15th)
    • e.g.: “on the 1st and 15th of every month”
  • semi-monthly (14th and last)
    • e.g.: “on the 14th and last day of every month”
  • monthly on a given day of the month
    • e.g.: “every 2 months on the 3rd”
    • e.g.: “every 8 months on the 30th”
  • monthly on a week / day
    • e.g.: “every 3 months on the 3rd Tuesday of the month”
    • e.g.: “every 9 months on the 1st Saturday of the month”
  • defined in years
    • e.g.: “every 2 years”
    • e.g.: “every 8 years”

5.1.3 Publish Output

When content executes, you can decide whether or not the output should be saved and published to RStudio Connect. If you opt not to have output published after it is generated, any emails will be sent and any side-effects such as database writes will occur, but the report output will not be saved on Connect. Further, there will be no output history (See section 5.2).

In order to save and publish output, as well as track the history of output on Connect, keep the “Publish Output” box checked.

5.1.4 Send Email

This section of the Schedule configuration determines if and where emails will be delivered after execution. If checked, the owner of the content will always be notified unless they opt out. Further, content output can be sent to:

  • all collaborators
  • all viewers
  • named additional recipients

By default the rendered content will be attached and RStudio Connect will generate a standard subject line and email body. For more information on the ability to customize this email, see the section on email customization.

If you are having difficulty sending emails, contact your RStudio Connect administrator.

5.2 Report History

You can view past renders of R Markdown content in RStudio Connect using the History tool. This includes both manually triggered and scheduled execution of content (See section 5.1).

To access the history of an R Markdown report, browse to the “More” button (indicated by ellipsis in a circle) and select “History.”

Navigate to R Markdown history

This will open up a dialog to select the output bundles from previous executions of this report. The latest execution is in bold and the currently visible version of the output is highlighted.

R Markdown history selection

Different variants of a parameterized report will have a separate rendering history associated with them.

R Markdown history selection for a report variant

Each collection of output is saved to disk and is available at a unique URL, along with any output files (See section 5.4). Permissions for saved output will be the same as permissions for the “parent document” and the source code that is stored on Connect.

5.3 Output Metadata

We normally think of R Markdown documents as producing a single output artifact, such as an HTML or PDF file. The rmarkdown package allows report authors to emit additional output metadata from their report. RStudio Connect takes advantage of this metadata, allowing output files, custom email subjects, and additional email attachments.

There are two ways to set output metadata: in the YAML header and in R code chunks.

The YAML header is a good place to configure default values for metadata that you always want to emit. All output metadata lives under the rmd_output_metadata section in the YAML:

---
title: "Report Title"
rmd_output_metadata:
  rsc_email_subject: Quarterly Department Metrics
---

You can also use R code to set output metadata. This is useful if you want metadata to vary based on conditions or variables within your code.

changePercent <- 20
subject <- paste("Sales changed by ", changePercent, "%", sep = "")
rmarkdown::output_metadata$set(rsc_email_subject = subject)

Your R code can also read the current state of your output metadata. This can help you gradually alter this information as the report runs.

subject <- rmarkdown::output_metadata$get("rsc_email_subject")
if (changePercent > 10) {
    subject <- paste(subject, "Exceeding goals!")
    rmarkdown::output_metadata$set(rsc_email_subject = subject)
}

The rmd_output_metadata names starting with rsc_ are reserved for use with RStudio Connect.

5.4 Output Files

5.4.1 Introduction to Output Files

Output files are files that live alongside your rendered report. They could be plots, data files, or other artifacts generated from the R code in your report. Output files will be available via HTTP, and they will be versioned in the same way as your report. Output files are also subject to the same access controls as your report.

Connect will not process any output files that exist outside the working directory of the report that is rendering. That means that you cannot use absolute paths (e.g., /root/file.csv) or relative paths (e.g., ../file.csv).

5.4.2 How to Work with Output Files

There are two ways to specify which files should be treated as output files. The first is to list the file names in the R Markdown YAML header’s rmd_output_metadata section under rsc_output_files, like so:

---
title: "Report Title"
rmd_output_metadata:
  rsc_output_files:
    - "data.csv"
---

rsc_output_files takes a list of names of files that should be available after the report has rendered. If you list a file that does not exist after rendering your report, Connect will log a message but continue trying to processing the other files listed. If the output files are not generated during the rendering of your report, then you will also need to list them as resource files when you upload your report to Connect. For more information on resource files, see Section 5.5.

It is also possible to specify the list of output files from R code. For example:

rmarkdown::output_metadata$set(rsc_output_files = list("data1.csv", "data2.csv"))

For nested files, the output directory will maintain the folder structure you provide. To add nested files include the relative path:

rmarkdown::output_metadata$set(rsc_output_files = list("data1.csv", "./moreData/data2.csv",
                              "./moreData/EvenMoreData/data3.csv")

To include a directory:

rmarkdown::output_metadata$set(rsc_output_files = list.files("./myDirectory", recursive = TRUE,
                               full.names = TRUE))

You can also make a link to share an output file from your report using the standard Markdown links as supported in R Markdown. For example, if you want to share a file named data.csv, you make a link to it in your report like this:

Here is the data used in my report: [data.csv](data.csv)

Because output files are versioned along with the rendering of their report, they also benefit from historical views. In the example above, if you view a historical rendering of the report, when you click on the data.csv link, you will get a download of the file from the same point in time as the report.

5.4.3 Accessing output files over HTTP

Content deployed to http://connect.mycompany.com/content/42/ will have its output files available under that URL path. An output file named daily-summary.csv will be available at the URL http://connect.mycompany.com/content/42/daily-summary.csv.

The URL for your content is the same as its “Open Solo” location and is available in the RStudio Connect dashboard.

5.5 Resource Files

If you want RStudio Connect to host a file that you have in your report’s source directory on your computer, and that file is not generated by the report when you render it, then you will need to mark that file as a resource file. Like an output file, a resource file can be a plot, a data file, or any other artifact that exists as a file. You can use the RStudio IDE to select resource files, or you can list them in the R Markdown header:

---
title: "Report Title"
rmd_output_metadata:
  rsc_output_files:
    - "data.csv"
resource_files:
  - "data.csv"
---

Unlike rsc_output_files, the resource_files key is not nested under rmd_output_metadata. If you do not list your resource files under resource_files, then you will need to add them manually using the “Add More…” button when deploying from the IDE. See Section 3 for more information on publishing additional resource files.

5.6 Email Customization

5.6.1 Email Subject

You can customize the subject line used when an email of a report is generated. RStudio Connect uses the output metadata entry named rsc_email_subject as email subject. A report without an rsc_email_subject entry uses its published document name.

Use the YAML header to specify a simple, static text override of the email subject:

---
title: "Report Title"
rmd_output_metadata:
    rsc_email_subject: "My Email Subject Goes Here"
---

Set the email subject in an R code chunk if you need to dynamically build the subject:

changePercent <- 20
subject <- paste("Sales changed by ", changePercent, "%", sep = "")
rmarkdown::output_metadata$set(rsc_email_subject = subject)

The RSC_EMAIL_SUBJECT environment variable contains the name of your published report, which also acts as the default email subject. This environment variable is helpful if you want to add, but not fully replace the subject.

changePercent <- 20
defaultSubject <- Sys.getenv("RSC_EMAIL_SUBJECT")
subject <- sprintf("%s changed by %d%%", defaultSubject, changePercent)
rmarkdown::output_metadata$set(rsc_email_subject = subject)

You can also read the current subject from the output metadata to incrementally compose a final subject.

changePercent <- 20
subject <- rmarkdown::output_metadata$get("rsc_email_subject")
subject <- sprintf("%s changed by %d%%", subject, changePercent)
rmarkdown::output_metadata$set(rsc_email_subject = subject)

5.6.2 Email Body

A report can customize the message body used when an email for that report is sent. RStudio Connect uses the output metadata entry named rsc_email_body_text for plain-text bodies and rsc_email_body_html for HTML bodies. A report with neither entry uses an automatically generated, plain-text body with a link to the report’s URL.

5.6.2.1 Text Message Bodies

Use the YAML header to specify a simple, static text override of the email body:

---
title: "Report Title"
rmd_output_metadata:
    rsc_email_body_text: "Here is my custom email message.
    
    YAML requires a full blank line like the one above to start a new line."
---

The message in the email client would look similar to the following:

Here is my custom email message.
YAML requires a full blank line like the one above to start a new line.

Set the body text in an R code chunk if you need to dynamically build the message:

changePercent <- 20
body <- paste("Sales changed by ", changePercent, "%.", sep = "")
rmarkdown::output_metadata$set(rsc_email_body_text = body)

You can also read the current body from the output metadata to incrementally compose a final body.

widgetOrders <- 42
body <- rmarkdown::output_metadata$get("rsc_email_body_text")
body <- sprintf("%s\n\nThere were %d widget sales.", body, widgetOrders)
rmarkdown::output_metadata$set(rsc_email_body_text = body)

The glue package can help with more complicated formatting.

library(glue)

widgetOrders <- 42
changePercent <- 20
body <- glue(
  'Sales changed by {changePercent}%.\n\n',
  'There were {widgetOrders} widget sales.')
rmarkdown::output_metadata$set(rsc_email_body_text = body)

5.6.2.2 HTML Message Bodies

The rsc_email_body_html attribute specifies an HTML-formatted message body. RStudio Connect sets the content-type of the message so that most email clients will display the HTML message correctly.

Use rsc_email_body_text together with rsc_email_body_html to supply text that older email clients can display while allowing newer clients to display your rich content.

The YAML header can specify a simple, static HTML override of the email body:

---
title: "Report Title"
rmd_output_metadata:
    rsc_email_body_html: "<strong>The new report is ready!</strong>"
---

You can build the HTML message dynamically:

library(htmltools)
changePercent <- 20
body <- paste(
  h1("Sales Update"),
  p("Sales changed by ",
    em(paste0(changePercent, "%"))),
  sep = "\n")
rmarkdown::output_metadata$set(rsc_email_body_html = body)

Composing and styling HTML email messages is different than building traditional web pages. Email messages cannot embed scripts nor reference external stylesheets. Email clients may implement additional restrictions.

Not all email clients display HTML messages exactly the same. Send yourself a test message to check basic formatting, then confirm with your audience that the message appears correctly in their email client.

5.6.2.3 Embedding Images in HTML Email

It is possible to embed images, such as plots, within HTML email, using the rsc_email_images attribute in rmd_output_metadata. The embedded image must have a Content ID that is used in the body of the HTML and when providing the image to rsc_email_images, and the image itself must be base64-encoded. Here is an example:

library(ggplot2)
library(htmltools)

# Create a plot.
car_plot <-
    ggplot(data = mtcars,
           aes(
               x = disp,
               y = hp,
               color = wt,
               size = mpg
           )) +
    geom_point()

# Save the plot to disk as a PNG image.
ggplot2::ggsave(
    "plot.png",
    plot = car_plot,
    device = "png",
    width = 5,
    height = 5,
    dpi = "screen"
)

# Encode the PNG image as base64.
plot_base64 <- base64enc::base64encode("plot.png")

# Construct the HTML email message.
message <- paste(h1("mtcars data plot"),
                 # Use the filename "plot.png" as the Content ID by using "cid:"
                 # in the image tag's "src" attribute:
                 p(img(src = "cid:plot.png")),
                 sep = "\n")

# Create the data structure to hold the embedded image.
images <- list(plot.png = plot_base64)

# Give RStudio Connect the message and image data for the HTML email.
rmarkdown::output_metadata$set(rsc_email_body_html = message)
rmarkdown::output_metadata$set(rsc_email_images = images)

R Markdown email table

R Markdown itself does not currently generate email-friendly HTML output, which is why RStudio Connect cannot use the generated report as the email body.

Building a correct, email-friendly HTML message with images can be complex, but the R package blastula, described in the next section, can simplify the process.

5.6.2.4 Simplifying HTML Email Creation with Blastula

The blastula package makes it easy to compose HTML email from R. It can style your message in a way that renders correctly across a variety of clients, and it can handle many of the details of structuring the HTML and embedding images.

Use blastula version 0.2.1 or newer.

# Blastula example adapted from https://github.com/rich-iannone/blastula

library(blastula)
library(formattable)

# Create a data frame.
df <- data.frame(
    Name = c(
        "Bob",
        "Ashley",
        "James",
        "David",
        "Jenny",
        "Hans",
        "Leo",
        "John",
        "Emily",
        "Lee"
    ),
    Overall = c("C", "A", "A", "C", "B", "B", "B", "A", "C", "C"),
    Q1_Sales = c(8.9, 9.5, 9.6, 8.9, 9.1, 9.3, 9.3, 9.9, 8.5, 8.6),
    Q2_Sales = c(9.1, 9.1, 9.2, 9.1, 8.9, 8.5, 9.2, 9.3, 9.1, 8.8),
    Projection = c(9, 9.3, 9.4, 9, 9, 8.9, 9.25, 9.6, 8.8, 8.7),
    Tracking = c(TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE),
    stringsAsFactors = FALSE
)

# Create an HTML table with `format_table()`.
formatted_table <-
    format_table(
        x = df,
        list(
            Overall =
                formatter("span",
                          style = x ~ ifelse(
                              x == "A",
                              style(color = "green", font.weight = "bold"), NA
                          )),
            area(col = c(Q1_Sales, Q2_Sales)) ~ normalize_bar("pink", 0.2),
            Projection =
                formatter(
                    "span",
                    style = x ~ style(color = ifelse(rank(-x) <= 3, "green", "gray")),
                    x ~ sprintf("%.2f (rank: %02d)", x, rank(-x))
                ),
            Tracking =
                formatter(
                    "span",
                    style = x ~ style(color = ifelse(x, "green", "red")),
                    x ~ icontext(ifelse(x, "ok", "remove"), ifelse(x, "Yes", "No"))
                )
        )
    )

# Create the Blastula email object.
message <- compose_email(
    body = "
  Hi Jim,

  The fiscal quarter closes next week. Here are the \\
  the sales rep numbers.\\


  {formatted_table}
  <br />
  Cheers,<br /> EVP of Sales"
)

# Use Blastula's message as the email body in RStudio Connect.
rmarkdown::output_metadata$set(rsc_email_body_html = message$html_str)
rmarkdown::output_metadata$set(rsc_email_images = message$images)

The output will be formatted for an email client:

R Markdown email table

You can also embed images and plots in your HTML email.

library(blastula)
library(ggplot2)

# Create a ggplot plot object.
car_plot <-
    ggplot(data = mtcars,
           aes(
               x = disp,
               y = hp,
               color = wt,
               size = mpg
           )) +
    geom_point()

# Use the `add_ggplot()` helper function inside the email message body.
email <- compose_email(
    body = "
  New data is available!

  This plot summarizes the new data:

  {add_ggplot(plot_object = car_plot, width = 5, height = 5)}

  Cheers
  "
)

# Give the HTML email data to RStudio Connect.
rmarkdown::output_metadata$set(rsc_email_body_html = email$html_str)
rmarkdown::output_metadata$set(rsc_email_images = email$images)

R Markdown email table

For consistency, you can always assign both rsc_email_body_html and rsc_email_images at the end of your R Markdown report when working with Blastula, even if initially it does not contain embedded images:

email <- blastula::compose_email(...)

rmarkdown::output_metadata$set(rsc_email_body_html = email$html_str)
rmarkdown::output_metadata$set(rsc_email_images = email$images)

See the blastula site at https://github.com/rich-iannone/blastula for more information and examples.

5.6.3 Including URLs and Other Details

You may want to customize your email with a link to the location of the report in RStudio Connect or to give your email recipients a way to manage their email subscription. RStudio Connect provides the R Markdown render with environment variables that can be referenced from your code.

Variable Name Example Value
RSC_REPORT_NAME "Quarterly Sales Summary"
RSC_REPORT_RENDERING_URL "http://example.com/content/42/_rev1/"
RSC_REPORT_SUBSCRIPTION_URL "http://example.com/connect/#/apps/42/subscriptions"
RSC_REPORT_URL "http://example.com/content/42/"

The final variable values may not be known prior to rendering. RStudio Connect provides the render placeholder values for these environment variables. The placeholder values are replaced when constructing the final email message.

Use the Sys.getenv() function to get the values for these environment variables in your report. When rendering your report outside of RStudio Connect, these environment variables will not have values. Use the second argument to Sys.getenv() to provide a temporary value.

# Use an example URL when rendering locally (not in RStudio Connect).
rendering_url <-
  Sys.getenv("RSC_REPORT_RENDERING_URL",
             "http://example.com/content/42/_rev123/")

You can use these variables anywhere within your email body or footer. The examples that follow use these variables to build a text or HTML message footer.

library(glue)

report_name <- Sys.getenv("RSC_REPORT_NAME")
report_url <- Sys.getenv("RSC_REPORT_URL")
rendering_url <-
  Sys.getenv("RSC_REPORT_RENDERING_URL",
             "http://example.com/content/42/_rev123/")
subscription_url <- Sys.getenv("RSC_REPORT_SUBSCRIPTION_URL")

widget_orders <- 42
change_percent <- 20
body <- glue(
    paste(
        'Sales changed by {change_percent}%.\n',
        'There were {widget_orders} widget sales.\n',
        '--',
        'This {report_name} document is available at {rendering_url}',
        'The latest published version is always available at {report_url}',
        'To stop receiving these emails, unsubscribe here: {subscription_url}',
        sep = '\n'
    )
)

rmarkdown::output_metadata$set(rsc_email_body_text = body)

5.6.4 Email Attachments

An attachment is an output file that will be attached to an emailed report. You can specify email attachment files in essentially the same way as output files, but instead of listing them under rsc_output_files, you list them under rsc_email_attachments. For example:

---
title: "Report Title"
rmd_output_metadata:
  rsc_output_files:
    - "data.csv"
  rsc_email_attachments:
    - "attachment_1.csv"
    - "attachment_2.csv"
---

In the example above, we are specifying the file data.csv to be an output file and the files attachment_1.csv and attachment_2.csv to be email attachments.

It is also possible to specify the list of email attachments from R code. For example:

attachments <- list("attachment_1.csv", "attachment_2.csv")
rmarkdown::output_metadata$set(rsc_email_attachments = attachments)

For nested files, include the relative path:

rmarkdown::output_metadata$set(
  rsc_email_attachments = list(
    "data1.csv",
    "./moreData/data2.csv",
    "./moreData/EvenMoreData/data3.csv"
  )
)

Attachments with the same filename but different directory paths are permitted but not recommended.

An email attachment will be accessible via HTTP just like an output file, and you can make a link to it in your report in the same way.

Some mail systems have limitations on attachments in email messages. Attachments from your report need to follow the restrictions enforced by your organization. Connect is not aware of those limitations. Please work with your systems administrators / IT organization if you have trouble delivering file attachments.

5.6.5 Suppressing Scheduled Email

Scheduled reports can be configured to automatically send email after generating their output. The author of the report can suppress this option by giving the rsc_email_suppress_scheduled metadata property a logical (Boolean) value.

Use the YAML header to set a default value for rsc_email_suppress_scheduled. If set to true and not altered by downstream code, the report will never permit email after scheduled execution. Any attempt to configure post-update emailing in the RStudio Connect dashboard will have no effect.

---
title: "Report Title"
rmd_output_metadata:
  rsc_email_suppress_scheduled: true
---

You can make this decision dynamically based on data available in your report. This example assumes email is suppressed by default (as in the YAML above) but triggered when some business condition is exceeded.

changePercent <- compute_weekly_sales_change()
if (changePercent < -5 || changePercent > 5) {
    #  email on substantial sales changes.
    rmarkdown::output_metadata$set(rsc_email_suppress_scheduled = FALSE)
}

5.6.6 Suppress Attaching Report To Email

By default, Connect adds the generated document as an attachment to email messages for that report. You can prevent this attachment from your R Markdown report by giving the rsc_email_suppress_report_attachment metadata property a logical (Boolean) value.

Use the YAML header to set a default value for rsc_email_suppress_report_attachment. A true value that is not later adjusted indicates that the generated content is never to be attached to email.

---
title: "Report Title"
rmd_output_metadata:
  rsc_email_suppress_report_attachment: true
---

You can also make an “attach or not” decision in R code.

rmarkdown::output_metadata$set(rsc_email_suppress_report_attachment = TRUE)

Attachments configured by the rsc_email_attachments metadata property (5.6.4) are still attached and not affected by the rsc_email_suppress_report_attachment setting.