jvbraun / AlgDesign

Algorithmic Experimental Design by Robert E. Wheeler
12 stars 5 forks source link

OptFederov: bug for one-factor designs #15

Closed timwaite closed 2 years ago

timwaite commented 2 years ago

The wrong result is given when trying to compute a design with one factor. Here is a minimal example:

library(AlgDesign) levels = seq(-1,1,by=.1) optFederov( ~., levels, nTrials=10, maxIteration=1000, nRepeats=100 )

$design X1 1 -1.0 2 -0.9 3 -0.8 4 -0.7 5 -0.6 17 0.6 18 0.7 19 0.8 20 0.9 21 1.0

However, the design should have 5 replicates each of +1 and -1.

Similarly for a quadratic model: optFederov( ~quad(.), levels, nTrials=9, maxIteration=1000, nRepeats=100)

$design X1 1 -1.0 2 -0.9 3 -0.8 10 -0.1 11 0.0 12 0.1 19 0.8 20 0.9 21 1.0

but the design should have 3 replicates each of -1, 0, and 1.

It does not make a difference if we specify the candidate set as a data frame with one column. However, oddly, if we do the same problem using a 2-factor candidate set then the correct design is found, e.g. candidateSet = expand.grid(X1=levels,X2=levels) optFederov( ~quad(X1), candidateSet, nTrials=9, maxIteration=1000, nRepeats=100)

$design X1 X2 1 -1 -1.0 11 0 -1.0 21 1 -1.0 22 -1 -0.9 32 0 -0.9 42 1 -0.9 43 -1 -0.8 63 1 -0.8 368 0 0.7

The X1 column gives the correct design.

Perhaps the package just doesn't allow replicated points?

tylermorganwall commented 2 years ago

AlgDesign, as it stands currently, does not allow replicated points, which is what you're seeing here. I wrote the skpr package partially around this limitation.

library(skpr)
#> Loading required package: shiny
#> Warning: package 'shiny' was built under R version 4.0.5
levels = data.frame(x=seq(-1,1,by=.1))
gen_design(candidateset = levels, model = ~., trials = 10)
#>     x
#> 1   1
#> 2  -1
#> 3  -1
#> 4   1
#> 5   1
#> 6  -1
#> 7   1
#> 8   1
#> 9  -1
#> 10 -1
gen_design(candidateset = levels, model = ~.*. + I(x^2), trials = 10, randomized = F)
#>     x
#> 1  -1
#> 2  -1
#> 3  -1
#> 4   0
#> 5   0
#> 6   0
#> 7   0
#> 8   1
#> 9   1
#> 10  1

Alternatively, you can rbind the candidate set multiple times so AlgDesign has copies of each point it can pull from (but that gets expensive, fast).

jvbraun commented 2 years ago

Bob Wheeler also discusses this in his section on approximate theory designs. If you use the 'approximate' option you will get the expected result.

> levels = seq(-1,1,by=.1)
> optFederov( ~., levels, nTrials=10, maxIteration=1000, nRepeats=100, approximate=TRUE)
$D
[1] 1

$A
[1] 1

$Ge
[1] 1

$Dea
[1] 1

$design
   Rep.. X1
1      5 -1
21     5  1

$rows
[1]  1 21
timwaite commented 2 years ago

Thanks both, this is very helpful. @tylermorganwall you will be glad to know that I presented examples to my class using skpr!