1 Problem 1: Silver Powder Production Process

1.1 A. Full 2^3 factorial model

There are three factors:

  • A: Ammonium concentration
  • B: Stir rate
  • C: Temperature

The full factorial model, including all main effects and interactions, is:

\[ \begin{aligned} Y_{ijkl} =\ &\mu + A_i + B_j + C_k \\ &+ (AB)_{ij} + (AC)_{ik} + (BC)_{jk}\\ &+ (ABC)_{ijk} + \epsilon_{ijkl} \end{aligned} \]

where \(Y\) is powder density, \(\mu\) is the overall mean, the factor and interaction terms represent their effects, and \(\epsilon\) is random error.

1.2 B. Identify significant factors at alpha = 0.05

1.2.1 Import the data

data_url <- "https://raw.githubusercontent.com/tmatis12/datafiles/main/PowderProduction.csv"

powder <- read.csv(data_url, check.names = FALSE)

# Keep the four columns required for this analysis
powder <- powder[, 1:4]

# Assign consistent column names
names(powder) <- c("Ammonium", "StirRate", "Temperature", "Density")

# Convert the three experimental factors into categorical variables
powder$A <- factor(powder$Ammonium,
                   levels = c(2, 30),
                   labels = c("Low", "High"))

powder$B <- factor(powder$StirRate,
                   levels = c(100, 150),
                   labels = c("Low", "High"))

powder$C <- factor(powder$Temperature,
                   levels = c(8, 40),
                   labels = c("Low", "High"))

# Display the data
knitr::kable(powder, caption = "Silver Powder Production Data")
Silver Powder Production Data
Ammonium StirRate Temperature Density A B C
2 100 8 14.68 Low Low Low
2 100 8 15.18 Low Low Low
30 100 8 15.12 High Low Low
30 100 8 17.48 High Low Low
2 150 8 7.54 Low High Low
2 150 8 6.66 Low High Low
30 150 8 12.46 High High Low
30 150 8 12.62 High High Low
2 100 40 10.95 Low Low High
2 100 40 17.68 Low Low High
30 100 40 12.65 High Low High
30 100 40 15.96 High Low High
2 150 40 8.03 Low High High
2 150 40 8.84 Low High High
30 150 40 14.96 High High High
30 150 40 14.96 High High High

1.2.2 Fit the full factorial model

full_model <- lm(Density ~ A * B * C, data = powder)

full_anova <- anova(full_model)

knitr::kable(
  full_anova,
  digits = 5,
  caption = "ANOVA Table for the Full 2^3 Factorial Model"
)
ANOVA Table for the Full 2^3 Factorial Model
Df Sum Sq Mean Sq F value Pr(>F)
A 1 44.38891 44.38891 11.18026 0.01018
B 1 70.68606 70.68606 17.80373 0.00292
C 1 0.32776 0.32776 0.08255 0.78117
A:B 1 28.11651 28.11651 7.08172 0.02875
A:C 1 0.02176 0.02176 0.00548 0.94281
B:C 1 10.12831 10.12831 2.55102 0.14889
A:B:C 1 1.51906 1.51906 0.38261 0.55341
Residuals 8 31.76235 3.97029 NA NA

1.2.3 Extract p-values safely

# This function extracts effect names and p-values directly
# from an ANOVA table. It excludes the residual row.

extract_pvalues <- function(anova_table) {

  p_column <- grep("^Pr\\(", names(anova_table), value = TRUE)

  if (length(p_column) == 0) {
    stop("The ANOVA table does not contain a p-value column.")
  }

  effect_names <- rownames(anova_table)
  p_values <- anova_table[[p_column[1]]]

  keep <- !is.na(p_values) & effect_names != "Residuals"

  result <- data.frame(
    Effect = effect_names[keep],
    P_Value = as.numeric(p_values[keep]),
    row.names = NULL
  )

  return(result)
}

full_pvalues <- extract_pvalues(full_anova)

