Lecture material, notes, and code

Before we talk about Latin squares we should talk about the differences between blocks and factors. A block is a source of nuisance variability that is known and controlled. Examples would include operators with different characteristics, machines that operate slightly differently. Say I have 3 different machines and am interested in the effects of two different chemical compounds. In writing the model equation we ignore interactions between the blocks.

If these were factors there would be interactions. We wouldn’t expect any interaction between the operator and the compound, even though there are differences between operators. Assuming this is the case, we can lay out an experiment with two replicates that looks like this:

Let’s add another factor and go with 3 replicates:

Each combination of operator, machine, and chemistry is repeated 3 times for a total of 27 observations. That’s a lot. Can be expensive. A Latin square is a way to deal with this challenge.

The key is that everything is a block except 1 factor. No interactions. Blocks and factors must have the same number of levels. Let’s do a 3x3 Latin square. That’s two blocks and one factor, each has 3 levels.

There are lots of ways to do this consistent with the rules. Randomly choose one of these allowable designs.

This is orthogonal and balanced but not complete, every operator tests each chemistry on every machine, but not every level of the factor (chemistry). Now we have 9 observations. If we had a randomized complete block design (RCBD), each operator would measure the yield for each level of each compound on each machine, 27 observations. The Latin square approach gives 9 observations, 8 degrees of freedom, can do anova. An example:

#### Latin Squares ####
#install.packages("agricolae")
library(agricolae)
## Warning: package 'agricolae' was built under R version 4.3.3
trts<-c("A","B","C")
outdesign <-design.lsd(trts,seed=343)
outdesign$sketch
##      [,1] [,2] [,3]
## [1,] "C"  "B"  "A" 
## [2,] "A"  "C"  "B" 
## [3,] "B"  "A"  "C"
outdesign$book 
##   plots row col trts
## 1   101   1   1    C
## 2   102   1   2    B
## 3   103   1   3    A
## 4   201   2   1    A
## 5   202   2   2    C
## 6   203   2   3    B
## 7   301   3   1    B
## 8   302   3   2    A
## 9   303   3   3    C

Let’s add some data and do an analysis:

dat<-outdesign$book
dat$response<-c(45,64,34,65,43,23,45,67,65)
str(dat)
## 'data.frame':    9 obs. of  5 variables:
##  $ plots   : num  101 102 103 201 202 203 301 302 303
##  $ row     : Factor w/ 3 levels "1","2","3": 1 1 1 2 2 2 3 3 3
##  $ col     : Factor w/ 3 levels "1","2","3": 1 2 3 1 2 3 1 2 3
##  $ trts    : Factor w/ 3 levels "A","B","C": 3 2 1 1 3 2 2 1 3
##  $ response: num  45 64 34 65 43 23 45 67 65
model<-aov(response~row+col+trts,data=dat) 
summary(model)
##             Df Sum Sq Mean Sq F value Pr(>F)
## row          2  379.6   189.8   0.387  0.721
## col          2  461.6   230.8   0.470  0.680
## trts         2  196.2    98.1   0.200  0.833
## Residuals    2  981.6   490.8

We can look at the blocks but we’re going with the assumption we know what the blocks are doing. We are interested in the factor, trts, and it is not significant. The Latin square has saved us a lot of time and money but we may have missed something.

Fractional Factorial Designs

Now we’re going to look at ways to quickly get to the significant factors without taking forever. We want to do some screening experiments.

If we had 10 factors that might be important, a 2 level full factorial would be 1024 observations, no replicates.

This gets out of hand pretty quickly. The model equation has 1024 elements if we include all the higher order interactions. So, we’re going to look at main effects and some first order interactions. Ignoring the rest results in confounding, mixing different factors together and losing orthogonality. Comparing full factorial with partial

So, how do we decide which corner points to use? We need a design generator and a defining relationship. We will be able to tell which effects are confounded.

The full factorial model follows for this 3 factor experiment. Let’s look at the fractional design that follows from the 3 factor full factorial. For this example try this:

Going in a slightly different direction,

