Processing math: 8%
+ - 0:00:00
Notes for current slide
Notes for next slide

These slides are viewed best by Chrome or Firefox and occasionally need to be refreshed if elements did not load properly. Please note this web version takes a while to load. See here for the PDF .


Press the right arrow to progress to the next slide!

1/76

Constructing experimental designs with the edibble R-package


Presenter: Emi Tanaka

Department of Econometrics and Business Statistics,
     Monash University, Melbourne, Australia

emi.tanaka@monash.edu

@statsgen

9 Nov 2021 @ Applications of Statistical Procedures in Biological Data


1/76

Table of Contents

1 Experimental design basics

2 Current state of experimental design tools

3 Software design for an everyday user

4 The grammar of experimental designs with edibble

These slides made using R powered by HTML/CSS/JS can be found at
emitanaka.org/slides/stats4bio2021/edibble

2/76

1


Experimental design basics

3/76

Experiment

Essential scientific endeavors to collect data to explore, understand or verify phenomena.

4/76

Big picture terminologies

Experimental data

The gold standard in data collection.

(provided that experimental design is satisfactory)
5/76

Comparative experiments

Collecting data to compare the effects of different conditions under a controlled environment with the goal of drawing generalisable conclusions

6/76

Designing comparative experiments

... to identify data-collection schemes that achieve sensitivity and specificity requirements despite biological and technical variability, while keeping time and resource costs low.

— Krzywinski & Altman (2014)

Krzywinski, M., Altman, N. Designing comparative experiments. Nat Methods 11, 597–598 (2014). https://doi.org/10.1038/nmeth.2974

7/76

Designing comparative experiments

... to identify data-collection schemes that achieve sensitivity and specificity requirements despite biological and technical variability, while keeping time and resource costs low.

— Krzywinski & Altman (2014)

Planning the controlled environment such that there is a higher confidence that effects can be attributed to selected conditions

Krzywinski, M., Altman, N. Designing comparative experiments. Nat Methods 11, 597–598 (2014). https://doi.org/10.1038/nmeth.2974

7/76

Basic terminology in comparative experiments modified versions of Bailey (2008)

A treatment (T) is the entire description of the condition applied to an experimental unit.

Experimental unit (Ω) is the smallest unit that the treatment can be independently applied to.

Observational unit (Ωo) is the smallest unit in which the response will be measured on.

  • Not to be confused with responses \boldsymbol{Y}.
  • May or may not be the same as experimental unit.

Block, also called cluster, is the unit that group some other units (e.g. experimental units) such that the units within the same block (cluster) are more alike (homogeneous).

A design (D: \Omega \rightarrow \mathcal{T}) is the allotment of treatments to particular set of units.

A plan or layout is the design translated into actual units. Randomisation is usually involved in the translation process.

Bailey, R. (2008). Design of Comparative Experiments (Cambridge Series in Statistical and Probabilistic Mathematics). Cambridge: Cambridge University Press. doi:10.1017/CBO9780511611483

8/76

Experimental structures as defined by Bailey (2008)

Unit structure means meaningful ways of dividing up experimental units (\Omega) and observational units (\Omega_o).

For example:

  • Unstructured
  • Blocking

Treatment structure means meaningful ways of dividing up \mathcal{T}.

For example:

  • Unstructured: no grouping within \mathcal{T}
  • Factorial: all combinations of at least two factors
  • Factorial + control

Bailey, R. (2008). Design of Comparative Experiments (Cambridge Series in Statistical and Probabilistic Mathematics). Cambridge: Cambridge University Press. doi:10.1017/CBO9780511611483

9/76

Unreplicated experiments

  • Experimental units: 3 cows
  • Observational units: 3 cows
  • Observation: milk yield
  • Treatments: 3 types of supplements
  • Allotment: supplements cows
  • Replication: 1 each
10/76

Unreplicated experiments

  • Experimental units: 3 cows
  • Observational units: 3 cows
  • Observation: milk yield
  • Treatments: 3 types of supplements
  • Allotment: supplements cows
  • Replication: 1 each

Conclusion: produces most therefore is the most effective supplement for higher milk yield from cows out of the three supplements tested

How confident will you be of this statement?
10/76

Unreplicated experiments

  • Experimental units: 3 cows
  • Observational units: 3 cows
  • Observation: milk yield
  • Treatments: 3 types of supplements
  • Allotment: supplements cows
  • Replication: 1 each

Conclusion: produces most therefore is the most effective supplement for higher milk yield from cows out of the three supplements tested

How confident will you be of this conclusion?
  • No individual experimental units are the same
    (with some exceptions)
10/76

Treatment replications

  • Experimental units: 6 cows
  • Observational units: 6 cows
  • Observation: milk yield
  • Treatments: 3 types of supplements
  • Allotment: supplements cows
  • Replication: 2 each

Conclusion: produces most on average therefore is the most effective supplement for higher milk yield from cows out of the three supplements tested

How confident will you be of this conclusion now?
11/76

Treatment replications

  • Experimental units: 6 cows
  • Observational units: 6 cows
  • Observation: milk yield
  • Treatments: 3 types of supplements
  • Allotment: supplements cows
  • Replication: 2 each

Conclusion: produces most on average therefore is the most effective supplement for higher milk yield from cows out of the three supplements tested

How confident will you be of this conclusion now?
  • Treatment replications here allow us to estimate experimental unit (or error) variation
11/76

Plan 1 Treatment allocation for nested unit structure






  • Units: 2 pens with 3 cows each
  • Observational units: 6 cows
  • Treatments: 3 types of supplements
  • Allotment: supplements cows
Are the treatment means of say,
and comparable?
How would you distribute the treatments?
12/76

Plan 2 Treatment allocation for nested unit structure






  • Units: 2 pens with 3 cows each
  • Observational units: 6 cows
  • Treatments: 3 types of supplements
  • Allotment: supplements cows, with restriction such that each treatment appears once in each pen
  • Every treatment appears once in each pen
  • This is a better design since each treatment appears in every pen so you can be more confident that the treatment means are not due to the conditions of particular pens
