• Advanced R Book Club
  • Welcome
    • Book club meetings
    • Pace
    • Group introductions
    • git and GitHub
    • Resources to learn more about git and GitHub
  • 1 Introduction
    • 1.1 What’s new?
    • 1.2 Overview of the book structure
      • 1.2.1 What this book is not
      • 1.2.2 Organization of the book
      • 1.2.3 Foundations
      • 1.2.4 Functional programming
      • 1.2.5 Object-oriented programming
      • 1.2.6 Metaprogramming
      • 1.2.7 Techniques
    • 1.3 Resources
    • 1.4 Meeting Videos
      • 1.4.1 Cohort 1
      • 1.4.2 Cohort 2
      • 1.4.3 Cohort 3
      • 1.4.4 Cohort 4
      • 1.4.5 Cohort 5
      • 1.4.6 Cohort 6
      • 1.4.7 Cohort 7
  • 2 Names and values
    • Quiz
    • Binding basics
      • Exercises
    • Copy-on-modify
    • Functions
    • Lists
    • Data Frames
    • Character vectors
    • Exercises
    • Object Size
      • Alternative Representation
      • Exercises
    • Modify-in-place
      • Objects with a single binding
      • Environmments
      • Exercises
    • Unbinding and the garbage collector
    • Meeting Videos
      • Cohort 1
      • Cohort 2
      • Cohort 3
      • Cohort 4
      • Cohort 5
      • Cohort 6
      • Cohort 7
  • 3 Vectors
    • 3.1 Aperitif
      • 3.1.1 Counting Penguins
      • 3.1.2 In
      • 3.1.3 Fix: base R
      • 3.1.4 Fix: dplyr
      • 3.1.5 Motivation
    • 3.2 Types of Vectors
    • 3.3 Atomic Vectors
      • 3.3.1 Types of atomic vectors
      • 3.3.2 Vectors of Length One
      • 3.3.3 Longer
      • 3.3.4 Type and Length
      • 3.3.5 Missing values
      • 3.3.6 Testing
      • 3.3.7 Coercion
      • 3.3.8 Exercises
    • 3.4 Attributes
      • 3.4.1 How?
      • 3.4.2 Why
      • 3.4.3 Exercises
    • 3.5 Class - S3 atomic vectors
      • 3.5.1 Factors
      • 3.5.2 Dates
      • 3.5.3 Date-times
      • 3.5.4 Durations
      • 3.5.5 Exercises
    • 3.6 Lists
      • 3.6.1 Constructing
      • 3.6.2 Testing
      • 3.6.3 Coercion
      • 3.6.4 Matrices and arrays
      • 3.6.5 Exercises
    • 3.7 Data frames and tibbles
      • 3.7.1 Data frame
      • 3.7.2 Tibble
      • 3.7.3 Printing
      • 3.7.4 Subsetting
      • 3.7.5 Testing
      • 3.7.6 Coercion
      • 3.7.7 List Columns
      • 3.7.8 Matrix and data frame columns
      • 3.7.9 Exercises
    • 3.8 NULL
    • 3.9 Digestif
      • 3.9.1 Attributes
      • 3.9.2 Data Frames vs Tibbles
      • 3.9.3 Atomic Vectors
      • 3.9.4 Column Names
    • 3.10 Chapter Quiz
    • 3.11 Meeting Videos
      • 3.11.1 Cohort 1
      • 3.11.2 Cohort 2
      • 3.11.3 Cohort 3
      • 3.11.4 Cohort 4
      • 3.11.5 Cohort 5
      • 3.11.6 Cohort 6
      • 3.11.7 Cohort 7
  • 4 Subsetting
    • 4.1 Selecting multiple elements
      • 4.1.1 Atomic Vectors
      • 4.1.2 Lists
      • 4.1.3 Matrices and arrays
      • 4.1.4 Data frames and tibbles
      • 4.1.5 Preserving dimensionality
    • 4.2 Selecting a single element
      • 4.2.1 [[]]
      • 4.2.2 $
      • 4.2.3 missing and out of bound indices
      • 4.2.4 @ and slot()
    • 4.3 Subsetting and Assignment
    • 4.4 Applications
      • 4.4.1 Lookup tables (character subsetting)
      • 4.4.2 Matching and merging by hand (integer subsetting)
      • 4.4.3 Random samples and bootstrapping (integer subsetting)
      • 4.4.4 Ordering (integer subsetting)
      • 4.4.5 Expanding aggregated counts (integer subsetting)
      • 4.4.6 Removing columns from data frames (character)
      • 4.4.7 Selecting rows based on a condition (logical subsetting)
      • 4.4.8 Boolean algebra versus sets (logical and integer)
    • 4.5 Meeting Videos
      • 4.5.1 Cohort 1
      • 4.5.2 Cohort 2
      • 4.5.3 Cohort 3
      • 4.5.4 Cohort 4
      • 4.5.5 Cohort 5
      • 4.5.6 Cohort 6
      • 4.5.7 Cohort 7
  • 5 Control flow
    • 5.1 Introduction
    • 5.2 Choices
    • Exercise
    • Single if without else
    • Invalid inputs
    • Vectorized choices
    • Switch
    • Using dplyr::case_when
    • 5.3 Loops
    • Exercise
    • Pitfalls
    • Related tools
    • 5.4 Meeting Videos
      • 5.4.1 Cohort 1
      • 5.4.2 Cohort 2
      • 5.4.3 Cohort 3
      • 5.4.4 Cohort 4
      • 5.4.5 Cohort 5
      • 5.4.6 Cohort 6
      • 5.4.7 Cohort 7
  • 6 Functions
    • 6.1 How to make a simple function in R
    • 6.2 Primitive functions
    • 6.3 Anonymous functions
    • 6.4 Function composition
    • 6.5 More about functions insights
      • 6.5.1 Lexical scoping
      • 6.5.2 … (dot-dot-dot)
      • 6.5.3 Exiting a function
      • 6.5.4 Function forms
    • 6.6 Case Study: SIR model function
    • 6.7 Meeting Videos
      • 6.7.1 Cohort 1
      • 6.7.2 Cohort 2
      • 6.7.3 Cohort 3
      • 6.7.4 Cohort 4
      • 6.7.5 Cohort 5
      • 6.7.6 Cohort 6
      • 6.7.7 Cohort 7
  • 7 Environments
    • 7.1 SLIDE 1
    • 7.2 Meeting Videos
      • 7.2.1 Cohort 1
      • 7.2.2 Cohort 2
      • 7.2.3 Cohort 3
      • 7.2.4 Cohort 4
      • 7.2.5 Cohort 5
      • 7.2.6 Cohort 6
      • 7.2.7 Cohort 7
  • 8 Conditions
    • 8.1 Introduction
    • 8.2 Signalling conditions
      • 8.2.1 Types of conditions
      • 8.2.2 ❌ Errors
      • 8.2.3 ⚠️ Warnings
      • 8.2.4 💬 Messages
    • 8.3 Ignoring conditions
      • 8.3.1 try()
      • 8.3.2 suppressWarnings(), suppressMessages()
    • 8.4 Handling conditions
      • 8.4.1 Condition objects
      • 8.4.2 Exiting handlers
      • 8.4.3 Calling handlers
      • 8.4.4 By default, conditions propagate
      • 8.4.5 But conditions can be muffled
      • 8.4.6 Call stacks
    • 8.5 Custom conditions
      • 8.5.1 Motivation
      • 8.5.2 Signalling
      • 8.5.3 Handling
    • 8.6 Applications
    • 8.7 Resources
    • 8.8 Meeting Videos
      • 8.8.1 Cohort 1
      • 8.8.2 Cohort 2
      • 8.8.3 Cohort 3
      • 8.8.4 Cohort 4
      • 8.8.5 Cohort 5
      • 8.8.6 Cohort 6
      • 8.8.7 Cohort 7
  • 9 Functionals
    • What are functionals
    • 9.1 Introduction
      • Benefits
    • 9.2 Map
    • Benefit of using the map function in purrr
    • Atomic vectors
    • Anonymous functions and shortcuts
    • Modify
    • 9.3 purrr style
    • 9.4 map_*() variants
    • map2_*()
    • The benefit of using the map over apply family of function
    • walk()
    • imap()
    • pmap()
    • 9.5 reduce() family
    • ggplot2 example with reduce
    • map_df*() variants
    • pluck()
    • Not covered: flatten()
    • Dealing with Failures
    • Safely
    • Possibly
    • 9.6 Meeting Videos
      • 9.6.1 Cohort 1
      • 9.6.2 Cohort 2
      • 9.6.3 Cohort 3
      • 9.6.4 Cohort 4
      • 9.6.5 Cohort 5
      • 9.6.6 Cohort 6
      • 9.6.7 Cohort 7
  • 10 Function factories
    • 10.1 What is a function factory?
    • 10.2 How does a function factory work?
    • 10.3 Important to remember
    • 10.4 Fundamentals - Environment
    • 10.5 Fundamentals - Forcing
    • 10.6 Forcing - Reiterated
    • 10.7 Fundamentals - Stateful functions
    • 10.8 Fundamentals - Garbage collection
    • 10.9 Useful Examples - Histograms and binwidth
    • 10.10 Useful Examples - Wrapper
    • 10.11 Useful Examples - Optimizing
    • 10.12 Function factories + functionals
    • 10.13 Meeting Videos
      • 10.13.1 Cohort 1
      • 10.13.2 Cohort 2
      • 10.13.3 Cohort 3
      • 10.13.4 Cohort 4
      • 10.13.5 Cohort 5
      • 10.13.6 Cohort 6
      • 10.13.7 Cohort 7
  • 11 Function operators
    • 11.1 Introduction
    • 11.2 Existing function operators
    • purrr::safely
    • Other purrr function operators
    • memoise::memoise
    • Exercise
    • 11.3 Case study: make your own function operator
    • Exercise
    • 11.4 Meeting Videos
      • 11.4.1 Cohort 1
      • 11.4.2 Cohort 2
      • 11.4.3 Cohort 3
      • 11.4.4 Cohort 4
      • 11.4.5 Cohort 5
      • 11.4.6 Cohort 6
      • 11.4.7 Cohort 7
  • 12 Base types
    • 12.1 Why OOP is hard in R
    • 12.2 OOP: Big Ideas
    • 12.3 OOP: Properties
      • 12.3.1 Objects have class
      • 12.3.2 Class is inherited
    • 12.4 OOP in R: Two Paradigms
      • 12.4.1 Concept Map
    • 12.5 OOP in base R
    • 12.6 OOP in packages
    • 12.7 How can you tell if an object is base or OOP?
      • 12.7.1 Functions
      • 12.7.2 sloop
      • 12.7.3 Class
    • 12.8 What about types?
      • 12.8.1 Vectors
      • 12.8.2 Functions
      • 12.8.3 Environments
      • 12.8.4 S4
      • 12.8.5 Language components
      • 12.8.6 Concept Map
    • 12.9 Be careful about the numeric type
    • 12.10 Meeting Videos
      • 12.10.1 Cohort 1
      • 12.10.2 Cohort 2
      • 12.10.3 Cohort 3
      • 12.10.4 Cohort 4
      • 12.10.5 Cohort 5
      • 12.10.6 Cohort 6
      • 12.10.7 Cohort 7
  • 13 S3
    • 13.1 Introcudion
    • 13.2 Basics
    • 13.3 Classes
      • 13.3.1 Constructors
      • 13.3.2 Validators
      • 13.3.3 Helpers
    • 13.4 Generics and methods
      • 13.4.1 Method dispatch
      • 13.4.2 Finding methods
      • 13.4.3 Creating methods
    • 13.5 Object styles
    • 13.6 Inheritance
      • 13.6.1 NextMethod()
      • 13.6.2 Allowing subclassing
    • 13.7 Meeting Videos
      • 13.7.1 Cohort 1
      • 13.7.2 Cohort 2
      • 13.7.3 Cohort 3
      • 13.7.4 Cohort 4
      • 13.7.5 Cohort 5
      • 13.7.6 Cohort 6
      • 13.7.7 Cohort 7
  • 14 R6
    • 14.1 A review of OOP
    • 14.2 Introducing R6
    • 14.3 Constructing an R6 class, the basics
    • 14.4 Constructing an R6 object
    • 14.5 R6 objects and method chaining
    • 14.6 R6 useful methods
    • 14.7 Constructing a bank account class
    • 14.8 Simple transactions
    • 14.9 Modifying the $print() method
    • 14.10 How does this work?
    • 14.11 Adding methods after class creation
    • 14.12 Inheritance
      • 14.12.1 Future instances debugging
      • 14.12.2 Individual object debugging
      • 14.12.3 Test out our debugged class
    • 14.13 Introspection
    • 14.14 Controlling access
    • 14.15 Privacy
    • 14.16 Active fields
    • 14.17 Adding a read-only bank account number
    • 14.18 How does an active field work?
    • 14.19 Reference semantics
    • 14.20 R6 makes it harder to reason about code
    • 14.21 Better sense of what’s going on by looking at a finalizer
    • 14.22 Consequences of R6 fields
    • 14.23 Why use R6?
    • 14.24 Meeting Videos
      • 14.24.1 Cohort 1
      • 14.24.2 Cohort 2
      • 14.24.3 Cohort 3
      • 14.24.4 Cohort 4
      • 14.24.5 Cohort 5
      • 14.24.6 Cohort 6
      • 14.24.7 Cohort 7
  • 15 S4
    • 15.1 Introduction
    • 15.2 Basics overview
      • 15.2.1 Set class
      • 15.2.2 Set generics
      • 15.2.3 Set methods
    • 15.3 Details on defining the class
      • 15.3.1 Inheritance
      • 15.3.2 Instantiation
      • 15.3.3 Validation
    • 15.4 Details on generics and methods
      • 15.4.1 Dictate dispatch via signature
      • 15.4.2 Define generics
    • 15.5 Example: lubridate::period()
      • 15.5.1 Define the class
      • 15.5.2 Validate object
      • 15.5.3 Set methods
    • 15.6 Meeting Videos
      • 15.6.1 Cohort 1
      • 15.6.2 Cohort 2
      • 15.6.3 Cohort 3
      • 15.6.4 Cohort 4
      • 15.6.5 Cohort 5
      • 15.6.6 Cohort 6
      • 15.6.7 Cohort 7
  • 16 Trade-offs
    • Introduction
    • S4 versus S3
    • R6 versus S3
    • Namespacing
    • Threading state
    • Method chaining
    • Umm… what about S7 ?
      • Primary references:
    • S7 briefly
    • Abbreviated introduction based on the vignette
    • So… switch to S7 ?
    • OOP system comparison
    • Meeting Videos
      • Cohort 1
      • Cohort 2
      • Cohort 3
      • Cohort 4
      • Cohort 5
      • Cohort 6
      • Cohort 7
  • 17 Big picture
    • 17.1 Code is data
    • 17.2 Code is a tree
    • 17.3 Code can generate code
    • 17.4 Evaluation runs code
    • 17.5 Customizing evaluations with functions
    • 17.6 Customizing evaluation with data
    • 17.7 Quosures
      • 17.7.1 Which environment is bundled?
    • 17.8 Meeting Videos
      • 17.8.1 Cohort 1
      • 17.8.2 Cohort 2
      • 17.8.3 Cohort 3
      • 17.8.4 Cohort 4
      • 17.8.5 Cohort 5
      • 17.8.6 Cohort 6
      • 17.8.7 Cohort 7
  • 18 Expressions
    • 18.1 Introduction
      • 18.1.1 Evaluating multiple expressions
    • 18.2 Abstract Syntax Tree (AST)
      • 18.2.1 With lobstr::ast():
      • 18.2.2 Infix calls
    • 18.3 Expression
      • 18.3.1 Constants
      • 18.3.2 Symbols
      • 18.3.3 Calls
      • 18.3.4 Subsetting
      • 18.3.5 Function position
      • 18.3.6 Constructing
    • 18.4 Parsing and grammar
      • 18.4.1 Associativity
      • 18.4.2 Parsing and deparsing
    • 18.5 Using the AST to solve more complicated problems
      • 18.5.1 Two helper functions
      • 18.5.2 Specific use cases for recurse_call()
      • 18.5.3 Example 1: Finding F and T
      • 18.5.4 Example 2: Finding all variables created by assignment
      • 18.5.5 Dealing with the base cases
      • 18.5.6 Dealing with the recursive cases
      • 18.5.7 Make the function more robust
    • 18.6 Specialised data structures
      • 18.6.1 Pairlists
      • 18.6.2 Missing arguments
      • 18.6.3 Expression vectors
    • 18.7 Meeting Videos
      • 18.7.1 Cohort 1
      • 18.7.2 Cohort 2
      • 18.7.3 Cohort 3
      • 18.7.4 Cohort 4
      • 18.7.5 Cohort 5
      • 18.7.6 Cohort 6
      • 18.7.7 Cohort 7
  • 19 Quasiquotation
    • 19.1 Introduction
    • 19.2 Motivation
    • Vocabulary
    • 19.3 Quoting
      • expr() and exprs()
      • enexpr() and enexprs()
      • ensym() and ensyms()
    • 19.4 Unquoting
      • Basic unquoting
      • Special usages or cases
    • 19.5 Non-quoting
    • 19.6 … (dot-dot-dot) [When using … with quoting]
    • exec() [Making your own …]
    • Base R do.call
      • Exercise 19.5.5 #1
    • 19.7 Case Studies (side note)
    • 19.8 Meeting Videos
      • 19.8.1 Cohort 1
      • 19.8.2 Cohort 2
      • 19.8.3 Cohort 3
      • 19.8.4 Cohort 4
      • 19.8.5 Cohort 5
      • 19.8.6 Cohort 6
      • 19.8.7 Cohort 7
  • 20 Evaluation
    • 20.1 A bit of a recap
    • 20.2 Evaluation basics
    • 20.3 Application: reimplementing source()
    • 20.4 Quosures
    • 20.5 Quosures and ...
    • 20.6 Other facts about quosures
    • 20.7 Data mask
    • 20.8 Pronouns: .data$ and .env$
    • 20.9 Application: reimplementing base::subset()
    • 20.10 Using tidy evaluation
    • 20.11 Base evaluation
    • 20.12 Meeting Videos
      • 20.12.1 Cohort 1
      • 20.12.2 Cohort 2
      • 20.12.3 Cohort 3
      • 20.12.4 Cohort 4
      • 20.12.5 Cohort 5
      • 20.12.6 Cohort 6
      • 20.12.7 Cohort 7
  • 21 Translating R code
    • 21.1 Case Study: MCQ
      • 21.1.1 Pop Quiz!
    • 21.2 HTML
    • 21.3 Escaping
      • 21.3.1 S3 Class
      • 21.3.2 Generic
      • 21.3.3 Checks
    • 21.4 Named Components
      • 21.4.1 Check
    • 21.5 Tags (calls)
      • 21.5.1 Checks
    • 21.6 Tags (processing)
      • 21.6.1 Example
    • 21.7 Bringing the HTML Together
      • 21.7.1 Main Example
      • 21.7.2 Check
    • 21.8 LaTeX
      • 21.8.1 to_math
    • 21.9 Known Symbols
    • 21.10 Known Functions
      • 21.10.1 Unary Operations
      • 21.10.2 Binary Operations
    • 21.11 Unknown Symbols
    • 21.12 Unknown Functions
    • 21.13 Bringing the LaTeX Together
      • 21.13.1 Check
    • 21.14 Finishing the Example
    • 21.15 Meeting Videos
      • 21.15.1 Cohort 1
      • 21.15.2 Cohort 2
      • 21.15.3 Cohort 3
      • 21.15.4 Cohort 4
      • 21.15.5 Cohort 5
      • 21.15.6 Cohort 6
  • 22 Debugging
    • Learning objectives
    • Introduction
      • Strategies for finding and fixing errors
    • Locating errors
    • Lazy evaluation
    • Interactive debugger
    • browser() commands
    • Alternatives
    • Breakpoints
    • recover()
    • debug()
    • Call stack
    • Non-interactive debugging
      • callr::r()
      • dump.frames()
      • Print debugging
      • RMarkdown
    • Non-error failures
    • Link to some useful resources on debugging
    • Meeting Videos
      • Cohort 1
      • Cohort 2
      • Cohort 3
      • Cohort 4
      • Cohort 5
      • Cohort 6
      • Cohort 7
  • 23 Measuring performance
    • 23.1 Introduction
    • 23.2 Profiling
      • 23.2.1 Exercise
    • 23.3 Microbenchmarking
    • 23.4 Resources
    • 23.5 Meeting Videos
      • 23.5.1 Cohort 1
      • 23.5.2 Cohort 2
      • 23.5.3 Cohort 3
      • 23.5.4 Cohort 4
      • 23.5.5 Cohort 5
      • 23.5.6 Cohort 6
      • 23.5.7 Cohort 7
  • 24 Improving performance
    • 24.1 Overview
    • 24.2 Organizing code
    • 24.3 Check for Existing Solution
    • 24.4 Do as little as possible
    • 24.5 Avoiding Method Dispatch
    • 24.6 Avoiding Input Coercion
    • 24.7 Vectorise
    • 24.8 Avoiding copies
    • 24.9 Case study: t-test
    • 24.10 Other techniques
    • 24.11 Meeting Videos
      • 24.11.1 Cohort 1
      • 24.11.2 Cohort 2
      • 24.11.3 Cohort 3
      • 24.11.4 Cohort 4
      • 24.11.5 Cohort 5
      • 24.11.6 Cohort 6
      • 24.11.7 Cohort 7
  • 25 Rewriting R code in C++
    • 25.1 Introduction
    • 25.2 Getting started with C++
      • First example
    • Example with scalar input and output
    • Vector Input, Scalar output:
    • Vector input and output
    • Source your C++ code
      • Example
    • 25.3 Data frames, functions, and attributes
      • Lists and Dataframes
      • Functions
    • 25.4 Missing values
      • Missing values behave differently for C++ scalers
      • 25.4.1 Vectors
    • 25.5 Standard Template Library
      • Iterators
      • Algorithms
    • Data Structures
    • 25.6 Case Studies
    • Case study 1: Gibbs sampler
    • Case study 2: predict a model response from three inputs
    • 25.7 Resources
    • 25.8 Op Success!
    • 25.9 Meeting Videos
      • 25.9.1 Cohort 1
      • 25.9.2 Cohort 2
      • 25.9.3 Cohort 3
      • 25.9.4 Cohort 4
      • 25.9.5 Cohort 5
      • 25.9.6 Cohort 6
      • 25.9.7 Cohort 7
  • Published with bookdown

Advanced R Book Club

Related tools

  • while(condition) action: performs action while condition is TRUE.

  • repeat(action): repeats action forever (i.e. until it encounters break).

  • Note that for can be rewritten as while and while can be rewritten as repeat (this goes in one direction only!); however:

Good practice is to use the least-flexible solution to a problem, so you should use for wherever possible. BUT you shouldn’t even use for loops for data analysis tasks as map() and apply() already provide less flexible solutions to most problems. (More in Chapter 9.)

for (i in 1:5) {
  print(i)
}
#> [1] 1
#> [1] 2
#> [1] 3
#> [1] 4
#> [1] 5

x_option <- function(x) {
  switch(x,
    a = "option 1",
    b = "option 2",
    c = "option 3"#,
    #stop("Invalid `x` value")
  )
}
i <- 1

while(i <=5 ) {
  print(i)
  i <- i+1
}
#> [1] 1
#> [1] 2
#> [1] 3
#> [1] 4
#> [1] 5
i <- 1

repeat {
  print(i)
  i <- i+1
  if (i > 5) break
}
#> [1] 1
#> [1] 2
#> [1] 3
#> [1] 4
#> [1] 5