Add a D column defined by the design generator D = ABC, that is, take the sign of the product of the signs of ABC.

This allows us to determine which corner points to collect data from:

The design generator comes from a table of optimal designs. Now, what is the alias structure? We know that in this design D is given by ABC. Multiplying D=ABC by D on both sides yields the defining relationship DD=I=ABCD. This then can be used to identify the aliased effects using A(ABCD)=AA(BCD)=I(BCD)=BCD, B = ACD, C = ABD, D = ABC

Main effects are confounded with 2nd order interactions, probably not a problem. 1st order interactions are confounded with other 1st order interactions, which may be a problem.

Reviewing,

  1. generate the table of pluses and minuses for the k-p design

  2. add a column for the p main effect using the design generator

  3. determine the corner points from which to collect data

  4. collect the data and analyze

  5. write out the alias structure

Design resolution:

Higher resolution is better but requires more observations. You can find a table of optimal designs in Montgomery’s book. Example:

26 is 64 observations, 26-3 is only 8 observations.

Again,

  1. generate the 26-3 design

  2. decide on resolution and identify generators

  3. populate table with the p factors.

  4. identify the corner points at which observations will be made

That is to say, if it’s a plus it will be part of the cornerpoint, minus no.

The aliasing is complicated, since there are now 3 generators. Easy to get this screwed up in the higher order interactions but not to worry, they probably aren’t significant. In R they’re not even reported.

So just hold on to the low order interactions, ignore everything more complicated than 2 factor interactions. As above we’re concentrating on the alias between A and BD and CE. Ok, now some stuff in R.

#install.packages("FrF2") 
library(FrF2) 
## Warning: package 'FrF2' was built under R version 4.3.3
## Loading required package: DoE.base
## Warning: package 'DoE.base' was built under R version 4.3.3
## Loading required package: grid
## Loading required package: conf.design
## Registered S3 method overwritten by 'DoE.base':
##   method           from       
##   factorize.factor conf.design
## 
## Attaching package: 'DoE.base'
## The following objects are masked from 'package:stats':
## 
##     aov, lm
## The following object is masked from 'package:graphics':
## 
##     plot.design
## The following object is masked from 'package:base':
## 
##     lengths
#Set up resolution III design with 6 Factors 
des.res3<-FrF2(nfactors=6,resolution=3,randomize=TRUE) 
des.res3 
##    A  B  C  D  E  F
## 1  1  1 -1  1 -1 -1
## 2 -1  1 -1 -1  1 -1
## 3 -1 -1 -1  1  1  1
## 4 -1  1  1 -1 -1  1
## 5  1 -1 -1 -1 -1  1
## 6  1  1  1  1  1  1
## 7 -1 -1  1  1 -1 -1
## 8  1 -1  1 -1  1 -1
## class=design, type= FrF2
#Print aliased relationships 
aliasprint(des.res3) 
## $legend
## [1] A=A B=B C=C D=D E=E F=F
## 
## $main
## [1] A=BD=CE B=AD=CF C=AE=BF D=AB=EF E=AC=DF F=BC=DE
## 
## $fi2
## [1] AF=BE=CD

The randomized design is best, but you can also set randomize to false and get the table in more recognizable form:

#install.packages("FrF2") 
library(FrF2) 
#Set up resolution III design with 6 Factors 
des.res3<-FrF2(nfactors=6,resolution=3,randomize=FALSE) 
des.res3 
##    A  B  C  D  E  F
## 1 -1 -1 -1  1  1  1
## 2  1 -1 -1 -1 -1  1
## 3 -1  1 -1 -1  1 -1
## 4  1  1 -1  1 -1 -1
## 5 -1 -1  1  1 -1 -1
## 6  1 -1  1 -1  1 -1
## 7 -1  1  1 -1 -1  1
## 8  1  1  1  1  1  1
## class=design, type= FrF2
#Print aliased relationships 
aliasprint(des.res3) 
## $legend
## [1] A=A B=B C=C D=D E=E F=F
## 
## $main
## [1] A=BD=CE B=AD=CF C=AE=BF D=AB=EF E=AC=DF F=BC=DE
## 
## $fi2
## [1] AF=BE=CD
#Collect data and add response 
response<-c(30,46,46,33,210,140,262,120) 
des.resp<-add.response(des.res3,response) 
summary(des.resp) 
## Call:
## FrF2(nfactors = 6, resolution = 3, randomize = FALSE)
## 
## Experimental design of type  FrF2 
## 8  runs
## 
## Factor settings (scale ends):
##    A  B  C  D  E  F
## 1 -1 -1 -1 -1 -1 -1
## 2  1  1  1  1  1  1
## 
## Responses:
## [1] response
## 
## Design generating information:
## $legend
## [1] A=A B=B C=C D=D E=E F=F
## 
## $generators
## [1] D=AB E=AC F=BC
## 
## 
## Alias structure:
## $main
## [1] A=BD=CE B=AD=CF C=AE=BF D=AB=EF E=AC=DF F=BC=DE
## 
## $fi2
## [1] AF=BE=CD
## 
## 
## The design itself:
##    A  B  C  D  E  F response
## 1 -1 -1 -1  1  1  1       30
## 2  1 -1 -1 -1 -1  1       46
## 3 -1  1 -1 -1  1 -1       46
## 4  1  1 -1  1 -1 -1       33
## 5 -1 -1  1  1 -1 -1      210
## 6  1 -1  1 -1  1 -1      140
## 7 -1  1  1 -1 -1  1      262
## 8  1  1  1  1  1  1      120
## class=design, type= FrF2
#Generate Half Normal Plot (DanielPlot is another name for halfnormal plot) 
DanielPlot(des.resp,half=TRUE)

C looks important. Let’s check by looking at the main effects:

 #Recall that Main Effects ARE Aliased with 2Fact Interactions in Res III ?MEPlot 
MEPlot(des.resp,show.alias=TRUE) 

#fold over

Which clearly indicates that C is an important factor, but we have to remember that C is aliased with AE and BF two factor interactions.

Ok, now a semiconductor example.

Here are the factors and levels:

A little hard to read but the excel file is in the folder. The design generators were deduced by looking at the pluses and minuses. Then we find the corner points

Here are the data:

#Set up resolution IV design with 6 Factors 
des.res4<-FrF2(nfactors=6,resolution=4,randomize=FALSE) 
des.res4 
##     A  B  C  D  E  F
## 1  -1 -1 -1 -1 -1 -1
## 2   1 -1 -1 -1  1  1
## 3  -1  1 -1 -1  1  1
## 4   1  1 -1 -1 -1 -1
## 5  -1 -1  1 -1  1 -1
## 6   1 -1  1 -1 -1  1
## 7  -1  1  1 -1 -1  1
## 8   1  1  1 -1  1 -1
## 9  -1 -1 -1  1 -1  1
## 10  1 -1 -1  1  1 -1
## 11 -1  1 -1  1  1 -1
## 12  1  1 -1  1 -1  1
## 13 -1 -1  1  1  1  1
## 14  1 -1  1  1 -1 -1
## 15 -1  1  1  1 -1 -1
## 16  1  1  1  1  1  1
## class=design, type= FrF2
#Print aliased relationships 
aliasprint(des.res4) 
## $legend
## [1] A=A B=B C=C D=D E=E F=F
## 
## $main
## character(0)
## 
## $fi2
## [1] AB=CE=DF AC=BE    AD=BF    AE=BC    AF=BD    CD=EF    CF=DE
#Collect data and add response 
response<-c(6,10,32,60,4,15,26,60,8,12,34,60,16,5,37,52) 
des.resp<-add.response(des.res4,response) 
des.resp 
##     A  B  C  D  E  F response
## 1  -1 -1 -1 -1 -1 -1        6
## 2   1 -1 -1 -1  1  1       10
## 3  -1  1 -1 -1  1  1       32
## 4   1  1 -1 -1 -1 -1       60
## 5  -1 -1  1 -1  1 -1        4
## 6   1 -1  1 -1 -1  1       15
## 7  -1  1  1 -1 -1  1       26
## 8   1  1  1 -1  1 -1       60
## 9  -1 -1 -1  1 -1  1        8
## 10  1 -1 -1  1  1 -1       12
## 11 -1  1 -1  1  1 -1       34
## 12  1  1 -1  1 -1  1       60
## 13 -1 -1  1  1  1  1       16
## 14  1 -1  1  1 -1 -1        5
## 15 -1  1  1  1 -1 -1       37
## 16  1  1  1  1  1  1       52
## class=design, type= FrF2
summary(des.resp) 
## Call:
## FrF2(nfactors = 6, resolution = 4, randomize = FALSE)
## 
## Experimental design of type  FrF2 
## 16  runs
## 
## Factor settings (scale ends):
##    A  B  C  D  E  F
## 1 -1 -1 -1 -1 -1 -1
## 2  1  1  1  1  1  1
## 
## Responses:
## [1] response
## 
## Design generating information:
## $legend
## [1] A=A B=B C=C D=D E=E F=F
## 
## $generators
## [1] E=ABC F=ABD
## 
## 
## Alias structure:
## $fi2
## [1] AB=CE=DF AC=BE    AD=BF    AE=BC    AF=BD    CD=EF    CF=DE   
## 
## 
## The design itself:
##     A  B  C  D  E  F response
## 1  -1 -1 -1 -1 -1 -1        6
## 2   1 -1 -1 -1  1  1       10
## 3  -1  1 -1 -1  1  1       32
## 4   1  1 -1 -1 -1 -1       60
## 5  -1 -1  1 -1  1 -1        4
## 6   1 -1  1 -1 -1  1       15
## 7  -1  1  1 -1 -1  1       26
## 8   1  1  1 -1  1 -1       60
## 9  -1 -1 -1  1 -1  1        8
## 10  1 -1 -1  1  1 -1       12
## 11 -1  1 -1  1  1 -1       34
## 12  1  1 -1  1 -1  1       60
## 13 -1 -1  1  1  1  1       16
## 14  1 -1  1  1 -1 -1        5
## 15 -1  1  1  1 -1 -1       37
## 16  1  1  1  1  1  1       52
## class=design, type= FrF2
#Generate Half Normal Plot 
DanielPlot(des.resp,half=TRUE) 

#Generate Main Effects plot 
#Recall that Main Effects are NOT Aliased w/ 2Fact Interaction in Res IV 
MEPlot(des.resp,show.alias=TRUE)

Let’s do this again with imported data:

#Set up resolution IV design with 6 Factors 
des.semiconductor<-FrF2(16,generators=c("ABC","ACD"),randomize=FALSE)
des.semiconductor 
##     A  B  C  D  E  F
## 1  -1 -1 -1 -1 -1 -1
## 2   1 -1 -1 -1  1  1
## 3  -1  1 -1 -1  1 -1
## 4   1  1 -1 -1 -1  1
## 5  -1 -1  1 -1  1  1
## 6   1 -1  1 -1 -1 -1
## 7  -1  1  1 -1 -1  1
## 8   1  1  1 -1  1 -1
## 9  -1 -1 -1  1 -1  1
## 10  1 -1 -1  1  1 -1
## 11 -1  1 -1  1  1  1
## 12  1  1 -1  1 -1 -1
## 13 -1 -1  1  1  1 -1
## 14  1 -1  1  1 -1  1
## 15 -1  1  1  1 -1 -1
## 16  1  1  1  1  1  1
## class=design, type= FrF2.generators
#Print aliased relationships 
aliasprint(des.semiconductor) 
## $legend
## [1] A=A B=B C=C D=D E=E F=F
## 
## $main
## character(0)
## 
## $fi2
## [1] AB=CE    AC=BE=DF AD=CF    AE=BC    AF=CD    BD=EF    BF=DE
#Collect data and add response 
response<-read.csv("C:/Users/rgale/Downloads/Lecture14_XFab_SemiConductorExample_Data2.csv") 
response
##    Run Observation
## 1    1      157.25
## 2    2       48.00
## 3    3       44.00
## 4    4       55.75
## 5    5       55.75
## 6    6      230.00
## 7    7       97.25
## 8    8      225.00
## 9    9       50.25
## 10  10       85.25
## 11  11       31.50
## 12  12      160.00
## 13  13      113.75
## 14  14       92.75
## 15  15      150.75
## 16  16      115.00
head(response)
##   Run Observation
## 1   1      157.25
## 2   2       48.00
## 3   3       44.00
## 4   4       55.75
## 5   5       55.75
## 6   6      230.00
des.semiconductor<-add.response(des.semiconductor,response$Observation)
des.semiconductor 
##     A  B  C  D  E  F response.Observation
## 1  -1 -1 -1 -1 -1 -1               157.25
## 2   1 -1 -1 -1  1  1                48.00
## 3  -1  1 -1 -1  1 -1                44.00
## 4   1  1 -1 -1 -1  1                55.75
## 5  -1 -1  1 -1  1  1                55.75
## 6   1 -1  1 -1 -1 -1               230.00
## 7  -1  1  1 -1 -1  1                97.25
## 8   1  1  1 -1  1 -1               225.00
## 9  -1 -1 -1  1 -1  1                50.25
## 10  1 -1 -1  1  1 -1                85.25
## 11 -1  1 -1  1  1  1                31.50
## 12  1  1 -1  1 -1 -1               160.00
## 13 -1 -1  1  1  1 -1               113.75
## 14  1 -1  1  1 -1  1                92.75
## 15 -1  1  1  1 -1 -1               150.75
## 16  1  1  1  1  1  1               115.00
## class=design, type= FrF2.generators
summary(des.semiconductor) 
## Call:
## FrF2(16, generators = c("ABC", "ACD"), randomize = FALSE)
## 
## Experimental design of type  FrF2.generators 
## 16  runs
## 
## Factor settings (scale ends):
##    A  B  C  D  E  F
## 1 -1 -1 -1 -1 -1 -1
## 2  1  1  1  1  1  1
## 
## Responses:
## [1] response.Observation
## 
## Design generating information:
## $legend
## [1] A=A B=B C=C D=D E=E F=F
## 
## $generators
## [1] E=ABC F=ACD
## 
## 
## Alias structure:
## $fi2
## [1] AB=CE    AC=BE=DF AD=CF    AE=BC    AF=CD    BD=EF    BF=DE   
## 
## 
## The design itself:
##     A  B  C  D  E  F response.Observation
## 1  -1 -1 -1 -1 -1 -1               157.25
## 2   1 -1 -1 -1  1  1                48.00
## 3  -1  1 -1 -1  1 -1                44.00
## 4   1  1 -1 -1 -1  1                55.75
## 5  -1 -1  1 -1  1  1                55.75
## 6   1 -1  1 -1 -1 -1               230.00
## 7  -1  1  1 -1 -1  1                97.25
## 8   1  1  1 -1  1 -1               225.00
## 9  -1 -1 -1  1 -1  1                50.25
## 10  1 -1 -1  1  1 -1                85.25
## 11 -1  1 -1  1  1  1                31.50
## 12  1  1 -1  1 -1 -1               160.00
## 13 -1 -1  1  1  1 -1               113.75
## 14  1 -1  1  1 -1  1                92.75
## 15 -1  1  1  1 -1 -1               150.75
## 16  1  1  1  1  1  1               115.00
## class=design, type= FrF2.generators
#Generate Half Normal Plot 
DanielPlot(des.semiconductor,half=TRUE) 

#Generate Main Effects plot 
#Recall that Main Effects are NOT Aliased w/ 2Fact Interaction in Res IV 
MEPlot(des.semiconductor,show.alias=TRUE)

Note that F is not aliased with other factors or two factor interactions. So, F it is. So, fractional factorials always result in some aliasing but they save a lot of time if you have a reasonable understanding of the measurements.