13/76

Pseudo-replication





  • Units: 3 pens with 2 cows each
  • Observational units: 6 cows
  • Treatments: 3 types of supplements
  • Allotment: supplements pens
  • Replication: ??
14/76

Pseudo-replication





  • Units: 3 pens with 2 cows each
  • Observational units: 6 cows
  • Treatments: 3 types of supplements
  • Allotment: supplements pens
  • Replication: ??
What are the experimental units?
14/76

Pseudo-replication





  • Units: 3 pens with 2 cows each
  • Observational units: 6 cows
  • Treatments: 3 types of supplements
  • Allotment: supplements pens
  • Replication: ??
What are the experimental units?
  • Experimental units are the 3 pens.
14/76

Pseudo-replication





  • Units: 3 pens with 2 cows each
  • Observational units: 6 cows
  • Treatments: 3 types of supplements
  • Allotment: supplements pens
  • Replication: ??
What are the experimental units?
  • Experimental units are the 3 pens.

  • Meaning there is only one replication of each treatment.

14/76

Pseudo-replication





  • Units: 3 pens with 2 cows each
  • Observational units: 6 cows
  • Treatments: 3 types of supplements
  • Allotment: supplements pens
  • Replication: ??
What are the experimental units?
  • Experimental units are the 3 pens.

  • Meaning there is only one replication of each treatment.

  • Meaning you cannot estimate the error variation in the pen stratum.
14/76

Pseudo-replication





  • Units: 3 pens with 2 cows each
  • Observational units: 6 cows
  • Treatments: 3 types of supplements
  • Allotment: supplements pens
  • Replication: ??
What are the experimental units?
  • Experimental units are the 3 pens.

  • Meaning there is only one replication of each treatment.

  • Meaning you cannot estimate the error variation in the pen stratum.
  • Pseudo-replication means that you treat repetition as replication in the analysis
14/76

Systematic designs

  • Experimental units: 6 cows
  • Observational units: 6 cows
  • Observation: milk yield
  • Treatments: 3 types of supplements
  • Allotment: supplements cows
  • Replication: 2 each
  • Assignment: systematic order
What could go wrong with this?
14/76

Systematic designs

  • Experimental units: 6 cows
  • Observational units: 6 cows
  • Observation: milk yield
  • Treatments: 3 types of supplements
  • Allotment: supplements cows
  • Replication: 2 each
  • Assignment: systematic order
What could go wrong with this?
  • The order of the experimental units may be confounded with some extraneous factor
14/76

Systematic designs

  • Experimental units: 6 cows
  • Observational units: 6 cows
  • Observation: milk yield
  • Treatments: 3 types of supplements
  • Allotment: supplements cows
  • Replication: 2 each
  • Assignment: systematic order
What could go wrong with this?
  • The order of the experimental units may be confounded with some extraneous factor

  • Like say, the order of the experimental units was determined by the speed (fast to slow) of the cow to get to the feed

14/76

Systematic designs

  • Experimental units: 6 cows
  • Observational units: 6 cows
  • Observation: milk yield
  • Treatments: 3 types of supplements
  • Allotment: supplements cows
  • Replication: 2 each
  • Assignment: systematic order
What could go wrong with this?
  • The order of the experimental units may be confounded with some extraneous factor

  • Like say, the order of the experimental units was determined by the speed (fast to slow) of the cow to get to the feed

  • This means that the more active cows are given and leasat active ones are given

14/76

Randomised designs

  • Experimental units: 6 cows
  • Observational units: 6 cows
  • Observation: milk yield
  • Treatments: 3 types of supplements
  • Allotment: supplements cows
  • Replication: 2 each
  • Assignment: random order
  • Randomisation protects you against bias and potential unwanted confounding with extraneous factors
15/76

Randomised designs

  • Experimental units: 6 cows
  • Observational units: 6 cows
  • Observation: milk yield
  • Treatments: 3 types of supplements
  • Allotment: supplements cows
  • Replication: 2 each
  • Assignment: random order
  • Randomisation protects you against bias and potential unwanted confounding with extraneous factors
  • Bias comes in many forms: obvious to not-so obvious, known to unknown, and so on.
15/76

Randomised designs

  • Experimental units: 6 cows
  • Observational units: 6 cows
  • Observation: milk yield
  • Treatments: 3 types of supplements
  • Allotment: supplements cows
  • Replication: 2 each
  • Assignment: random order
  • Randomisation protects you against bias and potential unwanted confounding with extraneous factors
  • Bias comes in many forms: obvious to not-so obvious, known to unknown, and so on.
  • Randomisation doesn't mean it'll completely shield you from all biases!
15/76

Randomised designs

  • Experimental units: 6 cows
  • Observational units: 6 cows
  • Observation: milk yield
  • Treatments: 3 types of supplements
  • Allotment: supplements cows
  • Replication: 2 each
  • Assignment: random order
  • Randomisation protects you against bias and potential unwanted confounding with extraneous factors
  • Bias comes in many forms: obvious to not-so obvious, known to unknown, and so on.
  • Randomisation doesn't mean it'll completely shield you from all biases!
  • You can get a systematic order by chance! This doesn't mean you should keep on randomising your design until get the layout you want! You should instead add another unit structure before randomisation.
15/76

Factorial treatment structure 1






  • Experimental units: 12 plots
  • Observational units: 12 plots
  • Observation: wheat yield
  • Treatments: combination of:
    • Water: irrigated or rain-fed
    • Fertilizer: type A or type B
  • Allotment:
    • Water plots
    • Fertilizer plots
  • Assignment: random order
How many treatments are there?
16/76

