library(designit)
library(ggplot2)
#> Want to understand how all the pieces fit together? Read R for Data
#> Science: https://r4ds.hadley.nz/
library(dplyr)
#>
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#>
#> filter, lag
#> The following objects are masked from 'package:base':
#>
#> intersect, setdiff, setequal, union
library(tidyr)
(latin square should give the best score)
First using a combination of two OSAT scores (for row and column).
This usually produces a latin square when using the squared L2 norm (L2s) for aggregation of the 2 scores.
# Setting up the batch container
example1 <- BatchContainer$new(
dimensions = c(
plate = 1,
row = 4, col = 4
)
)
# Add samples to container
# Need unique Sample ID. Can we drop this constraint?
example1 <- assign_in_order(example1,
samples = tibble::tibble(
Group = rep(c("Grp 1", "Grp 2", "Grp 3", "Grp 4"), each = 4),
ID = 1:16
)
)
# The following does not work (an gives a constant score of 144!)
# scoring_f <- osat_score_generator(batch_vars = c("row","col"), feature_vars = c("Group"))
# First analysis of problem indicates that osat_score generates a full row*col vector of 'ideal scores'
# which are in fact the same value, implying an identical overall result as each position can be either
# allocated by 1 sample or 0 samples, the sum of 1's being the sample count.
# --> don't use osat_score if there's a lack of samples as compared to possible positioning
# # Set scoring function
scoring_f <- list(
Row.Score = osat_score_generator(batch_vars = c("row"), feature_vars = c("Group")),
Column.Score = osat_score_generator(batch_vars = c("col"), feature_vars = c("Group"))
)
set.seed(41)
bc <- optimize_design(
example1,
scoring = scoring_f,
max_iter = 300, # this is set to shorten vignette run-time based on known random seed, normally we don't know.
n_shuffle = 2,
acceptance_func = mk_simanneal_acceptance_func(mk_simanneal_temp_func(T0 = 1000, alpha = 0.5)),
aggregate_scores_func = L2s_norm
)
#> Checking variances of 2-dim. score vector.
#> ... (11.385, 16.687) - OK
#> Initial score: c(48, 0)
#> Aggregated: 2304
#> Achieved score: c(36, 4) at iteration 1
#> Aggregated: 1312
#> Achieved score: c(24, 4) at iteration 2
#> Aggregated: 592
#> Achieved score: c(24, 12) at iteration 3
#> Aggregated: 720
#> Achieved score: c(24, 8) at iteration 4
#> Aggregated: 640
#> Achieved score: c(16, 10) at iteration 5
#> Aggregated: 356
#> Achieved score: c(12, 10) at iteration 6
#> Aggregated: 244
#> Achieved score: c(10, 10) at iteration 7
#> Aggregated: 200
#> Achieved score: c(10, 6) at iteration 9
#> Aggregated: 136
#> Achieved score: c(10, 4) at iteration 10
#> Aggregated: 116
#> Achieved score: c(8, 10) at iteration 11
#> Aggregated: 164
#> Achieved score: c(8, 8) at iteration 12
#> Aggregated: 128
#> Achieved score: c(8, 8) at iteration 14
#> Aggregated: 128
#> Achieved score: c(4, 10) at iteration 19
#> Aggregated: 116
#> Achieved score: c(4, 6) at iteration 20
#> Aggregated: 52
#> Achieved score: c(4, 4) at iteration 22
#> Aggregated: 32
#> Achieved score: c(4, 4) at iteration 27
#> Aggregated: 32
#> Achieved score: c(4, 4) at iteration 36
#> Aggregated: 32
#> Achieved score: c(4, 4) at iteration 38
#> Aggregated: 32
#> Achieved score: c(0, 4) at iteration 39
#> Aggregated: 16
#> Achieved score: c(0, 4) at iteration 50
#> Aggregated: 16
#> Achieved score: c(0, 4) at iteration 54
#> Aggregated: 16
#> Achieved score: c(0, 4) at iteration 82
#> Aggregated: 16
#> Achieved score: c(0, 4) at iteration 87
#> Aggregated: 16
#> Achieved score: c(0, 4) at iteration 119
#> Aggregated: 16
#> Achieved score: c(0, 4) at iteration 125
#> Aggregated: 16
#> Achieved score: c(0, 4) at iteration 200
#> Aggregated: 16
#> Achieved score: c(4, 0) at iteration 215
#> Aggregated: 16
#> Achieved score: c(0, 0) at iteration 284
#> Aggregated: 0
bc$trace$elapsed
#> Time difference of 4.846822 secs
plot_plate(bc,
plate = plate, row = row, column = col, .color = Group,
title = "Ex1: Using OSAT scores for plate design\n(not the recommended way!)"
)
Now using a dedicated scoring for the group distances on a plate.
This should reliably lead to a nice symmetry-bearing latin square design with only a one-dimensional score to look at.
scoring_f <- mk_plate_scoring_functions(bc, row = "row", column = "col", group = "Group")
set.seed(42)
bc <- optimize_design(
example1,
scoring = scoring_f,
max_iter = 1000, # this is set to shorten vignette run-time based on random seed, normally we don't know.
n_shuffle = 2,
acceptance_func = mk_simanneal_acceptance_func(mk_simanneal_temp_func(T0 = 1000, alpha = 0.5)),
quiet = TRUE
)
bc$trace$elapsed
#> Time difference of 4.184167 secs
plot_plate(bc,
plate = plate, row = row, column = col, .color = Group,
title = "Ex1: Using a dedicated plate scoring function:\nThis should show a latin square!"
)