Week 7: functions and Parameterized Markdown

Robert W. Walker

Overview

Overview

  1. AMA
  2. Presentations with Quarto
    • reveal.js
    • Powerpoint [.pptx]
    • Beamer [\LaTeX]
  3. function
  4. Parameterized markdown

The Assignments

  • Due this week: Produce a marketing presentation of yourself.
  • Due next week: Parameterize a markdown.

Syllabus Guidance

This Week

Next Week

AMA

If there are things you want to figure out with quarto, what are they?

  • I have one example on functions from the blog.

On Functions

In the old days, there was apply and variants of apply including lapply, sapply, apply, `vapply and others.

Code
sapply(1:5, function(x) {
    cat(paste0(x, "\n", sep = ""))
})
1
2
3
4
5
[[1]]
NULL

[[2]]
NULL

[[3]]
NULL

[[4]]
NULL

[[5]]
NULL

A More Modern Way

From Advanced R

Code
triple <- function(x) x * 3
map(1:3, triple)
[[1]]
[1] 3

[[2]]
[1] 6

[[3]]
[1] 9

Screen shot

The key idea is what to output

  • map_chr: map to character.
  • map_lgl: map to logical.
  • map_int: map to integer.
  • map_dbl: map to double.

map

Code
# map_chr() always returns a character vector
map_chr(mtcars, typeof)
     mpg      cyl     disp       hp     drat       wt     qsec       vs 
"double" "double" "double" "double" "double" "double" "double" "double" 
      am     gear     carb 
"double" "double" "double" 
Code
# map_lgl() always returns a logical vector
map_lgl(mtcars, is.double)
 mpg  cyl disp   hp drat   wt qsec   vs   am gear carb 
TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE 
Code
# map_int() always returns a integer vector
n_unique <- function(x) length(unique(x))
map_int(mtcars, n_unique)
 mpg  cyl disp   hp drat   wt qsec   vs   am gear carb 
  25    3   27   22   22   29   30    2    2    3    6 
Code
# map_dbl() always returns a double vector
map_dbl(mtcars, mean)
    mpg     cyl    disp      hp    drat      wt    qsec      vs      am 
 20.091   6.188 230.722 146.688   3.597   3.217  17.849   0.438   0.406 
   gear    carb 
  3.688   2.812 

A General Structure

map has a natural column orientation.

My use case

library(tidyquant)
library(rmarkdown)
library(purrr)
Equity.Analyser <- function(x) {
  render("TQ-Parameters.qmd", 
         params = list(ticker = x), 
         output_file = paste0("docs/files/",x,".html"))
}
SP400 <- tq_index("SP400")
SP400$symbol %>% map(., function(x) { Equity.Analyser(x)})

Anonymous Functions

Two general pathways.

  1. function(x) { something.happens.to(x) }

  2. ~

An example: NB: old school apply takes a row (1) or column (2) input.

Code
apply(mtcars, 2, function(x) {
    is.character(x)
})
  mpg   cyl  disp    hp  drat    wt  qsec    vs    am  gear  carb 
FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE 
Code
map(mtcars, ~is.character(.x))
$mpg
[1] FALSE

$cyl
[1] FALSE

$disp
[1] FALSE

$hp
[1] FALSE

$drat
[1] FALSE

$wt
[1] FALSE

$qsec
[1] FALSE

$vs
[1] FALSE

$am
[1] FALSE

$gear
[1] FALSE

$carb
[1] FALSE

The Various Techniques

Screen Shot

Screen shot

On Types

Screen shot

map2

Screen shot

walk

An example

A Great Example

Visualizing walk2

imap

Screen shot

Screen shot

Multiples: pmap

Screen shot

Screen shot

Think This Through

An Extended Example

The Cards: Part I

# Step 1
library(rmarkdown)
library(purrr)
CardsMaker2 <- function(User.ID, First, Name) {
  render("CardsMaster3-Sp23.Rmd", params = list(User.ID=User.ID, fname=First, name=Name), output_file = paste0("cards3/",User.ID,".html", sep=""))
}
# Modify this to import the spreadsheet
Email.List <- read.csv("ClassRoster.csv")
# Select remote attendees and change variable names to reflect the proper ones in the call below.
Email.List.Use <- Email.List %>% filter(Role=="Student") %>% mutate(email = Email) 
Email.List.Use %<>% 
  rowwise() %>% 
  mutate(Last = unlist(str_split(Name, ","))[1], First = unlist(str_split(Name, ","))[2]) %>% 
  data.frame()
Email.List.Use %>% select(Name, User.ID, First) %>% pmap(CardsMaker2)

The Cards: Part II

library(gmailr)
library(tidyverse)
library(magrittr)
use_secret_file("~/Client-Secret-RWALKER.json")
# Construct an email
send.IPmail.WU <- function(email, firstname, lastname, fstub) {
  html_msg <-
    gm_mime() %>%
    gm_to(paste0(firstname," ",lastname," <",email,">")) %>%
    gm_from("Robert W. Walker <rwalker@willamette.edu>") %>%
    gm_subject(paste0("A Mid-Semester Function...")) %>%
    gm_html_body(paste0("To: ", lastname,", ",firstname,", <hr /> <br> 
  Hello ",firstname,", <br> A wee gift in an .html card.<br> <br>
                      With my highest regards, <br> Robert W. Walker <br> <br>")) %>%
    gm_attach_file(paste0("cards3/",fstub,".html", sep=""))
  gm_send_message(html_msg)
  return(list(Success=1, email=email, Message = html_msg))
}
# Modify this to import the spreadsheet
Email.List <- read.csv("ClassRoster.csv")
# Select role.
Email.List.Use <- Email.List %>% filter(Role=="Student") %>% mutate(email = Email) 
Email.List.Use %<>% 
  rowwise() %>% 
  mutate(Last = unlist(str_split(Name, ","))[1], First = unlist(str_split(Name, ","))[2]) %>% 
  data.frame()
# A pedestrian use of map.
1:dim(Email.List.Use)[[1]] %>% 
map(~ send.IPmail.WU(
email=Email.List.Use$email[.x], 
firstname=Email.List.Use$First[.x], 
lastname=Email.List.Use$Last[.x], 
fstub=Email.List.Use$User.ID[.x])
)

The reduce family

Is explained here

Predicate functionals

Screen shot

A funny thing about the tidyverse

Quosures. The writeup

Code
mySum <- function(dat, vec) {
    vec <- enquo(vec)
    result <- dat %>%
        summarise(Mean = mean(!!vec, na.rm = TRUE), SD = sd(!!vec, na.rm = TRUE),
            SE = sd(!!vec, na.rm = TRUE)/sqrt(length(!!vec)), P25 = quantile({
                {
                  vec
                }
            }, probs = 0.25), P75 = quantile({
                {
                  vec
                }
            }, probs = 0.75))
    return(result)
}
mtcars %>%
    mySum(., disp)
  Mean  SD   SE P25 P75
1  231 124 21.9 121 326

An Example Command

A Wee Break

Week 8 is open. What do we want to do?

How To Do?

Page