Factorial treatment structure 1






  • Experimental units: 12 plots
  • Observational units: 12 plots
  • Observation: wheat yield
  • Treatments: combination of:
    • Water: irrigated or rain-fed
    • Fertilizer: type A or type B
  • Allotment:
    • Water plots
    • Fertilizer plots
  • Assignment: random order
How many treatments are there?
Treatment Replication
3
3
3
3
Treatment factor Count
6
6
6
6
16/76

Factorial treatment structure 2






  • Experimental units: 12 plots
  • Observational units: 12 plots
  • Observation: wheat yield
  • Treatments: combination of:
    • Water: irrigated or rain-fed
    • Fertilizer: type A or type B
  • Allotment:
    • Water and fertilizer plots
  • Assignment: random order
Treatment Replication
3
3
3
3
Treatment factor Count
6
6
6
6
17/76

Factorial treatment structure, nested unit structure, and treatment constraint







  • Units: 6 strips with 2 plots each
  • Observational units: 12 plots
  • Observation: wheat yield
  • Treatments: combination of:
    • Water: irrigated or rain-fed
    • Fertilizer: type A or type B
  • Allotment:
    • Water strip
    • Fertilizer plot
  • Assignment: random order
18/76

Some classical "named" experimental designs


A Completely Randomised Design

B Randomised Complete Block Design

C Factorial Design

D Split-Plot Design

19/76

A Completely Randomised Design (CRD)


  • Experimental units: 6 cows
  • Observational units: 6 cows
  • Observation: milk yield
  • Treatments: 3 types of supplements
  • Allotment: supplements cows
  • Replication: 2 each
  • Assignment: random order
20/76

B Randomised Complete Block Design (RCBD)




  • Units: 2 pens with 3 cows each
  • Observational units: 6 cows
  • Treatments: 3 types of supplements
  • Allotment: supplements cows, with restriction such that each treatment appears once in each pen
  • Assignment: random order
21/76

C Factorial Design






  • Experimental units: 12 plots
  • Observational units: 12 plots
  • Observation: wheat yield
  • Treatments: combination of:
    • Water: irrigated or rain-fed
    • Fertilizer: type A or type B
  • Allotment:
    • Water and fertilizer plots
  • Assignment: random order
22/76

D Split-Plot Design








  • Units: 6 strips with 2 plots each
  • Observational units: 12 plots
  • Observation: wheat yield
  • Treatments: combination of:
    • Water: irrigated or rain-fed
    • Fertilizer: type A or type B
  • Allotment:
    • Water strip
    • Fertilizer plot
  • Assignment: random order
23/76

2


Current state of experimental design tools

24/76

CRAN Task View of
Design of Experiments
& Analysis of Experimental Data

contains

📦 109 R-packages

based on the ctv package version 0.8.5

25/76

CRAN Task View of
Design of Experiments
& Analysis of Experimental Data

contains

📦 109 R-packages

based on the ctv package version 0.8.5

In contrast, only a handful of libraries exist in Python
(namely pyDOE, pyDOE2, dexpy, experimenter and GPdoemd).

25/76
  • Sheer quantity and variation in the output experimental design in the R-packages are arguably unmatched with any other programming languages
  • E.g. in Python, there are only a handful of libraries that generate design of experiment exist (namely pyDOE, pyDOE2, dexpy, experimenter and GPdoemd) with limited outputs.
  • This demonstrates how R is a programming language with large statistical community contributions

Design of experiments area appear to have the least collaboration

Thanks to Dewi Lestari Amaliah for the graph!

26/76

Design of experiments area appear to have the least collaboration

Thanks to Dewi Lestari Amaliah for the graph!

Authors tend to work in silos limited knowledge sharing across silos perhaps

26/76

Top downloaded R-packages in the design of experiments

Top 5 in 2016

Package Downloads
agricolae 73,521
AlgDesign 57,037
ez 37,488
lhs 23,518
DoE.base 20,651

Top 5 in 2020

Package Downloads
agricolae 171,813
lhs 165,415
AlgDesign 153,582
DiceKriging 92,287
DiceDesign 88,160

agricolae is one of the top downloaded

(total download based on logs from the RStudio CRAN mirror scrubbed by Danyang Dai)

27/76

agricolae

a case of classical named randomised designs

28/76

A agricolae::design.crd

Completely randomised design for t = 3 treatments with 2 replicates each

trt <- c("A", "B", "C")
agricolae::design.crd(trt = trt, r = 2)
## $parameters
## $parameters$design
## [1] "crd"
##
## $parameters$trt
## [1] "A" "B" "C"
##
## $parameters$r
## [1] 2 2 2
##
## $parameters$serie
## [1] 2
##
## $parameters$seed
## [1] 241038711
##
## $parameters$kinds
## [1] "Super-Duper"
##
## $parameters[[7]]
## [1] TRUE
##
##
## $book
## plots r trt
## 1 101 1 B
## 2 102 1 C
## 3 103 1 A
## 4 104 2 A
## 5 105 2 C
## 6 106 2 B
29/76

B agricolae::design.rcbd

Randomised complete block design for t =3 treatments with 2 blocks

trt <- c("A", "B", "C")
agricolae::design.rcbd(trt = trt, r = 2)
## $parameters
## $parameters$design
## [1] "rcbd"
##
## $parameters$trt
## [1] "A" "B" "C"
##
## $parameters$r
## [1] 2
##
## $parameters$serie
## [1] 2
##
## $parameters$seed
## [1] 351889891
##
## $parameters$kinds
## [1] "Super-Duper"
##
## $parameters[[7]]
## [1] TRUE
##
##
## $sketch
## [,1] [,2] [,3]
## [1,] "A" "C" "B"
## [2,] "B" "C" "A"
##
## $book
## plots block trt
## 1 101 1 A
## 2 102 1 C
## 3 103 1 B
## 4 201 2 B
## 5 202 2 C
## 6 203 2 A

30/76

C agricolae::design.ab()

Factorial design for t = 3 \times 2 treatments with 2 replication for each treatment

