# D-optimal DOE suggest repeated samples

I tried to generate a D optimal design but the design output sounds very weird to me. I have a (real) process and Id like to explore 3 factors, but the process have a lot of constraints so I provide a candidate set for the design generator. I have 20 possibilities, but only have money/time for 12 samples.

Let me paste the code here (I'm using gen_design function, from skpr package at R language)

config_machine <- matrix(c(5, 3, 20,
5, 3, 2210.,
5, 1, 1753.,
4, 3, 2105.,
4, 1, 2022.,
4, 1, 874,
5, 3, 2001.,
4, 3, 979,
5, 3, 811,
5, 2, 750,
4, 1, 853,
4, 2, 1836.,
4, 3, 895,
5, 3, 100,
5, 2, 832,
4, 2, 2043.,
4, 3, 1795.,
4, 1, 1815.,
4, 2, 937,
4, 3, 1920.),3,20)
config_machine <- t(config_machine)
colnames(config_machine) <- c('X1', 'X2', 'X3')
df <- as.data.frame(config_machine)
design <- gen_design(candidateset = df, model = ~X1 + X2 + X3,
trials = 12,repeats = 1000)
design


But the optimal design will show some like this

row X1 X2 X3
1 5 3 20
2 5 3 2210
3 5 3 20
4 4 3 2105
5 5 1 1753
6 5 1 1753
7 5 3 2210
8 4 3 2105
9 4 1 853
10 4 3 2105
11 5 3 20
12 4 1 853


Sounds very weird to me the sample 1,3 and 11 are the same point (5,3,20)! I only have 12 samples but the function is wasting my samples using repeated measures. What is my mistake? I tried to read the documentation but didnt find any tip.

Minutes ago I tried to solve the same design at minitab, but the output design was also show repeated samples. Any tips?

Actually the factor X1 and X2 are categorical, and I need provide this information for gen_design. This was my mistake :).

Just for curiosity Ill share more information about my process.

• X1 are a type of engine, the amount of blades at engine (categorical)

• X2 are a manufacturer (categorical)

• X3 is the relative distance from the first engine at the factory

We have 50 machines at total but we only have budget to install sensors at 12 machines. Well use information from this 12 sensors to provide some kind of machine behavior of the other 38 machines. We are developing a R&D project for intend to increase efficiency from the total 50 engines.

We think that use D-optimal DOE sounds a good idea to choose the 12 machines.

• To the downvoters: This question is on-topic and clear enough! Oct 25, 2019 at 18:25
• X1 sounds like a cont variable, not then categorical (8 blades is more than 5 blades, so should be treated as numerical. X2 categorical, X3 numerical. Why do you believe that relative distance from first engine is an important variable? (not clear what it is) Nov 2, 2019 at 21:39
• Jketil, actually we have this machines inside a river and the enviroment conditions should be diferent between the first machine, the machine at middle and the last machine (water speed, water quality, turbulence). Nov 6, 2019 at 22:12

After running your code I did

lapply(df,  range)
$X1 [1] 4 5$X2
[1] 1 3

\$X3
[1]   20 2210


and comparing with the generated design, observe that for X1 only the extremes 4 and 5 are used, same for X2, while X3 has some interior points. That make me actually doubt you found an actual optimum! What happens is: For a D-optimal design for the simple model ~ X1, an optimal design will be concentrated on the minimum and maximum points of the range of X1. This should not be too difficult to prove. The idea is that the optimization assumes (as it must), that the model is correct, and does not assign some points to check for linearity, say. So if you want a design that have some interior points, try the model ~ x1 + I(X1^2). It is not clear how this generalizes to a linear model with multiple variables, if an orthogonal design is possible, that could be preferred (and will omit interior points), but if not possible, maybe the inclusion of some interior points could make correlations closer to zero, which could improve the determinant. But as a general rule, D-optimal designs will prefer boundary points (think that a determinant is a hyper-volume, and to increase volume you should go to the boundary.)

But going to the boundary suggests finding the convex hull of the points in df. We should expect the points actually used in the design should be taken from the corner points on the convex hull (which in this case will be the smallest polyhedron enclosing all the points.) We can do that by

     hulldf <- geometry::convhulln(df)
hulldf
[,1] [,2] [,3]
[1,]   13   11    1
[2,]    5   11    3
[3,]    5    2    4
[4,]    5    2    3
[5,]   10   11    1
[6,]   10   11    3
[7,]   13    2    1
[8,]   13    2    4
[9,]    5   13    4
[10,]    5   13   11
[11,]   10    2    1
[12,]   10    2    3
attr(,"convhulln")
<pointer: 0x55e02aa9e120>
> unique(c(hulldf))
[1] 13  5 10 11  2  1  3  4


The last line above gives the row numbers from df of the points forming the convex hull. We should expect the optimal design to be chosen from this points. To find the points actually used in design, do

    findrows <- function(df1,  df2) {
stopifnot(NCOL(df1)==NCOL(df2))
# For each row in df2,  find which row it equals in df1
N <- NROW(df2)
out <- integer(length=N)
for (i in 1:N) {
row <- c(df2[i, ])
for (j in 1:(NROW(df1))) {
if(isTRUE(all.equal(row, c(df1[j, ]))))
{out[i]<-j; break}
}
}
out
}

used <- findrows(df, design)
used
[1]  3  1  4  1  2  3 11  4  4  1  2 11
table(used)
used
1  2  3  4 11
3  2  2  3  2
unique(used)
[1]  3  1  4  2 11


and by comparing with the output above we find that the rows 5, 10, 13 which are corners on the convex hull was not used in the design. That merits an investigation into why.

You could try

    design2 <- gen_design(candidateset = df, model = ~ X1 + X2 +
X3 + X1:X2 + X1:X3 + X2:X3 + I(X2^2) + I(X3^2),
trials = 12,repeats = 1000)

design2
X1 X2   X3
1   5  2  750
2   4  2 2043
3   5  3   20
4   4  1 2022
5   5  3 2210
6   4  1  853
7   4  3  895
8   4  3 2105
9   5  1 1753
10  4  2  937
11  5  3  811
12  5  3   20


and compare. We did not include I(X1^2) because the variable X1 does only have two levels. If what you want is a response surface design, that could be better. But you didn't tell us your ultimate goal with the design.

• Thanks kjetil! Ill read your response more times to try to understand your comment in deep. Thanks for help! Oct 25, 2019 at 13:02
• If you like it you can upvote (and accept) it! Oct 25, 2019 at 18:22
• Kjetil, I tried to upvote your answer but I dont have enough points to do that. Im beginner and dont have 15 point to stackexchange allow me upvote your answer. I find my mistake (I believe...) and I`ll write about that Oct 28, 2019 at 14:14
• @kjetilbhalvorsen can you please look into this and see if you could contribute there as well. Mar 29, 2020 at 18:03