R Markdown

R Markdown is an authoring format that enables easy creation of dynamic documents, presentations, and reports from R. It combines the core markdown syntax with embedded R code chunks.

The rmarkdown R package helps you create dynamic analysis documents that combine code, rendered output (such as figures), and prose. You bring your data, code, and ideas, and R Markdown renders your content into a polished document that can be used to:

Example R Markdown report.

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. Posit 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)
}
Note

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

Output files

Introduction to output files

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

Connect does 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).

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 logs a message but continues trying to processing the other files listed. If the output files are not generated during the rendering of your report, then you need to list them as resource files when you upload your report to Connect. See Resource Files for more information.

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

outputs <- list("categories.csv", "products.csv")
rmarkdown::output_metadata$set(rsc_output_files = outputs)

Output files can be contained within sub-directories. The relative directory structure is maintained.

outputs <- list("magazines.csv", 
    "./books/novels.csv", 
    "./books/young-adult/graphic-novels.csv")
rmarkdown::output_metadata$set(rsc_output_files = outputs)

To include a directory:

outputs <- list.files("./data", recursive = TRUE, full.names = TRUE)
rmarkdown::output_metadata$set(rsc_output_files = outputs)

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 get a download of the file from the same point in time as the report.

Accessing output files over HTTP

Content deployed to http://connect.mycompany.com/content/42/ has its output files available under that URL path. An output file named daily-summary.csv is 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 Connect dashboard.

Resource files

If you want 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 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 RStudio 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 need to add them manually using the Add More button when deploying from RStudio. See the Publishing from RStudio section for more information on publishing additional resource files.

Email customization

Posit Connect can send an email upon completion of scheduled execution or when manually requested in the dashboard. These emails, by default, contain a link to the report. However, it is possible to fully customize the email, and distribute results directly to users without requiring them to leave their inbox.

An email message is not automatically sent during publishing or when manually run in the dashboard.

Note

More information about Connect email configuration is found in the the Email section of the Admin Guide.

There are two approaches for customizing email in Connect. One approach is to directly set R Markdown Output Metadata. This option is the most flexible, but also the hardest to use. The second approach is to use the blastula package. Using the blastula package is the easiest way to get started and is recommended for most use cases.

Getting started with custom emails

To get started with custom emails, we recommend using the blastula package. The easiest way to start is by installing the package and using the included example:

install.packages("blastula")
blastula::prepare_rsc_example_files()

This command creates a new folder in your workspace with a number of example files. In general, the approach when using blastula is to create a new R Markdown document responsible for crafting the email. This R Markdown document is then attached to your original document by including the following code in the main R Markdown file:

library(blastula)
render_connect_email(input = "connect-example-email.Rmd") %>%
  attach_connect_email(
    subject = "Posit Connect HTML Email",
    attach_output = TRUE,
    attachments = c("dallas_home_sales.csv", "austin_home_sales.csv")
  )
Note

This code is an example from the final code chunk found in connect-example-main.Rmd Rendering the main report creates a preview of the custom email. When you publish to Connect, simply include the child R Markdown document responsible for the email as a supporting file.

Using R Markdown metadata

Instead of using the blastula package, it is possible to construct custom emails using R Markdown Output Metadata. A quick summary of the output metadata options are:

Option Description
rsc_email_subject A character string giving the email subject line
rsc_email_body_text A character string to be used as the plain-text body of the email
rsc_email_body_html A character string that results in HTML to be rendered in the body of the email
rsc_email_attachments A list of relative file paths for files to be attached to the email
rsc_email_images A named list, where the key matches the CID name of the image in the email body, and the object is a base64 encoded image.
rsc_email_supress_scheduled A boolean, whether to send the scheduled email (FALSE) or suppress the email (TRUE)
rsc_email_suppress_report_attachment A boolean, whether to include the rendered report as an attachment to the email

To set an option, use code like:

rmarkdown::output_metadata$set(rsc_email_subject = subject)