knitr::kable(
  full_pvalues,
  digits = 6,
  caption = "P-values for All Main Effects and Interactions"
)
P-values for All Main Effects and Interactions
Effect P_Value
A 0.010175
B 0.002918
C 0.781170
A:B 0.028754
A:C 0.942808
B:C 0.148890
A:B:C 0.553412

1.2.4 Identify significant effects

alpha <- 0.05

significant_effects <- full_pvalues[
  full_pvalues$P_Value < alpha,
]

knitr::kable(
  significant_effects,
  digits = 6,
  caption = "Significant Effects at Alpha = 0.05"
)
Significant Effects at Alpha = 0.05
Effect P_Value
1 A 0.010175
2 B 0.002918
4 A:B 0.028754

At the 0.05 significance level, the full model identifies the following significant effects:

  • Ammonium (A)
  • Stir Rate (B)
  • Ammonium × Stir Rate (AB)

Temperature (C), the AC interaction, the BC interaction, and the ABC interaction are not statistically significant.

1.2.5 Interaction plots

# Interaction between Ammonium and Stir Rate
interaction.plot(
  x.factor = powder$A,
  trace.factor = powder$B,
  response = powder$Density,
  fun = mean,
  type = "b",
  pch = c(1, 19),
  col = c("blue", "red"),
  xlab = "Ammonium",
  ylab = "Mean Powder Density",
  trace.label = "Stir Rate",
  main = "Interaction Plot: Ammonium and Stir Rate"
)

# Interaction between Ammonium and Temperature
interaction.plot(
  x.factor = powder$A,
  trace.factor = powder$C,
  response = powder$Density,
  fun = mean,
  type = "b",
  pch = c(1, 19),
  col = c("blue", "red"),
  xlab = "Ammonium",
  ylab = "Mean Powder Density",
  trace.label = "Temperature",
  main = "Interaction Plot: Ammonium and Temperature"
)

# Interaction between Stir Rate and Temperature
interaction.plot(
  x.factor = powder$B,
  trace.factor = powder$C,
  response = powder$Density,
  fun = mean,
  type = "b",
  pch = c(1, 19),
  col = c("blue", "red"),
  xlab = "Stir Rate",
  ylab = "Mean Powder Density",
  trace.label = "Temperature",
  main = "Interaction Plot: Stir Rate and Temperature"
)

The Ammonium × Stir Rate interaction is statistically significant. The interaction plot should therefore be considered when interpreting the effects of these two factors together.

The AC and BC interactions are not statistically significant based on their p-values.

1.2.6 Reduced factorial model

Since Temperature and all interactions involving Temperature are not statistically significant, the reduced model retains Ammonium, Stir Rate, and their interaction.

reduced_model <- lm(Density ~ A * B, data = powder)

reduced_anova <- anova(reduced_model)

knitr::kable(
  reduced_anova,
  digits = 5,
  caption = "ANOVA Table for the Reduced Model"
)
ANOVA Table for the Reduced Model
Df Sum Sq Mean Sq F value Pr(>F)
A 1 44.38891 44.38891 12.17268 0.00447
B 1 70.68606 70.68606 19.38409 0.00086
A:B 1 28.11651 28.11651 7.71033 0.01675
Residuals 12 43.75923 3.64660 NA NA

1.2.7 Reduced model p-values

reduced_pvalues <- extract_pvalues(reduced_anova)

knitr::kable(
  reduced_pvalues,
  digits = 6,
  caption = "P-values for the Reduced Model"
)
P-values for the Reduced Model
Effect P_Value
A 0.004472
B 0.000861
A:B 0.016751

The reduced model retains all three terms because they are statistically significant:

  • Ammonium (A)
  • Stir Rate (B)
  • Ammonium × Stir Rate (AB)

The interaction is retained, so both associated main effects are also retained.

1.2.8 Model diagnostics

par(mfrow = c(2, 2))
plot(reduced_model)

par(mfrow = c(1, 1))

These diagnostic plots are used to examine the residual assumptions, including normality, constant variance, and unusual observations.

1.2.9 Conclusion for Problem 1

