Day 3

Objectives

  • Walk through an example of a plot and table from stockplotr
  • Learn about the value of the stockplotr R package
  • Understand how to integrate stockplotr into an asar-based reporting workflow

Introduction

Icebreaker

Welcome! Please open the Day 3 communal notes doc and participate in the icebreaker exercise.

Tip

Reminder: For comments or questions, please raise your hand, or write them in the chat, at any time. Depending on our schedule, we may ask that you save larger questions for breaks.

Break for questions

Materials for today’s lesson

Installation

asar, stockplotr, and tinytex should already be installed if you attended Days 1 or 2. If not, please install these packages by following the instructions in the pre-workshop checklist.

Introduction to stockplotr

Convert output (if necessary)

First, you’ll need to convert your model results using the same workflow covered yesterday: asar::convert_output().

You can use the example Report.sso file uploaded to the workshop GitHub or, if you have a compatible output file, your own.

# Identify output file
output_file <- here::here("example_output", "Report.sso")
# convert the output and save it as an rda
petrale <- asar::convert_output(output_file,
                                save_dir = getwd())

If you have already converted your output: great! Import it into your R environment so that you can handle it as an object like “petrale” in the chunk above.

Break for issues

Package information

This package is an ongoing process to gather contributions in order to expand the number of pre-made tables and figures that can be incorporated into a stock assessment report. All objects are intended to be generalized and not specific to any region.

The following table contains figures and tables that are available in stockplotr:

Function Description
plot_abundance_at_age() abundance-at-age
plot_biomass_at_age() biomass-at-age
plot_biomass() biomass time series
plot_catch_comp() catch compositions
plot_fishing_mortality fishing mortality time series
plot_indices() indices
plot_landings() landings time series
plot_natural_mortality() natural mortality time series or at-age
plot_recruitment_deviations() recruitment deviations
plot_recruitment() recruitment time series
plot_spawn_recruitment() spawn recruitment relationship
plot_spawning_biomass() spawning biomass time series
table_landings() landings time series by fleet or other indexing
table_bnc() biomass, landings, and catch time series
table_harvest_projection() harvest projection table according to SAFE standards (to be expanded nationally)
tables_indices() indices by fleet

Each automated function returns either a ggplot2 object (figure) or flextable object (table). This allows for further customization of the output if desired by using the notation you are familiar with. For a figure, you can continue to add onto the plot any other ggplot2 function or extension using the plus (+) operator. For a table, please use the native pipe (|>) when adding additional formatting, rows, or other pieces to the object.

Example Figure

Run the example below. It should result in a line graph showing biomass over time, including a reference line for the biomass unfished.

stockplotr::plot_biomass(
  dat = petrale,
  geom = "line",
  group = NULL,
  facet = NULL,
  ref_line = "unfished",
  unit_label = "mt",
  scale_amount = 1,
  relative = FALSE,
  interactive = TRUE,
  module = NULL
)

Break for questions

Customizing

All figures will automatically identify any indexing variables in the data such as fleet, area, or sex. You can use the group and facet arguments to modify how these indexing variables are displayed in the figure. You can also modify other arguments such as geom, ref_line, and relative to change the appearance of the figure.

Here are some examples of how to customize the biomass figure:

Change the reference line to a specific value (e.g., 260)

In this example we are also telling the function which module to select in order to by-pass this step. We plan to remove grouping of some modules in the future.

stockplotr::plot_biomass(
  dat = petrale,
  geom = "line",
  group = NULL,
  facet = NULL,
  ref_line = c("target" = 260),
  unit_label = "mt",
  scale_amount = 1,
  relative = FALSE,
  # interactive = TRUE,
  module = "TIME_SERIES"
)

Plot relative biomass and change the size of the line

In this example, we still are bypassing module selection and we are automatically extracting the reference line value from the data. However, now we are using this reference value to plot relative biomass and changing the linewidth to 2 (an argument inherited from ggplot2).

stockplotr::plot_biomass(
  dat = petrale,
  geom = "line",
  group = NULL,
  facet = NULL,
  ref_line = c("target" = 260),
  unit_label = "mt",
  scale_amount = 1,
  relative = TRUE,
  # interactive = TRUE,
  module = "TIME_SERIES",
  linewidth = 2
)

Tip

