Learning Objectives
- Learn some of the more commonly used R Markdown syntax.
- Learn to generate formatted text and tables describing data and code.
- Learn to embed formatted code, with additional arguments to exclude the code, output, or both from appearing in the rendered document.
- Use R Markdown to create an annotated html document containing meta-data and exploratory data analysis of the
CO2dataset.
Log in to your Google Drive, and open your Environmental Data
Analysis project. Click on the arrow next to the icon you would
typically use to open a new R Script . Instead of
choosing “R Script,” choose “R Markdown.” RStudio will
ask you for a title and author name. You can also choose the type of
document you wish to create. You can use R Markdown to create a Word, a
pdf, or html document. The default is html, which is what we will create
today.
Once you select these options, RStudio will open an R markdown template, which you can save as a plain text file with the extension .Rmd. The template will provide you with several sections of formatted text and code chunks to get you started.
You will notice that the file contains three kinds of content:
- A header surrounded by
---. This header is optional, but it is good practice to keep a header that contains a title, author, and date of creation.
- R code chunks that begin with
```{r}and close with```. You can add additional arguments within{r}to specify whether this code should appear in your document, and whether the output of this code should appear in your document.
- Text mixed with simple text formatting. For example, the
##before a line indicates that line should be formatted as a heading. You can also leave two spaces at the end of a line to indicate you wish to begin a new paragraph. If you are creating an html document, this part of the document also supports html code.
You can click “Knit” at anytime to generate your R Markdown document and ensure that your formatting is rendering properly. When you knit, RStudio will automatically save your .Rmd file.
Extensive resources are available for formatting in R Markdown.
Some of the basic syntax is available here: https://rmarkdown.rstudio.com/authoring_basics.html
You can also access information on R Markdown, including tutorials, from
the creators at: https://rmarkdown.rstudio.com/
I have also provided you with an R Markdown cheat sheet on the Moodle
page, which contains some of the more common formatting options.
When in doubt, I find that Googling “How do I _____ in R Markdown?” will
usually return useful hints.
Today we will use the built-in CO2 data set to explore
some of the options for annotating analysis of data and including
meta-data and plots.
Challenge
Create a heading for “Packages” and an R chunk that loads all the packages we will use. Today we will use
rmarkdown,knitr, andtidyverse. Add the argumentwarning = FALSEin{r}to hide any warnings related to the packages in the rendered document, e.g., ```{r, warning = FALSE}. Remember to use#within your code chunk to annotate what the next line of code is going to do.
## Packages
# Load rmarkdown package
library(rmarkdown)
# Load knitr package
library(knitr)
# Load tidyverse package
library(tidyverse)
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr 1.1.0 ✔ readr 2.1.4
## ✔ forcats 1.0.0 ✔ stringr 1.5.0
## ✔ ggplot2 3.4.1 ✔ tibble 3.1.8
## ✔ lubridate 1.9.2 ✔ tidyr 1.3.0
## ✔ purrr 1.0.1
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag() masks stats::lag()
## ℹ Use the ]8;;http://conflicted.r-lib.org/conflicted package]8;; to force all conflicts to become errors
Challenge
Create a heading for “Data” and briefly describe the
CO2dataset we are using. Include a code chunk that loads the data, inspects the structure of the dataframe, and summarizes the dataframe. Remember to use#in your code chunk to annotate what the next line of code is going to do.
Hint: You can run?CO2in the console to retrieve a help file that contains meta-data on theCO2dataset.
## The CO2 dataset
The CO2 dataset contains responses in CO2 uptake rates
to increasing CO2 for grass species Echinochloa crus-galli,
collected from populations in Quebec and Mississippi. Half of the plants
were exposed to cold conditions the night before measurements, and half
were kept at ambient temperatures.
# Load the CO2 data set
data(CO2)
# Inspect the CO2 data frame
str(CO2)
## Classes 'nfnGroupedData', 'nfGroupedData', 'groupedData' and 'data.frame': 84 obs. of 5 variables:
## $ Plant : Ord.factor w/ 12 levels "Qn1"<"Qn2"<"Qn3"<..: 1 1 1 1 1 1 1 2 2 2 ...
## $ Type : Factor w/ 2 levels "Quebec","Mississippi": 1 1 1 1 1 1 1 1 1 1 ...
## $ Treatment: Factor w/ 2 levels "nonchilled","chilled": 1 1 1 1 1 1 1 1 1 1 ...
## $ conc : num 95 175 250 350 500 675 1000 95 175 250 ...
## $ uptake : num 16 30.4 34.8 37.2 35.3 39.2 39.7 13.6 27.3 37.1 ...
## - attr(*, "formula")=Class 'formula' language uptake ~ conc | Plant
## .. ..- attr(*, ".Environment")=<environment: R_EmptyEnv>
## - attr(*, "outer")=Class 'formula' language ~Treatment * Type
## .. ..- attr(*, ".Environment")=<environment: R_EmptyEnv>
## - attr(*, "labels")=List of 2
## ..$ x: chr "Ambient carbon dioxide concentration"
## ..$ y: chr "CO2 uptake rate"
## - attr(*, "units")=List of 2
## ..$ x: chr "(uL/L)"
## ..$ y: chr "(umol/m^2 s)"
# Summarize CO2 data
summary(CO2)
## Plant Type Treatment conc uptake
## Qn1 : 7 Quebec :42 nonchilled:42 Min. : 95 Min. : 7.70
## Qn2 : 7 Mississippi:42 chilled :42 1st Qu.: 175 1st Qu.:17.90
## Qn3 : 7 Median : 350 Median :28.30
## Qc1 : 7 Mean : 435 Mean :27.21
## Qc3 : 7 3rd Qu.: 675 3rd Qu.:37.12
## Qc2 : 7 Max. :1000 Max. :45.50
## (Other):42
It is good practice to include meta-data where you store your data. Meta-data can be as simple as a plain text file containing information on data collection methods, the variables included in your data frame, and any other information a user may find helpful. If your data have been published in a journal article or an online database, you can also provide a suggested citation.
R Markdown documents are commonly included with manuscript submissions to document the process used to clean, manipulate, analyze, and plot data. You can also provide meta-data for the data frame in the form of a data dictionary. For an example, you can view a meta-data file I created in R Markdown for a recent journal article here.
We will use two approaches to include a data dictionary in an R Markdown document: in-line tables and “kables.”
First we will create a table by typing information directly into the R Markdown document.
The code to create a table is as follows:
Table Header | Second Header
------------- | -------------
Table Cell | Cell 2
Cell 3 | Cell 4
So I could use the following code to create a table for the first couple rows of meta-data by typing the following as simple text:
Variable | Description
-------- | ------------
Plant | an ordered factor with levels Qn1 < Qn2 ... < Mc1 giving a unique identifier for each plant
Type | a factor with levels Quebec Mississippi giving the origin of the plant
| Variable | Description |
|---|---|
| Plant | an ordered factor with levels Qn1 < Qn2 … < Mc1 giving a unique identifier for each plant |
| Type | a factor with levels Quebec Mississippi giving the origin of the plant |
Note that this approach will only work if you leave a blank line containing two spaces before the first line of your table.
kable()The other approach is to create a data frame or .csv file containing
your meta-data, and create a table using the kable()
function. This approach is much more efficient for tables
larger than ~2-3 rows.
To create a data frame from scratch in R, I will create a vector for
each column using c() and then combine them into a data
frame using data.frame(). This is relatively easy to do, as
I can copy and paste the information from the help file.
# Create vector of variable names
Variable <- c("Plant", "Type", "Treatment", "conc", "uptake")
# Create vector of descriptions
Description <- c("an ordered factor with levels Qn1 < Qn2 <...< Mc1 giving a unique identifier for each plant",
"a factor with levels Quebec Mississippi giving the origin of the plant",
"a factor with levels nonchilled chilled",
"a numeric vector of ambient carbon dioxide concentrations (mL/L)",
"a numeric vector of carbon dioxide uptake rates (umol/m^2 sec)")
#Create data frame from two column vectors
metadata <- data.frame(Variable, Description)
Once I have a data frame metadata, I can use the
kable() function in a code chunk to create a table.
# Create table from metadata data frame
kable(metadata)
| Variable | Description |
|---|---|
| Plant | an ordered factor with levels Qn1 < Qn2 <…< Mc1 giving a unique identifier for each plant |
| Type | a factor with levels Quebec Mississippi giving the origin of the plant |
| Treatment | a factor with levels nonchilled chilled |
| conc | a numeric vector of ambient carbon dioxide concentrations (mL/L) |
| uptake | a numeric vector of carbon dioxide uptake rates (umol/m^2 sec) |
If I already had a .csv file containing the meta-data, I could import
the file from my working directory, save it as an object, and then use
the kable() function to create a table from that object.
Again, I would do this within a code chunk.
# Import metadata from .csv file
metadata2 <- read.csv("metadata.csv")
# Create table
kable(metadata2)
| Variable | Description |
|---|---|
| Plant | an ordered factor with levels Qn1 < Qn2 <…< Mc1 giving a unique identifier for each plant |
| Type | a factor with levels Quebec Mississippi giving the origin of the plant |
| Treatment | a factor with levels nonchilled chilled |
| conc | a numeric vector of ambient carbon dioxide concentrations (mL/L) |
| uptake | a numeric vector of carbon dioxide uptake rates (umol/m^2 sec) |
Note that if you wanted the table, but did not want the code used to
generate the table to appear in your R Markdown document, you can add
the argument echo = FALSE in {r},
e.g., ```{r, echo = F}.
Challenge
Using either the in-line table or kable approach, generate a table that includes the name of each variable in the
CO2data frame and a brief desciption of each variable.
You can insert images into an R Markdown document by including a link to an image file in your working directory, or by creating a link to a permanent web location. Including a link to a web location is often risky, as image locations can change or be replaced (story there). You can also create an image caption in association with the image.
For example, if I wanted to insert an image for this assignment, I
would save the image file to my project folder and type the following
code as simple text in my R Markdown document:

The code is in the format .
Note that I have added modifiers to create bold ** and
italicized * fonts in the caption.
Fig. 1 Echinochloa crus-galli, the grass species used in experiments in Potvin et al. (1990). Source: Wikimedia commons.
Challenge
Find a photo of Echinochloa crus-galli using a Google image search.
You want to make sure you find a photo that is available for reuse.
Under the search bar, clickToolsthen clickUsage RightsandCreative Commons licenses.
Choose an image. Right click, chooseSave image as...and save the image to your project folder.
Insert the image in R Markdown, with a caption describing the image and the name of the image file with correct file extension.
At times, you may wish to include a formatted equation in a document.
For example, in the power analysis workshop, I embedded formatted
equations explaining how “effect size” was calculated for various
statistical tests. Here, I may wish to include an equation that explains
the anticipated relationship between CO2 and CO2
uptake. I can format equations in R Markdown either inline or as a
separate line.
For a thorough treatment of mathematical notation in R Markdown, see https://rpruim.github.io/s341/S19/from-class/MathinRmd.html.
Example:
$v = V_{max}\frac{[CO_{2}]}{[CO_{2}]_{k}+[CO_{2}]}$ is
rendered as \(v =
V_{max}\frac{[CO_{2}]}{[CO_{2}]_{k}+[CO_{2}]}\)
Example:
$$v = V_{max}\frac{[CO_{2}]}{[CO_{2}]_{k}+[CO_{2}]}$$ is
rendered as \[v =
V_{max}\frac{[CO_{2}]}{[CO_{2}]_{k}+[CO_{2}]}\]
This equation describes a saturating relationship between
CO2 uptake and the amount of CO2 available,
where:
\(v\) = CO2 uptake
rate
\(V_{max}\) = maximum uptake rate
\([CO_2]_{k}\) = half-saturation
concentration
Challenge
Create a new section in your R Markdown document titled “Hypotheses.”
In text, briefly explain why you may expect uptake to follow a hyperbolic, or saturating, relationship. (Hint: Google “Michaelis-Menten kinetics”)
Following the example above, create an equation describing this relationship. Be sure to define your terms.
Below the equation, insert an image showing Michaelis-Menten relationship. (Use the method you used to insert the plant photo.)
You can also embed plots. For example, I may want to create a
scatterplot examining the relationship between ambient CO2
and CO2 uptake for only those plants collected from
Mississippi and chilled prior to measurement. I will first create a new
object that includes only those data.
In the next unit, we will learn to make plots using the package
ggplot2. For now, use the function qplot() in
the ggplot2 package to generate a plot using similar syntax
to the base plots you have already made.
# Create dataframe of chilled plants from Mississippi
MS_chilled <- CO2[CO2$Type == "Mississippi" & CO2$Treatment == "chilled",]
# Plot relationship for replicate plants
qplot(x = conc,
y = uptake,
data = MS_chilled,
facets = ~Plant,
geom = "line",
xlab = "CO2 Concentration (ppm)",
ylab = "CO2 Uptake Rate (umol/m^2/s)")
Note that you can add the echo = FALSE parameter to the
code chunk to prevent printing of the R code that generated the plot,
e.g., ```{r, echo = FALSE}.
Challenge
Create a new section titled “Results.”
In this section, create two plots: One for plants collected in Mississippi (using the code provided above) and one for plants collected in Quebec (which you will need to create using the code above as a model). For both, include only plants that were chilled prior to measurement.
Below each plot, include a figure caption that describes the plot content. (You can type this text directly into the R Markdown document below the code chunk that generates the plot. If the text appears next to the plot, you can insert a blank line with two spaces to make your caption begin on a new line.)