agricolae::design.ab(trt = c(3, 2), r = 2, design = "crd")
## $parameters
## $parameters$design
## [1] "factorial"
##
## $parameters$trt
## [1] "1 1" "1 2" "2 1" "2 2" "3 1" "3 2"
##
## $parameters$r
## [1] 2 2 2 2 2 2
##
## $parameters$serie
## [1] 2
##
## $parameters$seed
## [1] 34955907
##
## $parameters$kinds
## [1] "Super-Duper"
##
## $parameters[[7]]
## [1] TRUE
##
## $parameters$applied
## [1] "crd"
##
##
## $book
## plots r A B
## 1 101 1 2 2
## 2 102 1 2 1
## 3 103 1 1 2
## 4 104 2 2 1
## 5 105 1 3 1
## 6 106 2 2 2
## 7 107 1 1 1
## 8 108 2 3 1
## 9 109 2 1 2
## 10 110 2 1 1
## 11 111 1 3 2
## 12 112 2 3 2

Note not A/B testing!



31/76

D agricolae::design.split()

Split-plot design for t = 2 \times 4 treatments with 2 replication for each treatment

trt1 <- c("I", "R"); trt2 <- LETTERS[1:4]
agricolae::design.split(trt1 = trt1, trt2 = trt2, r = 2, design = "crd")
## $parameters
## $parameters$design
## [1] "split"
##
## $parameters[[2]]
## [1] TRUE
##
## $parameters$trt1
## [1] "I" "R"
##
## $parameters$applied
## [1] "crd"
##
## $parameters$r
## [1] 2 2
##
## $parameters$serie
## [1] 2
##
## $parameters$seed
## [1] -1981495681
##
## $parameters$kinds
## [1] "Super-Duper"
##
##
## $book
## plots splots r trt1 trt2
## 1 101 1 1 R D
## 2 101 2 1 R C
## 3 101 3 1 R B
## 4 101 4 1 R A
## 5 102 1 1 I A
## 6 102 2 1 I C
## 7 102 3 1 I D
## 8 102 4 1 I B
## 9 103 1 2 R B
## 10 103 2 2 R C
## 11 103 3 2 R A
## 12 103 4 2 R D
## 13 104 1 2 I C
## 14 104 2 2 I A
## 15 104 3 2 I B
## 16 104 4 2 I D
32/76

Good design considers units and treatments first, and then allocates treatments to units. It does not choose from a menu of named designs.

—Rosemary Bailey (2008)

33/76

AlgDesign

a case of optimised (model-based) designs

34/76

AlgDesign::gen.factorial()

  • First, a helper function to create the treatment (and replicate) combinations:
dat <- AlgDesign::gen.factorial(levels = 3,
nVars = 3,
center = FALSE,
varNames = c("irrigation",
"fertilizer",
"variety"),
factors = "all")
dat
## irrigation fertilizer variety
## 1 1 1 1
## 2 2 1 1
## 3 3 1 1
## 4 1 2 1
## 5 2 2 1
## 6 3 2 1
## 7 1 3 1
## 8 2 3 1
## 9 3 3 1
## 10 1 1 2
## 11 2 1 2
## 12 3 1 2
## 13 1 2 2
## 14 2 2 2
## 15 3 2 2
## 16 1 3 2
## 17 2 3 2
## 18 3 3 2
## 19 1 1 3
## 20 2 1 3
## 21 3 1 3
## 22 1 2 3
## 23 2 2 3
## 24 3 2 3
## 25 1 3 3
## 26 2 3 3
## 27 3 3 3
35/76

AlgDesign::optFederov

  • Optimum design with 14 trials using Federov's exchange algorithm
AlgDesign::optFederov(frml = ~ ., # assume additive effects
data = dat,
nTrials = 14,
criterion = "D")
## $D
## [1] 0.2343815
##
## $A
## [1] 6.25
##
## $Ge
## [1] 0.727
##
## $Dea
## [1] 0.687
##
## $design
## irrigation fertilizer variety
## 2 2 1 1
## 3 3 1 1
## 4 1 2 1
## 5 2 2 1
## 7 1 3 1
## 9 3 3 1
## 10 1 1 2
## 13 1 2 2
## 15 3 2 2
## 17 2 3 2
## 19 1 1 3
## 23 2 2 3
## 24 3 2 3
## 25 1 3 3
##
## $rows
## [1] 2 3 4 5 7 9 10 13 15 17 19 23 24 25
36/76

AlgDesign::optBlock()

  • An optimal design with 3 blocks of size 9.
AlgDesign::optBlock(frml = ~ ., # assume additive effects
withinData = dat,
blocksizes = rep(9, 3),
criterion = "D")
## $D
## [1] 0.1924501
##
## $diagonality
## [1] 0.866
##
## $Blocks
## $Blocks$B1
## irrigation fertilizer variety
## 2 2 1 1
## 5 2 2 1
## 8 2 3 1
## 12 3 1 2
## 15 3 2 2
## 16 1 3 2
## 21 3 1 3
## 22 1 2 3
## 25 1 3 3
##
## $Blocks$B2
## irrigation fertilizer variety
## 1 1 1 1
## 6 3 2 1
## 9 3 3 1
## 10 1 1 2
## 13 1 2 2
## 18 3 3 2
## 20 2 1 3
## 23 2 2 3
## 26 2 3 3
##
## $Blocks$B3
## irrigation fertilizer variety
## 3 3 1 1
## 4 1 2 1
## 7 1 3 1
## 11 2 1 2
## 14 2 2 2
## 17 2 3 2
## 19 1 1 3
## 24 3 2 3
## 27 3 3 3
##
##
## $design
## irrigation fertilizer variety
## 2 2 1 1
## 5 2 2 1
## 8 2 3 1
## 12 3 1 2
## 15 3 2 2
## 16 1 3 2
## 21 3 1 3
## 22 1 2 3
## 25 1 3 3
## 1 1 1 1
## 6 3 2 1
## 9 3 3 1
## 10 1 1 2
## 13 1 2 2
## 18 3 3 2
## 20 2 1 3
## 23 2 2 3
## 26 2 3 3
## 3 3 1 1
## 4 1 2 1
## 7 1 3 1
## 11 2 1 2
## 14 2 2 2
## 17 2 3 2
## 19 1 1 3
## 24 3 2 3
## 27 3 3 3
##
## $rows
## [1] 2 5 8 12 15 16 21 22 25 1 6 9 10 13 18 20 23 26 3 4 7 11 14 17 19 24 27
37/76