The full \(2^3\) factorial analysis shows that Ammonium, Stir Rate, and their interaction are significant at the 0.05 level. Temperature and interactions involving Temperature are not significant.

The reduced model therefore includes Ammonium, Stir Rate, and the Ammonium × Stir Rate interaction. The interaction indicates that the effect of Ammonium on powder density depends on the Stir Rate.

2 Problem 2: Greenhouse Tomato Yield Experiment

2.1 Experimental factors

A horticultural researcher wants to investigate three factors that may affect tomato yield.

Factor Level 1 Level 2
A: Fertilizer Type Organic compost Chemical fertilizer
B: Irrigation Frequency Once per day Twice per day
C: Temperature Setting 22°C 28°C

This is a \(2^3\) factorial experiment with eight treatment combinations.

The experiment uses three replications in a randomized complete block design (RCBD), with greenhouse bench differences controlled through blocking.

There are eight treatment combinations and three blocks, resulting in 24 experimental units.

2.2 Generate the experimental layout using agricolae

# Install agricolae if it is not already installed
if (!requireNamespace("agricolae", quietly = TRUE)) {
  install.packages("agricolae")
}

library(agricolae)
# Three factors, each with two levels
treatments <- c(2, 2, 2)

# Three replications / blocks
replications <- 3

# Set a reproducible random seed
set.seed(12345)

# Generate the randomized complete block design
design_result <- agricolae::design.ab(
  trt = treatments,
  r = replications,
  serie = 2,
  design = "rcbd",
  seed = 12345,
  kinds = "Super-Duper",
  randomization = TRUE
)

# Extract the experimental field book
field_book <- design_result$book

# Display the randomized experimental layout
knitr::kable(
  field_book,
  caption = "Randomized Complete Block 2^3 Factorial Experimental Layout"
)
Randomized Complete Block 2^3 Factorial Experimental Layout
plots block A B C
101 1 2 2 1
102 1 1 2 2
103 1 2 1 2
104 1 1 1 2
105 1 2 1 1
106 1 1 2 1
107 1 2 2 2
108 1 1 1 1
109 2 1 1 2
110 2 2 2 2
111 2 1 2 1
112 2 1 2 2
113 2 1 1 1
114 2 2 1 2
115 2 2 2 1
116 2 2 1 1
117 3 2 1 2
118 3 2 2 2
119 3 2 2 1
120 3 1 2 1
121 3 2 1 1
122 3 1 2 2
123 3 1 1 1
124 3 1 1 2

2.3 Display design parameters

knitr::kable(
  design_result$parameters,
  caption = "Experimental Design Parameters"
)
Experimental Design Parameters
x
factorial
x
1 1 1
1 1 2
1 2 1
1 2 2
2 1 1
2 1 2
2 2 1
2 2 2
x
3
x
2
x
12345
x
Super-Duper
x
TRUE
x
rcbd

2.4 Treatment combinations

The eight treatment combinations are:

Treatment Fertilizer (A) Irrigation (B) Temperature (C)
1 Organic compost Once per day 22°C
2 Chemical fertilizer Once per day 22°C
3 Organic compost Twice per day 22°C
4 Chemical fertilizer Twice per day 22°C
5 Organic compost Once per day 28°C
6 Chemical fertilizer Once per day 28°C
7 Organic compost Twice per day 28°C
8 Chemical fertilizer Twice per day 28°C

2.5 Verify the experimental layout

cat("Number of treatment combinations:",
    length(unique(field_book$plots)), "\n")
## Number of treatment combinations: 24
cat("Number of blocks:",
    length(unique(field_book$block)), "\n")
## Number of blocks: 3
cat("Total number of experimental units:",
    nrow(field_book), "\n")
## Total number of experimental units: 24

2.6 Conclusion for Problem 2

The design.ab() function from the agricolae package was used to generate a randomized complete block design for the \(2^3\) factorial experiment.

The experiment contains eight treatment combinations, three replications, and 24 total experimental units. Blocking helps control variation associated with differences between greenhouse benches, while randomization helps reduce potential bias in treatment assignment.