7 Patient reports with sections
You can download the RDS files by clicking on the following links:
This chapter demonstrates how to create patient reports with custom sections in Word documents using the officer package. We’ll explore two approaches: using a single default section with page numbering, and using even and odd footers for more sophisticated layouts.
7.1 A single default section
In this first example, we’ll create patient reports with a consistent section layout throughout the document. The section will have custom margins and a footer displaying page numbers.
7.1.1 Setting up paths
First, we define the template file and output directory:
Code
path_to_template <- here("template", "template-02.docx")
sub_path <- here("output", "patient-profile", "default-section")
dir.create(sub_path, showWarnings = FALSE, recursive = TRUE)7.1.2 Defining section properties
We create two section properties objects:
-
sect_properties_1: A portrait section with 1-inch margins and a footer displaying page numbers (e.g., “1 on 5 pages”) -
sect_properties_2: A landscape section with 1-inch margins, useful for wide tables
Code
# Portrait section with page numbering footer
sect_properties_1 <- prop_section(
page_margins = page_mar(top = 1, bottom = 1, left = 1, right = 1),
type = "oddPage",
footer_default = block_list(
fpar(
run_word_field(field = "PAGE \\* MERGEFORMAT"),
" on ",
run_word_field(field = "NumPages \\* MERGEFORMAT"),
" pages"
)
)
)
# Landscape section for wide content
sect_properties_2 <- prop_section(
page_size = page_size(orient = "landscape"),
page_margins = page_mar(top = 1, bottom = 1, left = 1, right = 1),
type = "oddPage"
)The type = "oddPage" argument ensures that each section starts on a new page.
7.1.3 Generating individual patient reports
This loop creates one Word document per patient, with the following structure:
- Table of contents
- Subject-level analysis table (portrait)
- Vital signs graph (portrait)
- Vital signs table (landscape)
Code
for (i in seq_len(nrow(LIST_TBLS))) {
# Create output filename for this patient
USUBJID_STR <- LIST_TBLS[["USUBJID"]][i]
file_basename <- paste0(USUBJID_STR, ".docx")
fileout <- file.path(sub_path, file_basename)
# Initialize document with table of contents
doc <- read_docx(path = path_to_template)
doc <- body_add_toc(doc)
doc <- body_add_break(doc)
# Add subject-level analysis table
SL_TBL <- LIST_TBLS[["SL"]][[i]]
tab1 <- as_flextable(SL_TBL, show_coltype = FALSE) |>
labelizor(
labels = pharmaverseadam::adsl |>
labelled::get_variable_labels() |>
unlist()
) |>
padding(padding = 6)
doc <- body_add_par(doc, value = "Subject Level Analysis", style = "heading 1")
doc <- body_add_flextable(doc, tab1, align = "center")
# Prepare metabolic data and create visualization
METABOLIC_TBL <- LIST_TBLS[["METABOLIC"]][[i]] |>
mutate(ADY = as.Date(ADY))
gg <- ggplot(METABOLIC_TBL, aes(ADY, AVAL)) +
geom_path() +
scale_x_date(date_breaks = "4 weeks", date_labels = "%W") +
facet_wrap(~PARAMCD, scales = "free_y") +
labs(x = "Week", y = "Value")
doc <- body_add_par(doc, value = "Vital Signs Analysis for Metabolic", style = "heading 1")
doc <- body_add_par(doc, value = "Graphic", style = "heading 2")
doc <- body_add_gg(doc, gg, style = "Graphic")
# Create summary table for metabolic data
mb_ft <- METABOLIC_TBL |>
pivot_wider(
id_cols = AVISIT,
names_from = PARAMCD,
values_from = AVAL
) |>
flextable() |>
theme_vanilla() |>
colformat_double(digits = 2) |>
labelizor(labels = LABELS)
# End portrait section and start landscape section for table
doc <- body_end_block_section(doc, value = block_section(property = sect_properties_1))
doc <- body_add_par(doc, value = "Table", style = "heading 2")
doc <- body_add_flextable(doc, mb_ft, align = "center")
doc <- body_end_block_section(doc, value = block_section(property = sect_properties_2))
# Set default section and document settings
doc <- body_set_default_section(doc, sect_properties_1)
doc <- docx_set_settings(doc, even_and_odd_headers = FALSE)
# Save the document
print(doc, target = fileout)
}Click to download output/patient-profile/default-section/01-701-1015.docx.
7.3 Reminder
7.3.1 Section management in officer
The officer package provides powerful tools for managing sections in Word documents:
-
prop_section(): Defines section properties including page size, margins, orientation, and headers/footers -
body_end_block_section(): Ends the current section and applies new section properties -
body_set_default_section(): Sets the default section properties for the entire document -
docx_set_settings(): Configures document-wide settings like even/odd headers