What were the experiments about?

38/76

What were the experiments about?

Context is key in
experimental design

38/76

What were the experiments about?

Context is key in
experimental design

Units and allocation are often implicitly understood

38/76

3


Software design
for an everyday user

39/76

Benefits of programming

40/76

Benefits of programming

  1. Computational reproducibility
40/76

Benefits of programming

  1. Computational reproducibility

  2. Allows greater flexibility

40/76

Benefits of programming

  1. Computational reproducibility

  2. Allows greater flexibility

  3. Can promote higher order thinking

40/76

Benefits of programming

  1. Computational reproducibility

  2. Allows greater flexibility

  3. Can promote higher order thinking
    if the software is designed with the user in mind

40/76

Software design for users

41/76

Software design for users

  • A user interacts with the software interface
41/76

Software design for users

  • A user interacts with the software interface
  • The interface design can make a huge difference to an everyday user
41/76

Drawing faces 1 Specific instructions for the computer

Drawing a happy face

42/76

Drawing faces 1 Specific instructions for the computer

Drawing a happy face

library(grid)
# face shape
grid.circle(x = 0.5, y = 0.5, r = 0.5)


42/76

Drawing faces 1 Specific instructions for the computer

Drawing a happy face

library(grid)
# face shape
grid.circle(x = 0.5, y = 0.5, r = 0.5)
# eyes
grid.circle(x = c(0.35, 0.65),
y = c(0.6, 0.6),
r = 0.05,
gp = gpar(fill = "black"))


42/76

Drawing faces 1 Specific instructions for the computer

Drawing a happy face

library(grid)
# face shape
grid.circle(x = 0.5, y = 0.5, r = 0.5)
# eyes
grid.circle(x = c(0.35, 0.65),
y = c(0.6, 0.6),
r = 0.05,
gp = gpar(fill = "black"))
# mouth
grid.curve(x1 = 0.4, y1 = 0.4,
x2 = 0.6, y2 = 0.4,
square = FALSE)


42/76

Drawing faces 1 Specific instructions for the computer

Drawing a sad face

43/76

Drawing faces 1 Specific instructions for the computer

Drawing a sad face

library(grid)
# face shape
grid.circle(x = 0.5, y = 0.5, r = 0.5)
# eyes
grid.circle(x = c(0.35, 0.65),
y = c(0.6, 0.6),
r = 0.05,
gp = gpar(fill = "black"))
# mouth
grid.curve(x1 = 0.4, y1 = 0.4,
x2 = 0.6, y2 = 0.4,
square = FALSE,
curvature = -1)


43/76

Drawing faces 2 Functional instructions for the computer

Use functions to draw faces

face1 <- function() {
grid::grid.circle(x = 0.5, y = 0.5, r = 0.5)
grid::grid.circle(x = c(0.35, 0.65),
y = c(0.6, 0.6),
r = 0.05,
gp = gpar(fill = "black"))
grid::grid.curve(x1 = 0.4, y1 = 0.4,
x2 = 0.6, y2 = 0.4,
square = FALSE)
}
face2 <- function() {
grid::grid.circle(x = 0.5, y = 0.5, r = 0.5)
grid::grid.circle(x = c(0.35, 0.65),
y = c(0.6, 0.6),
r = 0.05,
gp = gpar(fill = "black"))
grid::grid.curve(x1 = 0.4, y1 = 0.4,
x2 = 0.6, y2 = 0.4,
square = FALSE,
curvature = -1)
}
44/76

Drawing faces 2 Functional instructions for the computer

Use functions to draw faces

face1 <- function() {
grid::grid.circle(x = 0.5, y = 0.5, r = 0.5)
grid::grid.circle(x = c(0.35, 0.65),
y = c(0.6, 0.6),
r = 0.05,
gp = gpar(fill = "black"))
grid::grid.curve(x1 = 0.4, y1 = 0.4,
x2 = 0.6, y2 = 0.4,
square = FALSE)
}
face2 <- function() {
grid::grid.circle(x = 0.5, y = 0.5, r = 0.5)
grid::grid.circle(x = c(0.35, 0.65),
y = c(0.6, 0.6),
r = 0.05,
gp = gpar(fill = "black"))
grid::grid.curve(x1 = 0.4, y1 = 0.4,
x2 = 0.6, y2 = 0.4,
square = FALSE,
curvature = -1)
}
face1()

44/76

Drawing faces 2 Functional instructions for the computer

Use functions to draw faces

face1 <- function() {
grid::grid.circle(x = 0.5, y = 0.5, r = 0.5)
grid::grid.circle(x = c(0.35, 0.65),
y = c(0.6, 0.6),
r = 0.05,
gp = gpar(fill = "black"))
grid::grid.curve(x1 = 0.4, y1 = 0.4,
x2 = 0.6, y2 = 0.4,
square = FALSE)
}
face2 <- function() {
grid::grid.circle(x = 0.5, y = 0.5, r = 0.5)
grid::grid.circle(x = c(0.35, 0.65),
y = c(0.6, 0.6),
r = 0.05,
gp = gpar(fill = "black"))
grid::grid.curve(x1 = 0.4, y1 = 0.4,
x2 = 0.6, y2 = 0.4,
square = FALSE,
curvature = -1)
}
face1()

face2()

44/76

Drawing faces 2 Functional instructions for the computer

Use functions to draw faces

