--- title: "PowerPoint decks" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{PowerPoint decks} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r, include = FALSE} knitr::opts_chunk$set( collapse = TRUE, comment = "#>" ) # Every suggested package the chunks below reach. A deck that carries a table # goes through flextable, and the driver model through rwa, so officer alone # is not enough to know a chunk can run. has_officer <- requireNamespace("officer", quietly = TRUE) has_flextable <- requireNamespace("flextable", quietly = TRUE) has_rwa <- requireNamespace("rwa", quietly = TRUE) can_table <- has_officer && has_flextable can_model <- can_table && has_rwa ``` ```{r setup} library(ezrsurvey) ``` The deck is where a survey project ends, and rebuilding it by hand every wave is where the time goes. Two routes are provided: one call for a deck with no particular shape, and a slide-at-a-time builder for a deck that has one. Both write a real `.pptx` through `officer`, so the result opens in PowerPoint, Keynote and Google Slides. Everything below writes into a temporary folder. ```{r} deck_dir <- tempdir() ``` ## One call Give `report_deck()` a named list. The names become slide titles, and each item becomes the slide's content. ```{r, eval = can_table} report_deck( list( "Who follows pod racing?" = plot_bars( calc_percentage(podracing_survey, demo_gender)), "How likely are they to recommend it?" = calc_nps( podracing_survey, nps_value) ), path = file.path(deck_dir, "overview.pptx"), title = "Pod-Racing Fan Survey" ) ``` The content dispatches on what it is. A ggplot becomes a chart sized to the layout's content placeholder, a data frame becomes a table sized to fill the slide, and a character vector becomes a bullet list. ## A slide at a time A deck with chapters, dividers and commentary is assembled step by step. Each call returns the document, so the whole deck is one pipe. ```{r, eval = can_model} drivers <- ipm_model(podracing_survey, nps_value, "ratings_") report_new("pptx") %>% report_title_slide( "Pod-Racing Fan Survey", subtitle = "1,000 fans | Fieldwork 2026" ) %>% report_section("RECOMMENDATION") %>% report_slide("How likely are you to recommend pod racing?", plot_nps(podracing_survey, nps_value)) %>% report_section("RATINGS") %>% report_slide("Which aspects matter most, and which fall short?", plot_ipm(drivers)) %>% report_add_slide("What we should fix first") %>% report_add_text(c( "Value and commentary sit lowest and matter most.", "Atmosphere is already strong; further gains there move nothing." )) %>% report_save(file.path(deck_dir, "deck.pptx")) ``` `report_slide()` is title plus one thing, which is most slides. `report_add_slide()` opens a slide you then add to with `report_add_plot()`, `report_add_table()` and `report_add_text()`, for the slides that carry more than one element. The same calls produce a Word document. Sections become headings rather than dividers: ```{r, eval = can_model} report_new("docx") %>% report_section("Pod-Racing Fan Survey") %>% report_add_text("Net Promoter Score and the drivers behind it.") %>% report_add_table(drivers) %>% report_save(file.path(deck_dir, "report.docx")) ``` ## Your organisation's template Point ezrsurvey at a template once and everything downstream matches it: ```r use_brand("brand/org-template.pptx") ``` That reads the template's theme: accent colours become the palette behind `plot_bars()`, `pal_brand()` and `scale_fill_brand()`, the body typeface becomes the default for `theme_ezrsurvey()`, and the file itself becomes the reference document for `report_new()`, `report_deck()` and `scaffold_report()`. With no template to hand, set the values directly: ```{r} use_brand(colors = c("#0B5394", "#E69138"), fonts = "Georgia", quiet = TRUE) pal_brand() clear_brand() ``` Both live in an `.ezrsurvey.yml` profile if you want them for every project. The semantic palettes keep their meaning whatever the brand: `pal_rating` and `pal_nps` stay red-amber-green, because recolouring a detractor to match a logo would make the chart lie. > A brand typeface only reaches the page through a graphics device that reads > the machine's fonts. `save_plot()` uses one. The `pdf` device, which is the > default in a plain `Rscript` run, does not, and `use_brand()` says so when it > sets a font in such a session. Layouts are chosen by inspecting a template's placeholders rather than their names, so a template written in any language works. `report_layouts()` shows what yours offers: ```{r, eval = has_officer} report_layouts() ``` ## Without a template Decks default to the package's own 16:9 template: a full-bleed cover with a large title and a subtitle strapline, full-bleed section dividers, and content slides carrying a left-aligned title over a slim rule with a live slide number in the corner. ```r report_deck(items, path = "deck.pptx") # styled, the default report_deck(items, path = "deck.pptx", style = "plain") # same palette, no decoration report_new("pptx", slide_numbers = FALSE) # drop the numbering ``` Charts are drawn at a constant bar thickness whatever the answer count, so a three-answer chart and a ten-answer chart sit together in a deck instead of the first one's bars turning into slabs. `bar_width` and `bar_ref_items` in `ezrsurvey_options()` control it. ## Google Slides Google Slides imports PowerPoint natively, so the route above is also the Google Slides route: build the deck, then use **File > Import slides**, or open the `.pptx` straight from Drive. Chart images, text boxes, bullets, speaker notes and theme colours all survive the import. Two things to watch. Fonts outside Google's catalogue are substituted, so if Slides is the destination, brand with one that is in it (`use_brand(..., fonts = "Roboto")`). And intricate table borders simplify. Charts are saved as transparent-background PNGs, so they sit cleanly on any Slides background.