The following sections describe the individual options in more detail.

Email subject

You can customize the subject line used when an email of a report is generated. 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.

Note

The value of RSC_EMAIL_SUBJECT is computed when your report is rendered. Changes to the report name are incorporated into subsequent renderings.

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)

Email body

A report can customize the message body used when an email for that report is sent. 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.

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)

HTML message bodies

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

Note

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 or reference external stylesheets. Email clients might implement additional restrictions.

Note

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.

Embedding images in HTML email

Note

For emails including images or tables, we highly recommend using the blastula package.

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 Posit 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)

Including URLs and other details

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

  • RSC_EMAIL_SUBJECT

    The default subject used when sending email. Computed when your report is rendered.

    Example: "Quarterly Sales Summary"

  • RSC_REPORT_NAME

    The title of your content. Augmented with the variant name, when in use.

    Example: "Quarterly Sales Summary"

  • RSC_REPORT_URL

    The default URL for this content. Includes a path to the variant, when in use. Contains placeholder text when rendering and is replaced with the final URL when sending email.

    Example: "http://rsc.company.com/content/42/"

  • RSC_REPORT_RENDERING_URL

    The URL for this specific rendering of the content. Contains placeholder text when rendering and is replaced with the final URL when sending email.

    Example: "http://rsc.company.com/content/42/_rev1/"

  • RSC_REPORT_SUBSCRIPTION_URL

    The URL that a subscriber can use to remove themselves. Contains placeholder text when rendering and is replaced with the final URL when sending email.

    Example: "http://rsc.company.com/connect/#/apps/42/subscriptions"

Important

The final values of the URL environment variables are not known prior to rendering. Connect renders your document using placeholder values for these environment variables. The placeholder values are replaced when constructing the final email message.

When rendering your content outside of Connect, these environment variables do not have values.

Access these environment variables from code using the Sys.getenv() R function.

You can use these variables anywhere within your email body or footer. These URLs are not appropriate for use in the body of your report.

Email Attachments

An attachment is an output file that is attached to an emailed report. You can specify email attachments as an argument to the blastula attach_connect_email function, or using the rsc_email_attachments R Markdown Output Metadata.

For example, using blastula:

render_connect_email(input = "connect-example-email.Rmd") %>%
  attach_connect_email(
    subject = "Posit Connect HTML Email",
    attach_output = TRUE,
    attachments = c("dallas_home_sales.csv", "austin_home_sales.csv")
  )

For example, using output metadata:

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"
  )
)

An email attachment is 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.

Conditionally sending email

By default, reports can be configured to run on a regular schedule. However, you might only want to send an email to stakeholders under certain conditions. For example, you can have a report that runs every day to check supply levels, but only sends an email notification if supplies dip below a critical threshold.

This behavior can be configured with the blastula package or using R Markdown Output Metadata.

Using blastula you can craft an if statement around the call to attach_connect_email:

library(blastula)
if (demand_forecast > 1000) {
  render_connect_email(input = "alert-supply-team-email.Rmd") %>%
  attach_connect_email(
    subject = sprintf("We need to prepare %d units!", demand_forecast),
    attach_output = TRUE,
    attachments = c("demand_forecast_data.csv")
  )
} else {
  suppress_scheduled_email() 
}

Using R Markdown Output Metadata follows a similar pattern with an if statement:

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

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 or using the attach_output = FALSE argument in blastula::attach_connect_email.

Note

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

Tracking visits

Connect records visits to R Markdown documents and lets you see:

  • Which documents were viewed
  • When the documents were viewed
  • Who viewed the documents

Details about visits are also recorded for parameterized R Markdown documents and other types of rendered and static content.

An overview of recent activity is available in the Connect dashboard. See the Content Settings Panel chapter to learn more.

Details about each visit are available through Connect Server API instrumentation endpoints. Perform your own analysis using the results from these endpoints. Code examples showing how to obtain this data can be found in the UserActivity section of the Posit Connect Server API Cookbook.