face1 <- function() {
grid::grid.circle(x = 0.5, y = 0.5, r = 0.5)
grid::grid.circle(x = c(0.35, 0.65),
y = c(0.6, 0.6),
r = 0.05,
gp = gpar(fill = "black"))
grid::grid.curve(x1 = 0.4, y1 = 0.4,
x2 = 0.6, y2 = 0.4,
square = FALSE)
}
face2 <- function() {
grid::grid.circle(x = 0.5, y = 0.5, r = 0.5)
grid::grid.circle(x = c(0.35, 0.65),
y = c(0.6, 0.6),
r = 0.05,
gp = gpar(fill = "black"))
grid::grid.curve(x1 = 0.4, y1 = 0.4,
x2 = 0.6, y2 = 0.4,
square = FALSE,
curvature = -1)
}
face1()


face1()

face2()

44/76
  • I can repeatedly call the function
  • Drawing happy or sad faces are easier now

Drawing faces 2 Functional instructions for the computer

Use functions to draw faces

face1 <- function() {
grid::grid.circle(x = 0.5, y = 0.5, r = 0.5)
grid::grid.circle(x = c(0.35, 0.65),
y = c(0.6, 0.6),
r = 0.05,
gp = gpar(fill = "black"))
grid::grid.curve(x1 = 0.4, y1 = 0.4,
x2 = 0.6, y2 = 0.4,
square = FALSE)
}
face2 <- function() {
grid::grid.circle(x = 0.5, y = 0.5, r = 0.5)
grid::grid.circle(x = c(0.35, 0.65),
y = c(0.6, 0.6),
r = 0.05,
gp = gpar(fill = "black"))
grid::grid.curve(x1 = 0.4, y1 = 0.4,
x2 = 0.6, y2 = 0.4,
square = FALSE,
curvature = -1)
}
face1()


face1()

face2()


face1()

44/76

Drawing faces 2 Functional instructions for the computer

Use functions to draw faces

face1 <- function() {
grid::grid.circle(x = 0.5, y = 0.5, r = 0.5)
grid::grid.circle(x = c(0.35, 0.65),
y = c(0.6, 0.6),
r = 0.05,
gp = gpar(fill = "black"))
grid::grid.curve(x1 = 0.4, y1 = 0.4,
x2 = 0.6, y2 = 0.4,
square = FALSE)
}
face2 <- function() {
grid::grid.circle(x = 0.5, y = 0.5, r = 0.5)
grid::grid.circle(x = c(0.35, 0.65),
y = c(0.6, 0.6),
r = 0.05,
gp = gpar(fill = "black"))
grid::grid.curve(x1 = 0.4, y1 = 0.4,
x2 = 0.6, y2 = 0.4,
square = FALSE,
curvature = -1)
}
face1()


face1()


face2()

face2()


face1()

44/76

Drawing faces 2 Functional instructions for the computer

Use functions to draw faces

face1 <- function() {
grid::grid.circle(x = 0.5, y = 0.5, r = 0.5)
grid::grid.circle(x = c(0.35, 0.65),
y = c(0.6, 0.6),
r = 0.05,
gp = gpar(fill = "black"))
grid::grid.curve(x1 = 0.4, y1 = 0.4,
x2 = 0.6, y2 = 0.4,
square = FALSE)
}
face2 <- function() {
grid::grid.circle(x = 0.5, y = 0.5, r = 0.5)
grid::grid.circle(x = c(0.35, 0.65),
y = c(0.6, 0.6),
r = 0.05,
gp = gpar(fill = "black"))
grid::grid.curve(x1 = 0.4, y1 = 0.4,
x2 = 0.6, y2 = 0.4,
square = FALSE,
curvature = -1)
}
face1()


face1()


face2()

face2()


face1()


face1()

44/76

Drawing faces 3 Human-centered design

Adapt computational systems for human use with syntactic sugar

45/76

Drawing faces 3 Human-centered design

Adapt computational systems for human use with syntactic sugar

face1()

face2()

face3()

?

45/76

Drawing faces 3 Human-centered design

Adapt computational systems for human use with syntactic sugar

face1()

face2()

face3()

?


Alternative function names:

face_happy()
face_sad()
face_angry()

Now what do you expect for the output?

45/76

Drawing faces 3 Human-centered design

Adapt computational systems for human use with syntactic sugar

face1()

face2()

face3()

?


Alternative function names:

face_happy()
face_sad()
face_angry()

Now what do you expect for the output?

  • Functions are named after emotions
  • Emotion is a surrogate for describing the entire face
45/76

What if you want to draw a face that is winking?

46/76

What if you want to draw a face that is winking?

... with a grin?

46/76

What if you want to draw a face that is winking?

... with a grin?

... or with the tongue out?

46/76

What if you want to draw a face that is winking?

... with a grin?

... or with the tongue out?


The differences between facial features are small, but you need an entire new function that contains instructions for the whole face and a new function name.

46/76

What if you want to draw a face that is winking?

... with a grin?

... or with the tongue out?


The differences between facial features are small, but you need an entire new function that contains instructions for the whole face and a new function name.

How would you design the system to draw faces?

46/76

Drawing faces 4 Rethinking function arguments as facial parts

Let's reframe how we think

47/76

Drawing faces 4 Rethinking function arguments as facial parts

Let's reframe how we think

https://github.com/emitanaka/portrait

library(portrait)
48/76

Drawing faces 4 Rethinking function arguments as facial parts

Let's reframe how we think

https://github.com/emitanaka/portrait

library(portrait)
  • Let's reframe how we think
  • A face is made up of:
    • eyes
    • mouth
    • shape
48/76

Drawing faces 4 Rethinking function arguments as facial parts

Let's reframe how we think

https://github.com/emitanaka/portrait

library(portrait)
  • Let's reframe how we think
  • A face is made up of:
    • eyes
    • mouth
    • shape
face(eyes = "googly",
mouth = "smile",
shape = "round")

