An engineer is interested in the effects of cutting speed A, tool geometry B, and cutting angle C on the life (in hours) of a machine tool. Two levels of each factor are chosen, and one replicate of a 2^3 factorial design is run:
Interaction ABC, standard practice is to confound the highest-order interaction so that main effects and low-order interactions remain unconfounded.
Using the contrast ABC, the blocks are determined by the sign of the ABC interaction column, where low level is -1 and high level is +1.
To run a 2^3 design in 4 (2^2) blocks, the generalized interaction will be confounded as well, in two two-way interactions, which automatically confounds the third, leaving main effects unconfounded. Such as, AB and BC, which results in AC also being cofounded (AB x BC = AC).
By evaluating the signs of AB and BC across the standard layout, partitioning the 8 treatment combinations into 4 blocks:
# data frame
df <- data.frame(
Treatment = c("(1)", "a", "b", "ab", "c", "ac", "bc", "abc"),
A = c(-1, 1, -1, 1, -1, 1, -1, 1),
B = c(-1, -1, 1, 1, -1, -1, 1, 1),
C = c(-1, -1, -1, -1, 1, 1, 1, 1),
ToolLife = c(22, 32, 35, 55, 44, 40, 60, 39)
)
df$Block <- as.factor(ifelse(df$A * df$B * df$C == 1, 2, 1))
# Convert factors
df$A <- as.factor(df$A)
df$B <- as.factor(df$B)
df$C <- as.factor(df$C)
knitr::kable(df, caption = "Experimental Data for Tool Life")
| Treatment | A | B | C | ToolLife | Block |
|---|---|---|---|---|---|
| (1) | -1 | -1 | -1 | 22 | 1 |
| a | 1 | -1 | -1 | 32 | 2 |
| b | -1 | 1 | -1 | 35 | 2 |
| ab | 1 | 1 | -1 | 55 | 1 |
| c | -1 | -1 | 1 | 44 | 2 |
| ac | 1 | -1 | 1 | 40 | 1 |
| bc | -1 | 1 | 1 | 60 | 1 |
| abc | 1 | 1 | 1 | 39 | 2 |
# Fit full model including block
fit <- aov(ToolLife ~ Block + A * B * C, data = df)
# Extract effects for half-normal plot
effects_vector <- 2 * coef(fit)[-1]
# Create coded design matrix data frame for DanielPlot
library("FrF2")
design_matrix <- data.frame(
A = c(-1, 1, -1, 1, -1, 1, -1, 1),
B = c(-1, -1, 1, 1, -1, -1, 1, 1),
C = c(-1, -1, -1, -1, 1, 1, 1, 1)
)
response <- df$ToolLife
DanielPlot(aov(response ~ A*B*C, data = design_matrix), main = "Half-Normal Probability Plot of Effects")
summary(fit)
## Df Sum Sq Mean Sq
## Block 1 91.1 91.1
## A 1 3.1 3.1
## B 1 325.1 325.1
## C 1 190.1 190.1
## A:B 1 6.1 6.1
## A:C 1 378.1 378.1
## B:C 1 55.1 55.1
Based on the half-normal probability plot and the ANOVA table results, interaction A:C (interaction between cutting speed and cutting angle), appears to be the most statistically significant effect, as it has the largest Sum of Squares, 378.1, and deviate farthest from the linear trend on the half-normal plot. Main Effect B also shows substantial significance with Sum of Squares of 325.1, and main effect C with Sum of Squares of 190.1. They exhibit the largest Sum of Squares indicating that they exert a dominant influence on the tool life.
The Block in ANOVA table test the effect of the blocked interaction (ABC), which accounts for a Sum of Squares of 91.1. Compared to the other main effects and interactions, such as A:C (378.1), the block sum of squares is small. While blocking captured some experimental variation, its magnitude is comparable to or smaller than the primary active effects. Therefore, the blocking effect does not overpower the primary experimental factors, though the ABC interaction contributes notably to the total variation.
knitr::opts_chunk$set(echo = TRUE, warning=FALSE, message = FALSE)
# data frame
df <- data.frame(
Treatment = c("(1)", "a", "b", "ab", "c", "ac", "bc", "abc"),
A = c(-1, 1, -1, 1, -1, 1, -1, 1),
B = c(-1, -1, 1, 1, -1, -1, 1, 1),
C = c(-1, -1, -1, -1, 1, 1, 1, 1),
ToolLife = c(22, 32, 35, 55, 44, 40, 60, 39)
)
df$Block <- as.factor(ifelse(df$A * df$B * df$C == 1, 2, 1))
# Convert factors
df$A <- as.factor(df$A)
df$B <- as.factor(df$B)
df$C <- as.factor(df$C)
knitr::kable(df, caption = "Experimental Data for Tool Life")
# Fit full model including block
fit <- aov(ToolLife ~ Block + A * B * C, data = df)
# Extract effects for half-normal plot
effects_vector <- 2 * coef(fit)[-1]
# Create coded design matrix data frame for DanielPlot
library("FrF2")
design_matrix <- data.frame(
A = c(-1, 1, -1, 1, -1, 1, -1, 1),
B = c(-1, -1, 1, 1, -1, -1, 1, 1),
C = c(-1, -1, -1, -1, 1, 1, 1, 1)
)
response <- df$ToolLife
DanielPlot(aov(response ~ A*B*C, data = design_matrix), main = "Half-Normal Probability Plot of Effects")
summary(fit)