The only extended arguments available are the ones found from the ggplot2::geom_XX() function. Thus, any indexed variables can not be changes such as color to fill. Please see the documentation for ggplot2 geom functions for these additional arguments.

Summarize our data

Notice that you can remove the reference line by setting ref_line = NULL.

stockplotr::plot_biomass(
  dat = petrale,
  geom = "line",
  group = "none",
  facet = NULL,
  ref_line = NULL,
  unit_label = "mt",
  scale_amount = 1,
  relative = FALSE,
  # interactive = TRUE,
  module = "TIME_SERIES"
)

Break for questions

Tip

Remember that figures return ggplot2 objects, so we can make additional customization to these plots.

stockplotr::plot_biomass(
  dat = petrale,
  geom = "line",
  group = "fleet",
  facet = NULL,
  ref_line = c("target" = 5690),
  unit_label = "mt",
  scale_amount = 1,
  relative = FALSE,
  # interactive = TRUE,
  module = "TIME_SERIES"
) +
  ggplot2::geom_vline(xintercept = 2005, linetype = "dashed", color = "red")

Break for questions. We will be moving onto tables next.

Example Table

Run the following example table. The result is a fully report ready table showing landings over time. Remember that these are exported as flextable objects and can be edited as such.

Note

stockplotr uses the native pipe (|>), so if you decide to customize you table, please also use the native pipe to avoid errors.

# not sure what this will exactly look like so this is a place holder
stockplotr::table_landings(
  dat = petrale,
  group = "fleet",
  unit_label = "mt",
  module = NULL
)

Break for questions

Next, we can add some different formatting:

stockplotr::table_landings(
  dat = petrale,
  group = "fleet",
  unit_label = "mt",
  module = NULL
) |>
  flextable::footnote(
    i = 6, # row
    j = 2, # column
    value = flextable::as_paragraph(
      "This is an example table from the workflows workshop. Not intended for official use."
      )
  )

or potentially highlight a specific line within the table:

stockplotr::table_landings(
  dat = petrale,
  group = "fleet",
  unit_label = "mt",
  module = NULL
) |>
  flextable::footnote(
    i = 6, # row
    j = 2, # column
    value = flextable::as_paragraph(
      "Not intended for official use."
      )
  ) |>
  flextable::bg(
    i = 5,
    bg = "lightblue",
    part = "body"
    )

Break for questions

rda file

An rda is an R data file that stores R objects and preserves their structure. In this case, you can think of an rda file exported from stockplotr as a list of objects.

Each plot or table has the option to export it as an rda. This rda is a list of 3 associated components for the plot/table to be used in a stock assessment report:

  • ggplot or flextable object
  • caption
  • alternative text (figures only)
  • latex object (tables only)
stockplotr::plot_biomass(
  dat = petrale,
  ref_line = c("target" = 260),
  unit_label = "mt",
  module = "TIME_SERIES",
  make_rda = TRUE,
  tables_dir = getwd()
)
load("figures/biomass_figure.rda")
rda$figure
rda$cap
rda$alt_text

Break for questions

stockplotr::table_landings(
  dat = petrale,
  group = "fleet",
  unit_label = "mt",
  make_rda = TRUE,
  tables_dir = getwd()
)
load("tables/landings_table.rda")
rda$table
rda$cap
rda$latex
Tip

We have designed two functions that allow you to automatically create all available figures and tables:

  • save_all_plots()
  • html_all_figs_tables()

20 minute break for questions & practicing

For the following, use stockplotr::example_data as the input data.

  1. Create an abundance-at-age plot. Export it as an rda to your working directory.
  2. Create a recruitment time series plot. Change the unit_label and scale_amount so that the y axis shows recruitment in thousands of fish. Set module = “TIME_SERIES”.
  3. Create a fishing mortality plot. Ensure it does not group by fleet. Set module = “TIME_SERIES”. Add a reference line (“target”) at 0.5. Convert it from a line plot to a scatterplot.
  4. Create a landings table.

Now, use your own data.

  1. Convert your own dataset using convert_output().
  2. Create a spawning biomass plot. Change the theme by applying the ggplot2::theme_classic().

For the following, use stockplotr::example_data as the input data.

  1. Create an abundance-at-age plot. Export it as an rda to your working directory.

Answer:

stockplotr::plot_abundance_at_age(
  dat = stockplotr::example_data,
  make_rda = TRUE,
  figures_dir = getwd()
)
  1. Create a recruitment time series plot. Change the unit_label and scale_amount so that the y axis shows recruitment in thousands of fish. Set module = “TIME_SERIES”.

Answer:

stockplotr::plot_recruitment(
  dat = stockplotr::example_data,
  unit_label = "fish",
  scale_amount = 1000,
  module = "TIME_SERIES"
)
  1. Create a fishing mortality plot. Ensure it does not group by fleet. Set module = “TIME_SERIES”. Add a reference line (“target”) at 0.5. Convert it from a line plot to a scatterplot.

Answer:

stockplotr::plot_fishing_mortality(
  dat = stockplotr::example_data,
  group = "none",
  module = "TIME_SERIES",
  ref_line = c("target" = 0.5),
  geom = "point"
)
  1. Create a landings table.

Answer:

stockplotr::table_landings(
  dat = stockplotr::example_data
)

Now, use your own data.

  1. Convert your own dataset using convert_output().

Answer:

convert_output(
  file = "path/to/your_report_file"
  # Specify these arguments if you wish: model, fleet_names,   save_dir
)
  1. Create a spawning biomass plot. Change the theme by applying the ggplot2::theme_classic().

Answer:

stockplotr::plot_spawning_biomass(
  dat = your_converted_data_object
) +
  ggplot2::theme_classic()

Integrating stockplotr in the workflow

For the second half of today’s lesson, let’s reorient ourselves. We’ve just learned how to make figures and tables with stockplotr. Now, we’ll cover how to add those plots into your asar report template.

Remember that after running the primary asar function– create_template()- you have a ‘report’ folder with several files in it. These files include the report skeleton; the child documents containing the executive summary, introduction, results, and so on; and, importantly for us right now, the documents that will contain code to display your figures and tables. The files will be named something like ‘08_tables.qmd’ and ‘09_figures.qmd’ (the prefix numbers may vary).

Each file will contain zero figures or tables. Instead, they will contain a statement referring you to {stockplotr} so that you can make your own. Since we’ve created those already, let’s add them to your report!

Adding tables and figures to your report

You can add your figures and tables with two workflows:

  1. Rerunning asar::create_tables_doc() and asar::create_figures_doc()
  • If you fill in arguments that allow R to find your tables and figures, then it will place them into the respective tables and figures docs automatically.
  1. Adding your tables and figures manually to each doc.

Option 1: Rerunning asar::create_tables_doc()/asar::create_figures_doc()

This is also known as the rda-based workflow.

Tables

To add tables, first ensure that your folder containing the tables is called “tables”.

Then, there are only two arguments to fill out:

  1. subdir: The location where the new tables doc should be saved (we recommend your ‘report’ folder, so it overwrites the old, empty version)
  2. tables_dir: The location of your “tables” folder
create_tables_doc(
  subdir = fs::path(getwd(), "report"), # indicates the new tables doc will be saved in your "report" folder, located in the working directory
  tables_dir = getwd() # indicates your "tables" folder is located in the working directory
                  )

Now, open your new tables doc and take a look!

You’ll notice the following structure:

Chunk 1 will always create an object saving the location of your tables_dir.

Then, there will be at least two chunks for each table. For tables that are regularly-sized (i.e., small enough that they don’t need to be rotated or split across pages):

Chunk 2 will:

  • load an rda containing a table
  • give the rda a specific name
  • save the table and caption as separate objects

Chunk 3 will:

  • display the table
Note

This workflow can also accommodate tables that are wide enough to require rotation into a landscape-view page OR splitting across pages. For more information, please see the “Adding Custom Tables & Figures” vignette.

Figures

Adding figures entails nearly the same process as described for tables. The only differences are:

  1. Figures will involve captions and alternative text, whereas tables only require captions
  2. Figures do not require the option to be rotated or split across pages.

Break for questions

Option 2: Manually adding tables/figures

Tables

You can add a regularly-sized1 table/figure manually by following these main steps:

  1. Create a code chunk
  2. Add your label and other chunk options
  3. Add code
  4. Write caption
  5. Add a page break between tables (optional but recommended)
Direct coding-in-qmd table workflow

Example from the “Adding Custom Tables & Figures” vignette:

```{r} 
#| label: 'tbl-custom1' # choose a label
#| tbl-cap: !expr This is your table caption.

# Import your data
petrale <- load(fs::path("std_output.rda"))

# Make your table
your_table <- head(petrale) |>
  dplyr::select(label, year, estimate) |>
  flextable::flextable()

# Show your table
your_table
``` 

Example of a table produced with the 'Direct coding-in-qmd table workflow' option for adding tables to `asar` reports.

Then, add a pagebreak:

{{< pagebreak >}}
Warning

It will be important to add your captions and labels into a csv file when making your documents accessible. You will soon learn more about this in the the “Adding accessibility features” section!

Direct image-based table insertion workflow

We don’t recommended adding tables as images, since it significantly reduces the accessibility of your table. However, we understand that sometimes this is the only format available.

Use the following notation to reference an external table as an image:

![Caption for my example table](example_table.png){fig-alt="This is the alternative text for my table", #tbl-example}

Note

Notice how there is alternative text added to this method of adding a table. In this scenario, the table is recognized as an image and thus would NOT pass accessibility checks. Please make sure you add alternative text for image-based tables added in this way.

Figures

Direct coding-in-qmd figure workflow

Like with tables, running create_figures_doc() produces a blank figures quarto file. We add figures similarly to tables. In fact, the only major difference is that you must write alternative text for your figure.

Put your alternative text in a chunk option called ‘fig-alt’ (example below).

```{r} 
#| label: 'fig-custom1' # choose a label
#| fig-cap: !expr This is your figure caption.
#| fig-alt: !expr This is your figure alternative text.

# Import your data
load(fs::path("std_output.rda"))

petrale <- out_new |>
                    dplyr::filter(year > 1980) |>
                    dplyr::filter(module_name == "TIME_SERIES") |>
                    dplyr::filter(label == "biomass") |>
                    dplyr::filter(!is.na(fleet))

# Make your figure
your_figure <- ggplot2::ggplot(petrale,
  ggplot2::aes(x = year, y = estimate, color = fleet)) +
  ggplot2::geom_line(linewidth = 0.75) +
  ggplot2::geom_point() +
  ggplot2::theme_classic()

# Show your figure
your_figure
``` 

Example of a figure produced with the 'Direct coding-in-qmd figure workflow' option for adding figures to `asar` reports.

Warning

Even though you wrote alt text in the fig-alt area, when you first render your report into a PDF, your alternative text will not show up in your document. Strange, right?! To ensure it shows up, refer to the “Adding accessibility features” section (which we’ll discuss in a moment).

Direct image-based figure insertion workflow

Like tables, you can reference figures not made directly in code chunks. However, in this case, this does not change the accessibility of the figure because you can still add the necessary components to meet Section 508 compliance standards: alternative text and a caption.

![Caption for my example figure](example_figure.png){fig-alt="This is the alternative text for my figure", #fig-example}

Referencing your tables or figures in text

Quarto uses a special notation to allow users to link tables and figures throughout their text. Use the following notation to link/reference tables in your text:

@tbl-example

or

@fig-example

Adding an @ symbol followed by the chunk label, or label of your table/figure, will create an interactive link that lets the reader navigate to that specific table/figure.

Break for questions

Render your first report draft!

Open your skeleton qmd file, then render the report.

You can render a report in three ways:

In the R console

Run quarto::quarto_render([path/to/your/skeleton.qmd file]) in the console. For example:

quarto::quarto_render(
  here::here("report",
             "SAR_species_skeleton.qmd") # add your skeleton filename
)

With the RStudio “render” button

Open the skeleton.qmd file. Then, in the program pane, press the “render” button:

Screenshot of the RStudio console with a red rectangle highlighting the location of the 'Render' button.

In the terminal

Run quarto render [path/to/your/skeleton.qmd file] in the terminal. For example:

Enter quarto render report/SAR_species_skeleton.qmd

20 minute break for questions & practicing

  1. Ensure that you have a ‘figures’ folder and a ‘tables’ folder, each with at least one rda file. If you don’t, export a couple of figures and tables.
    • Hint: ensure that the make_rda argument is set to TRUE when running the stockplotr functions that create figures and tables).
  2. Open up your figures and tables qmds, in the ‘report’ folder. If these documents do not contain the necessary chunks to import and display at least one plot, rerun create_figures_doc() and/or create_tables_doc() to add code that will plot the figures/tables in your ‘figures’ and ‘tables’ folders.
    • Hint: ensure that the arguments are correct: subdir and figures_dir (for the figures doc) / tables_dir (for the tables doc)
    • Hint: This step practices the “rda-based workflow”.
  3. Practice adding a figure with markdown notation by adding the image of a landings figure into the figures doc. The figure is located in the ‘example_plots’ folder. Set the caption to “Historical landings by fleet.”, the alternative text to “Cumulative line plot showing historical landings for North and South fleets. The x axis shows the year, which spans from 1850 to 2026. The y axis shows landings in metric tons, which spans from 0 to 2,400.”, and the figure label to “practice-figure-label”.
  4. In the Executive Summary, add a reference to the first figure in your figures qmd file.
  1. Practice adding a figure with markdown notation by adding the image of a landings figure into the figures doc. The figure is located in the ‘example_plots’ folder. Set the caption to “Historical landings by fleet.”, the alternative text to “Cumulative line plot showing historical landings for North and South fleets. The x axis shows the year, which spans from 1850 to 2026. The y axis shows landings in metric tons, which spans from 0 to 2,400.”, and the figure label to “practice-figure-label”. Hint: This step practices the “direct image-based workflow”.

Answer: Add the following chunk to the figures doc:

![Historical landings by fleet.](example_plots/landings_fig_png.png){fig-alt="Cumulative line plot showing historical landings for North and South fleets. The x axis shows the year, which spans from 1850 to 2026. The y axis shows landings in metric tons, which spans from 0 to 2,400.", #practice-figure-label}
  1. In the Executive Summary, add a reference to the first figure in your figures qmd file.

Answer: If the ‘label’ for that first figure is ‘fig-custom1’, then the in-text reference would be ‘@fig-custom1’.

Adding accessibility features

TipCongrats! You’re almost there!

You’ve made major progress towards completing your first report!

While your rendered report looks superb, it’s probably missing two major components: tags and alternative text.

If you made an HTML-based report, these features would most likely be in your document. But since we’re prioritizing PDFs, there are a few more steps to take before your document will significantly more accessible than it is now. This means that, to achieve compliance with Section 508 criteria, you must complete a couple more tasks.

Add tagging

In your ‘report’ folder, you’ll find a new file with a .tex filetype: ‘SAR_species_skeleton.tex’ (or something similar). This file is a LaTex-based version of your rendered skeleton qmd file. It’s also where we add our remaining accessibility features, since Quarto does not yet offer that functionality within its qmd files.

Tags are structural elements of PDFs. They are signals telling software which information are headers, images, tables, text, and so on. Tags allow people using technology like screen readers to logically navigate PDFs.

We’ll use the asar::add_tagging() function to add tags.

Notice that we are using the withr::with_dir() function as a wrapper for add_tagging(). This allow us to set the “report” folder as a temporary working directory, which is essential for the function to work. Likewise, if you set the “report” folder as the working directory, you could remove this wrapper and add_tagging() would succeed.

path <- getwd()

withr::with_dir(
  file.path(path, "report"),
  asar::add_tagging(
  x = "SAR_species_skeleton.tex", # your .tex report file
  dir = getwd(), # the location of the .tex file
  compile = FALSE # whether the .tex file should be compiled after tagging. We'll set it to FALSE for now
  )
)

Now your PDF is tagged! If you compiled your .tex file, it’d look something like this. The tags are on the right side of the PDF viewer.

Screenshot of an example PDF-based, tagged report. The PDF is opened in Adobe and tags for the Table of Contents are shown on the right side of the screen.

WarningDefault alt text should be updated

If you stop here (i.e., you don’t add your own alt text), this function will add the image paths as alt text. We’ll show you how to add your intended alt text in the next step.

Break for questions

Add alternative text

You must add alternative text (“alt text”) for images in a separate csv if you added figures using any of the workflows described above.

Since you’ve used stockplotr to make some figures, you’ve already completed the first step: making a csv that will contain your alt text.

Look at your alt text csv

The file, “captions_alt_text.csv”, should be located in your working directory (enter getwd() if you forget where that is). Open it up.

The file is set up like this:

  • Column 1 (“label”) is a shorthand label for your figure or table. Labels should be somewhat short and exclude spaces. Examples include “kobe”, “relative.biomass”, and “fishing.mortality”.
  • Column 2 (“type”) contains “figure” or “table”.
  • Column 3 (“caption”) contains your caption.
  • Column 4 (“alt_text”) contains alternative text for figures. For tables, this column will be blank.
Format for csv containing table and figure captions and alternative text.
label type caption alt_text
example_fig figure Example caption for figure. Example alternative text for figure.
example_tab table Example caption for table.

Update the csv

Your job is to:

Editing existing entries

Using the “label” column, find the row associated with your figure and inspect it.

  • You’ll see that there’s already some prewritten alt text (in the “alt_text” column) that includes data from the model results file. Now, you must check this information for accuracy and update it where necessary (especially if the default figures were modified).

  • If you see text that looks like a placeholder (e.g., “The x axis, showing the year, spans from B.start.year to B.end.year…”), that means that there was at least one instance where our tool failed to extract a specific value from the model results, calculate a key quantity (like the start year of a biomass plot- aka “B.start.year”), and substitute it into the placeholder.

Important

While we have extracted key quantities as accurately as possible, we cannot guarantee that each quantity will have been calculated perfectly. Input data varies widely. It’s your responsibility to check the accuracy of your figures’ alt text.

  • This prewritten alt text usually contains 3/4 essential ingredients for well-written alt text. The remaining ingredient (#4): the relationship between the variables shown (i.e., what the figure is conveying). Since we can’t program stockplotr to analyze the figure’s meaning, you must provide this crucial component.

When you’re satisfied, save the csv.

Adding new entries

  • Make a new row.
  • For “label”, take the “label” of your figure chunk. For example, in the example above, the label would be “fig-custom1”.
  • The type will be “figure”.
  • The caption should be identical to the caption in your chunk (what you put in “fig-cap”).
  • The “alt_text” will contain your alt text. See the “Editing existing entries” section above, and the “Achieve Greater Accessibility” vignette, for help writing alt text.

When you’re satisfied, save the csv.

Add alt text to your report’s images

Now, we’ll use the asar::add_alttext() function to add the alt text into the report’s .tex file. Again, we’ll wrap the function with with_dir() to set a temporary working directory.

path <- getwd()

withr::with_dir(
  file.path(path, "report"),
  add_alttext(
    x = "SAR_species_skeleton.tex", # your .tex report file
    dir = getwd(), # the location of the .tex file
    alttext_csv_dir = getwd(), # the location of your "captions_alt_text.csv"
    figures_dir = path, # location of your "figures" folder
    compile = TRUE # now we'll compile the PDF
  )
)

Now your PDF’s figures have alt text! You can find and edit the alt text by following these steps:

Screenshot of a document opened in Adobe. The 'All Tools' menu shows a red oval around the 'Prepare for accessibility' button.

1. Open the ‘All Tools’ menu in Adobe. Scroll down until you reach the “Prepare for accessibility” button. Click it.

Screenshot of a document opened in Adobe. The 'Prepare for accessibility' menu shows a red oval around the 'Add alternative text' button.

2. In the ‘Prepare for accessibility’, click the “Add alternative text” button.

Screenshot of a document opened in Adobe. The 'Set alternative text' pop-up shows where an example image's alternative text is located.

3. In the ‘Set alternative text’ pop-up, verify that your images contain the expected alternative text and edit as necessary.

20 minute break for questions & practicing

  1. If you haven’t already, add tags to your pdf by running add_tagging() with the appropriate arguments (including compile set to TRUE). Then, open up the report and ensure it was tagged.

  2. Open up the “captions_alt_text.csv” file that contains your alternative text and captions. Find the rows that are linked with the figures and tables in your report.

    • Read through the captions and alternative text. Edit inaccuracies if necessary.
    • For figures, add a sentence or two describing the final ingredient for a solid alternative text: the relationship between the variables shown (i.e., what the figure is conveying).
    • If you’ve created custom figures/tables, create new rows for each. Add captions for all, and alternative text for just figures. Ensure that the label matches the chunk label.
  3. Run add_alttext() with compile set to TRUE. Then, open up the report and ensure the images contain alt text.

Questions, comments, and feedback

Please navigate to the Feedback heading and tell us what you thought about today’s workshop. Only 3 simple questions!

  • What went well?
  • What could be improved?
  • What is a question you still have?

Footnotes

  1. Again, for tables that require rotating or splitting across pages, please refer to the “Adding Custom Tables & Figures” vignette.↩︎