49/76

Drawing faces 4 Rethinking function arguments as facial parts

Let's reframe how we think

https://github.com/emitanaka/portrait

library(portrait)
  • Let's reframe how we think
  • A face is made up of:
    • eyes
    • mouth
    • shape
face(eyes = "googly",
mouth = "smile",
shape = "round")

face(eyes = "round",
mouth = "sad",
shape = "oval")

49/76

Drawing faces 4 Rethinking function arguments as facial parts

Let's reframe how we think

https://github.com/emitanaka/portrait

library(portrait)
  • Let's reframe how we think
  • A face is made up of:
    • eyes
    • mouth
    • shape
face(eyes = "googly",
mouth = "smile",
shape = "round")

face(eyes = "round",
mouth = "sad",
shape = "oval")

  • We can easily make large number of faces with a single function
49/76

Drawing faces 4 Rethinking function arguments as facial parts

Let's reframe how we think

https://github.com/emitanaka/portrait

library(portrait)
  • Let's reframe how we think
  • A face is made up of:
    • eyes
    • mouth
    • shape
face(eyes = "googly",
mouth = "smile",
shape = "round")

face(eyes = "round",
mouth = "sad",
shape = "oval")

  • We can easily make large number of faces with a single function
  • It makes users think about faces based on facial features
49/76

Drawing faces 4 Rethinking function arguments as facial parts

Let's reframe how we think

https://github.com/emitanaka/portrait

library(portrait)
  • Let's reframe how we think
  • A face is made up of:
    • eyes
    • mouth
    • shape
face(eyes = "googly",
mouth = "smile",
shape = "round")

face(eyes = "round",
mouth = "sad",
shape = "oval")

  • We can easily make large number of faces with a single function
  • It makes users think about faces based on facial features

But what about hair, nose and other facial features?

49/76

Drawing faces 4 Rethinking function arguments as facial parts

Let's reframe how we think

  • A face is made up of:
    • eyes
    • mouth
    • shape
    • hair
    • nose
  • Adding more arguments:
face(eyes = "googly",
mouth = "smile",
shape = "round",
hair = "none",
nose = "simple")

face(eyes = "googly",
mouth = "smile",
shape = "round",
hair = "mohawk",
nose = "simple")

50/76

Drawing faces 4 Rethinking function arguments as facial parts

Let's reframe how we think

  • A face is made up of:
    • eyes
    • mouth
    • shape
    • hair
    • nose
  • Adding more arguments:
face(eyes = "googly",
mouth = "smile",
shape = "round",
hair = "none",
nose = "simple")

face(eyes = "googly",
mouth = "smile",
shape = "round",
hair = "mohawk",
nose = "simple")


But about other facial features?

50/76

Drawing faces 5 Object oriented programming

Rethink everything as an object

51/76

Drawing faces 5 Object oriented programming

Rethink everything as an object

library(portrait)
face()

52/76

Drawing faces 5 Object oriented programming

Rethink everything as an object

library(portrait)
face() +
cat_shape()

53/76

Drawing faces 5 Object oriented programming

Rethink everything as an object

library(portrait)
face() +
cat_shape() +
cat_eyes()

54/76

Drawing faces 5 Object oriented programming

Rethink everything as an object

library(portrait)
face() +
cat_shape() +
cat_eyes() +
cat_nose()

55/76

Drawing faces 5 Object oriented programming

Rethink everything as an object

library(portrait)
face() +
cat_shape() +
cat_eyes() +
cat_nose() +
cat_whiskers()

56/76

Drawing faces 5 Object oriented programming

Rethink everything as an object

library(portrait)
face() +
dog_shape() +
cat_eyes(fill = "red") +
cat_nose() +
cat_whiskers()

57/76

Drawing faces 5 Object oriented programming

Rethink everything as an object

library(portrait)
face() +
dog_shape() +
cat_eyes(fill = "red") +
cat_nose() +
cat_whiskers(size = 6,
color = "brown") +
sketch_mouth(smile = 0.3,
size = 3)

58/76

Software design for everyday users

  1. Imperative instructions for the computer more work for humans
  2. Recipe functions One function to draw one complete face
  3. Syntactic syntax Make it easier for humans to read code
  4. A function with multiple arguments
    One function to draw multiple complete faces
  5. Finite number of functions to draw
    infinite possible incomplete and complete faces

The tool you choose to use can enforce a certain way of thinking and may restrict you on what you can do.

59/76
  • You can lock yourself in a system that doesn't help you grow.

4


The grammar of experimental designs with edibble

60/76

The grammar of experimental design with edibble

library(edibble)
start_design("My experiment")

61/76

The grammar of experimental design with edibble

library(edibble)
start_design("My experiment") %>%
set_units(wholeplot = 4)

62/76

The grammar of experimental design with edibble

library(edibble)
start_design("My experiment") %>%
set_units(wholeplot = 4) %>%
set_units(subplot = nested_in(wholeplot, 2))

63/76

The grammar of experimental design with edibble

library(edibble)
start_design("My experiment") %>%
set_units(wholeplot = 4,
subplot = nested_in(wholeplot, 2))

64/76

The grammar of experimental design with edibble

library(edibble)
start_design("My experiment") %>%
set_units(wholeplot = 4,
subplot = nested_in(wholeplot, 2)) %>%
set_trts(water = c("irrigated", "rainfed"),
fertilizer = c("A", "B"))

65/76

The grammar of experimental design with edibble

library(edibble)
start_design("My experiment") %>%
set_trts(water = c("irrigated", "rainfed"),
fertilizer = c("A", "B")) %>%
set_units(wholeplot = 4,
subplot = nested_in(wholeplot, 2))

66/76

The grammar of experimental design with edibble

library(edibble)
start_design("My experiment") %>%
set_trts(water = c("irrigated", "rainfed")) %>%
set_units(wholeplot = 4) %>%
set_trts(fertilizer = c("A", "B")) %>%
set_units(subplot = nested_in(wholeplot, 2))

67/76

The grammar of experimental design with edibble

library(edibble)
start_design("My experiment") %>%
set_units(wholeplot = 4,
subplot = nested_in(wholeplot, 2)) %>%
set_trts(water = c("irrigated", "rainfed"),
fertilizer = c("A", "B")) %>%
allot_trts(water ~ wholeplot,
fertilizer ~ subplot)

68/76

The grammar of experimental design with edibble

library(edibble)
start_design("My experiment") %>%
set_units(wholeplot = 4,
subplot = nested_in(wholeplot, 2)) %>%
set_trts(water = c("irrigated", "rainfed"),
fertilizer = c("A", "B")) %>%
allot_trts(water ~ wholeplot,
fertilizer ~ subplot) %>%
assign_trts("random", seed = 1)

69/76

The grammar of experimental design with edibble

library(edibble)
start_design("My experiment") %>%
set_units(wholeplot = 4,
subplot = nested_in(wholeplot, 2)) %>%
set_trts(water = c("irrigated", "rainfed"),
fertilizer = c("A", "B")) %>%
allot_trts(water ~ wholeplot,
fertilizer ~ subplot) %>%
assign_trts("random", seed = 1) %>%
serve_table()

70/76

The grammar of experimental design with edibble

library(edibble)
start_design("Modified design") %>%
set_units(block = 2,
subplot = nested_in(block, 4)) %>%
set_trts(water = c("irrigated", "rainfed"),
fertilizer = c("A", "B")) %>%
allot_trts(water:fertilizer ~ subplot) %>%
assign_trts("random", seed = 1) %>%
serve_table()

  • The resulting design is what we call "randomised complete block design"
71/76

The grammar of experimental design with edibble

library(edibble)
start_design("Modified design") %>%
set_units(block = 2,
subplot = nested_in(block, 4)) %>%
set_trts(water = c("irrigated", "rainfed"),
fertilizer = c("A", "B")) %>%
allot_trts(water:fertilizer ~ subplot) %>%
assign_trts("random", seed = 1) %>%
serve_table()

  • The resulting design is what we call "randomised complete block design"
71/76

The grammar of experimental design with edibble

library(edibble)
start_design("Modified design") %>%
set_units(block = 2,
subplot = nested_in(block, 4)) %>%
set_trts(water = c("irrigated", "rainfed"),
fertilizer = c("A", "B")) %>%
allot_trts(water:fertilizer ~ subplot) %>%
assign_trts("random", seed = 1) %>%
set_rcrds_of(subplot = c("yield", "disease"),
block = "manager") %>%
serve_table()
  • The functions are reminiscent of the fundamental experimental terminology

72/76

The grammar of experimental design with edibble

out <- start_design("Modified design") %>%
set_units(block = 2,
subplot = nested_in(block, 4)) %>%
set_trts(water = c("irrigated", "rainfed"),
fertilizer = c("A", "B")) %>%
allot_trts(water:fertilizer ~ subplot) %>%
assign_trts("random", seed = 1) %>%
set_rcrds_of(subplot = c("yield", "disease"),
block = "manager") %>%
expect_rcrds(yield = to_be_numeric(with_value(">=", 0)),
disease = to_be_factor(levels = c("none", "moderate", "severe"))) %>%
serve_table()
73/76

The grammar of experimental design with edibble

out <- start_design("Modified design") %>%
set_units(block = 2,
subplot = nested_in(block, 4)) %>%
set_trts(water = c("irrigated", "rainfed"),
fertilizer = c("A", "B")) %>%
allot_trts(water:fertilizer ~ subplot) %>%
assign_trts("random", seed = 1) %>%
set_rcrds_of(subplot = c("yield", "disease"),
block = "manager") %>%
expect_rcrds(yield = to_be_numeric(with_value(">=", 0)),
disease = to_be_factor(levels = c("none", "moderate", "severe"))) %>%
serve_table()
export_design(out, file = "design-layout.xlsx", overwrite = TRUE)
  • The exported file has data validation features embedded
73/76

There are more (not-well documented) features in edibble

74/76

There are more (not-well documented) features in edibble

More on those on Thursday!

74/76
  • Our understanding of experimental design is growing and so the tool should evolve with better understanding
75/76
  • Our understanding of experimental design is growing and so the tool should evolve with better understanding
  • The idea for edibble was conceived early 2019, the code base was released publicly on 31st Dec 2020.
75/76
  • Our understanding of experimental design is growing and so the tool should evolve with better understanding
  • The idea for edibble was conceived early 2019, the code base was released publicly on 31st Dec 2020.

  • Since its initial public realease, underlying structure in edibble has evolved drastically for the better

75/76
  • Our understanding of experimental design is growing and so the tool should evolve with better understanding
  • The idea for edibble was conceived early 2019, the code base was released publicly on 31st Dec 2020.

  • Since its initial public realease, underlying structure in edibble has evolved drastically for the better

  • The development of a good tool is a community effort so...

75/76

Get in touch!

  • The purpose of edibble is to help you plan experiments better
  • edibble gets better with feedback
76/76
  • edibble is a community effort
  • make use

Constructing experimental designs with the edibble R-package


Presenter: Emi Tanaka

Department of Econometrics and Business Statistics,
     Monash University, Melbourne, Australia

emi.tanaka@monash.edu

@statsgen

9 Nov 2021 @ Applications of Statistical Procedures in Biological Data


1/76
Paused

Help

Keyboard shortcuts

, , Pg Up, k Go to previous slide
, , Pg Dn, Space, j Go to next slide
Home Go to first slide
End Go to last slide
Number + Return Go to specific slide
b / m / f Toggle blackout / mirrored / fullscreen mode
c Clone slideshow
p Toggle presenter mode
t Restart the presentation timer
?, h Toggle this help
oTile View: Overview of Slides
Esc Back to slideshow