Introduction

This analysis examines CO2 change using a two-way factorial ANOVA to test:

  1. Main effect of Light (Light vs Dark) - does CO2 differ by light condition?
  2. Main effect of Nativity (Native vs Non-Native) - do CO2 levels differ?
  3. Interaction (Light × Nativity) - does the light effect depend on nativity?

Experimental Design

  • 2 factors: Nativity (N, NN) × Light (Light, Dark)
  • 4 treatment combinations
  • Response variable: CO2_Change

Step 1: Load Required Packages

library(readxl)       # Read Excel files
library(ggplot2)      # Create plots
library(dplyr)        # Data wrangling
library(car)          # Type II/III ANOVA and Levene's test
library(emmeans)      # Estimated marginal means
library(multcomp)     # Multiple comparisons
library(tidyr)        # Data manipulation

Step 2: Import and Clean Data

#setwd
getwd()
## [1] "/Users/ivyvelasco/Downloads"
#setwd
setwd("/Users/ivyvelasco/Desktop/Greenhouse 2026")
getwd()
## [1] "/Users/ivyvelasco/Desktop/Greenhouse 2026"
list.files()
##  [1] "arthropod_barplot.png"                           
##  [2] "arthropod_boxplot.png"                           
##  [3] "Arthropods_R.xlsx"                               
##  [4] "Book5.xlsx"                                      
##  [5] "CarbonFluxLMM.R"                                 
##  [6] "CFlux_Anova#1.Rmd"                               
##  [7] "CFlux_R.xlsx"                                    
##  [8] "emmeans_Nativity_by_Light_Edited.xlsx"           
##  [9] "emmeans_Nativity_by_Light.xlsx"                  
## [10] "emmeans_Nativity_Light.xlsx"                     
## [11] "emmeans&contrasts_Light_by_Nativity_Edited.xlsx" 
## [12] "emmeans&contrasts_PairwiseComparison_Edited.xlsx"
## [13] "height_change_barplot.png"                       
## [14] "height_change_boxplot.png"                       
## [15] "height_change_by_species.png"                    
## [16] "HeightDataCleaning.xlsx"                         
## [17] "Nativity_"                                       
## [18] "Nativity_WaterContent 18-19"                     
## [19] "Plant_Height.html"                               
## [20] "Plant_Height.Rmd"                                
## [21] "Plant_Height.xlsx"                               
## [22] "Rplot.pdf"
# Read the Excel file
#DOESN'T WORK: data <- read_excel("CFlux_R.xlsx")
# Use the full path instead
data <- read_excel("/Users/ivyvelasco/Desktop/Greenhouse 2026/CFlux_R.xlsx")

# Display the raw data
print(data)
## # A tibble: 24 × 4
##    Nativity Plot  Light CO2_Change
##    <chr>    <chr> <chr>      <dbl>
##  1 NN       1L    Light         19
##  2 NN       1D    Dark        -109
##  3 NN       2L    Light        985
##  4 NN       2D    Dark        -137
##  5 N        3D    Dark         -76
##  6 N        4D    Dark        -138
##  7 N        5D    Dark        -129
##  8 N        6D    Dark        -174
##  9 N        9D    Dark        -106
## 10 N        10D   Dark         -66
## # ℹ 14 more rows
cat("Total rows:", nrow(data), "\n")
## Total rows: 24
# Clean and prepare variables
data$Nativity <- trimws(data$Nativity)
data$Light <- trimws(data$Light)

# Convert to factors with meaningful levels
data$Nativity <- factor(data$Nativity, levels = c("NN", "N"))
data$Light <- factor(data$Light, levels = c("Dark", "Light"))

# Rename for clarity
levels(data$Nativity) <- c("Non-Native", "Native")

# Check the cleaned data
str(data)
## tibble [24 × 4] (S3: tbl_df/tbl/data.frame)
##  $ Nativity  : Factor w/ 2 levels "Non-Native","Native": 1 1 1 1 2 2 2 2 2 2 ...
##  $ Plot      : chr [1:24] "1L" "1D" "2L" "2D" ...
##  $ Light     : Factor w/ 2 levels "Dark","Light": 2 1 2 1 1 1 1 1 1 1 ...
##  $ CO2_Change: num [1:24] 19 -109 985 -137 -76 -138 -129 -174 -106 -66 ...

Step 3: Experimental Design Check

# Check sample sizes per treatment combination
design_table <- table(data$Nativity, data$Light)
cat("Sample sizes (Nativity × Light):\n")
## Sample sizes (Nativity × Light):
print(design_table)
##             
##              Dark Light
##   Non-Native    6     3
##   Native        6     3
# Check if design is balanced
if(length(unique(as.vector(design_table))) == 1) {
  cat("\n✓ BALANCED DESIGN - all groups have equal sample sizes\n")
  cat("  Can use Type I, II, or III ANOVA (results will be identical)\n")
} else {
  cat("\n✗ UNBALANCED DESIGN - groups have different sample sizes\n")
  cat("  Must use Type II or Type III ANOVA\n")
  cat("  Type III recommended for testing main effects with interaction\n")
}
## 
## ✗ UNBALANCED DESIGN - groups have different sample sizes
##   Must use Type II or Type III ANOVA
##   Type III recommended for testing main effects with interaction
# Total sample size
cat("\nTotal observations:", nrow(data), "\n")
## 
## Total observations: 24
cat("Treatment combinations:", length(design_table), "\n")
## Treatment combinations: 4

Step 4: Descriptive Statistics

# Summary by both factors
summary_stats <- data %>%
  group_by(Nativity, Light) %>%
  summarise(
    n = n(),
    Mean = mean(CO2_Change, na.rm = TRUE),
    SD = sd(CO2_Change, na.rm = TRUE),
    SE = sd(CO2_Change, na.rm = TRUE) / sqrt(n()),
    Min = min(CO2_Change, na.rm = TRUE),
    Max = max(CO2_Change, na.rm = TRUE),
    .groups = 'drop'
  )

cat("CO2 Change by Treatment Combination:\n")
## CO2 Change by Treatment Combination:
print(summary_stats)
## # A tibble: 6 × 8
##   Nativity   Light     n  Mean     SD     SE   Min   Max
##   <fct>      <fct> <int> <dbl>  <dbl>  <dbl> <dbl> <dbl>
## 1 Non-Native Dark      6 -104.  46.6   19.0   -174   -47
## 2 Non-Native Light     3  343. 556.   321.      19   985
## 3 Native     Dark      6 -115.  40.5   16.5   -174   -66
## 4 Native     Light     3  114    9.85   5.69   106   125
## 5 Native     <NA>      1  NaN   NA     NA      Inf  -Inf
## 6 <NA>       <NA>      5  NaN   NA     NA      Inf  -Inf
# Marginal means
cat("\nMARGINAL MEANS:\n")
## 
## MARGINAL MEANS:
marginal_nativity <- data %>%
  group_by(Nativity) %>%
  summarise(
    n = n(),
    Mean_CO2 = mean(CO2_Change, na.rm = TRUE),
    SD = sd(CO2_Change, na.rm = TRUE),
    .groups = 'drop'
  )

cat("\nBy Nativity (averaged over Light conditions):\n")
## 
## By Nativity (averaged over Light conditions):
print(marginal_nativity)
## # A tibble: 3 × 4
##   Nativity       n Mean_CO2    SD
##   <fct>      <int>    <dbl> <dbl>
## 1 Non-Native     9     45    359.
## 2 Native        10    -38.6  119.
## 3 <NA>           5    NaN     NA
marginal_light <- data %>%
  group_by(Light) %>%
  summarise(
    n = n(),
    Mean_CO2 = mean(CO2_Change, na.rm = TRUE),
    SD = sd(CO2_Change, na.rm = TRUE),
    .groups = 'drop'
  )

cat("\nBy Light (averaged over Nativity):\n")
## 
## By Light (averaged over Nativity):
print(marginal_light)
## # A tibble: 3 × 4
##   Light     n Mean_CO2    SD
##   <fct> <int>    <dbl> <dbl>
## 1 Dark     12    -109.  42.0
## 2 Light     6     228. 374. 
## 3 <NA>      6     NaN   NA

Step 5: Visualizations

Interaction Plot

Most important for factorial design! Parallel lines = no interaction; Crossing/diverging lines = interaction present.

p1 <- ggplot(summary_stats, aes(x = Light, y = Mean, 
                                 color = Nativity, group = Nativity)) +
  geom_point(size = 4) +
  geom_line(linewidth = 1.5) +
  geom_errorbar(aes(ymin = Mean - SE, ymax = Mean + SE), 
                width = 0.1, linewidth = 1) +
  scale_color_manual(values = c("Non-Native" = "#E74C3C", "Native" = "#27AE60")) +
  labs(
    title = "Interaction Plot: CO2 Change by Light and Nativity",
    subtitle = "Parallel lines = no interaction; Crossing/diverging lines = interaction present",
    x = "Light Condition",
    y = "Mean CO2 Change",
    color = "Plant Type"
  ) +
  theme_minimal(base_size = 14) +
  geom_hline(yintercept = 0, linetype = "dashed", color = "gray50")

Boxplot by Treatment Combination

p2 <- ggplot(data, aes(x = Light, y = CO2_Change, fill = Nativity)) +
  geom_boxplot(alpha = 0.7, outlier.shape = 16) +
  geom_point(position = position_jitterdodge(jitter.width = 0.2), 
             alpha = 0.5, size = 2) +
  scale_fill_manual(values = c("Non-Native" = "#E74C3C", "Native" = "#27AE60")) +
  labs(
    title = "CO2 Change by Light Condition and Nativity",
    x = "Light Condition",
    y = "CO2 Change",
    fill = "Plant Type"
  ) +
  theme_minimal(base_size = 14) +
  geom_hline(yintercept = 0, linetype = "dashed", color = "gray50")

Faceted by Nativity

p3 <- ggplot(data, aes(x = Light, y = CO2_Change, fill = Light)) +
  geom_boxplot(alpha = 0.7) +
  geom_jitter(width = 0.2, alpha = 0.5, size = 2) +
  facet_wrap(~ Nativity) +
  scale_fill_manual(values = c("Dark" = "#34495E", "Light" = "#F39C12")) +
  labs(
    title = "CO2 Change by Light Condition (Separated by Nativity)",
    x = "Light Condition",
    y = "CO2 Change",
    fill = "Light"
  ) +
  theme_minimal(base_size = 14) +
  geom_hline(yintercept = 0, linetype = "dashed", color = "gray50")

Step 6: Check ANOVA Assumptions

# First fit the model to get residuals
model_check <- aov(CO2_Change ~ Nativity * Light, data = data)
residuals_check <- residuals(model_check)

# 1. Normality Test
cat("1. NORMALITY TEST (Shapiro-Wilk):\n")
## 1. NORMALITY TEST (Shapiro-Wilk):
shapiro_test <- shapiro.test(residuals_check)
print(shapiro_test)
## 
##  Shapiro-Wilk normality test
## 
## data:  residuals_check
## W = 0.68893, p-value = 5.955e-05
if(shapiro_test$p.value > 0.05) {
  cat("→ Residuals are approximately normal (p > 0.05) ✓\n")
} else {
  cat("→ Residuals deviate from normality (p < 0.05)\n")
  cat("  Consider transformations (log, sqrt) if severe\n")
}
## → Residuals deviate from normality (p < 0.05)
##   Consider transformations (log, sqrt) if severe
# Q-Q plot doesn't work due to graphics issue
#qqnorm(residuals_check, main = "Q-Q Plot of Residuals")
#qqline(residuals_check, col = "red")

# 2. Homogeneity of Variances
cat("\n2. HOMOGENEITY OF VARIANCE TEST (Levene's Test):\n")
## 
## 2. HOMOGENEITY OF VARIANCE TEST (Levene's Test):
levene_test <- leveneTest(CO2_Change ~ Nativity * Light, data = data)
print(levene_test)
## Levene's Test for Homogeneity of Variance (center = median)
##       Df F value Pr(>F)
## group  3  1.6401 0.2252
##       14
if(levene_test$`Pr(>F)`[1] > 0.05) {
  cat("→ Variances are homogeneous across groups (p > 0.05) ✓\n")
} else {
  cat("→ Variances differ across groups (p < 0.05)\n")
  cat("  ANOVA is relatively robust to this with equal sample sizes\n")
}
## → Variances are homogeneous across groups (p > 0.05) ✓
# Residuals vs Fitted doesn't plot due to graphics issue
#plot(fitted(model_check), residuals_check,
     #xlab = "Fitted Values", ylab = "Residuals",
     #main = "Residuals vs Fitted Values\n(Should show random scatter)")
#abline(h = 0, col = "red", lty = 2)

Step 7: Two-Way ANOVA

# Fit the model with interaction
model <- aov(CO2_Change ~ Nativity * Light, data = data)

# Type I ANOVA
cat("ANOVA Table (Type I):\n")
## ANOVA Table (Type I):
anova_type1 <- summary(model)
print(anova_type1)
##                Df Sum Sq Mean Sq F value  Pr(>F)   
## Nativity        1  31417   31417   0.689 0.42036   
## Light           1 456075  456075  10.005 0.00691 **
## Nativity:Light  1  47379   47379   1.039 0.32526   
## Residuals      14 638160   45583                   
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 6 observations deleted due to missingness
# Type III ANOVA (recommended for unbalanced designs)
cat("\n\nANOVA Table (Type III) - Recommended for unbalanced designs:\n")
## 
## 
## ANOVA Table (Type III) - Recommended for unbalanced designs:
cat("(Tests each effect while controlling for all others)\n\n")
## (Tests each effect while controlling for all others)
model_lm <- lm(CO2_Change ~ Nativity * Light, data = data)
anova_type3 <- Anova(model_lm, type = "III")
print(anova_type3)
## Anova Table (Type III tests)
## 
## Response: CO2_Change
##                Sum Sq Df F value  Pr(>F)  
## (Intercept)     64688  1  1.4191 0.25335  
## Nativity          363  1  0.0080 0.93016  
## Light          398724  1  8.7472 0.01039 *
## Nativity:Light  47379  1  1.0394 0.32526  
## Residuals      638160 14                  
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Step 8: Interpret ANOVA Results

# Extract p-values from Type III ANOVA
p_nativity <- anova_type3$`Pr(>F)`[2]
p_light <- anova_type3$`Pr(>F)`[3]
p_interaction <- anova_type3$`Pr(>F)`[4]

cat("P-VALUES:\n")
## P-VALUES:
cat("Main effect of Nativity:", round(p_nativity, 4), "\n")
## Main effect of Nativity: 0.9302
cat("Main effect of Light:", round(p_light, 4), "\n")
## Main effect of Light: 0.0104
cat("Interaction (Nativity × Light):", round(p_interaction, 4), "\n")
## Interaction (Nativity × Light): 0.3253
cat("\nINTERPRETATION:\n")
## 
## INTERPRETATION:
# Interaction
cat("\n1. INTERACTION (Nativity × Light):\n")
## 
## 1. INTERACTION (Nativity × Light):
if(p_interaction < 0.05) {
  cat("   ✓ SIGNIFICANT INTERACTION (p < 0.05)\n")
  cat("   → The effect of Light DEPENDS ON Nativity\n")
  cat("   → The effect of Nativity DEPENDS ON Light condition\n")
  cat("   → Cannot interpret main effects in isolation!\n")
  cat("   → Must examine simple effects\n")
} else {
  cat("   ✗ NO SIGNIFICANT INTERACTION (p ≥ 0.05)\n")
  cat("   → The effect of Light is similar for Native and Non-Native\n")
  cat("   → The effect of Nativity is similar in Light and Dark\n")
  cat("   → Main effects can be interpreted independently\n")
}
##    ✗ NO SIGNIFICANT INTERACTION (p ≥ 0.05)
##    → The effect of Light is similar for Native and Non-Native
##    → The effect of Nativity is similar in Light and Dark
##    → Main effects can be interpreted independently
# Light main effect
cat("\n2. MAIN EFFECT OF LIGHT:\n")
## 
## 2. MAIN EFFECT OF LIGHT:
if(p_light < 0.05) {
  cat("   ✓ SIGNIFICANT MAIN EFFECT (p < 0.05)\n")
  cat("   → CO2 change differs significantly between Light and Dark conditions\n")
  
  light_diff <- marginal_light$Mean_CO2[marginal_light$Light == "Light"] - 
                marginal_light$Mean_CO2[marginal_light$Light == "Dark"]
  cat("   → Light condition mean:", 
      round(marginal_light$Mean_CO2[marginal_light$Light == "Light"], 2), "\n")
  cat("   → Dark condition mean:", 
      round(marginal_light$Mean_CO2[marginal_light$Light == "Dark"], 2), "\n")
  cat("   → Difference:", round(light_diff, 2), "\n")
} else {
  cat("   ✗ NO SIGNIFICANT MAIN EFFECT (p ≥ 0.05)\n")
}
##    ✓ SIGNIFICANT MAIN EFFECT (p < 0.05)
##    → CO2 change differs significantly between Light and Dark conditions
##    → Light condition mean: 228.33 NA 
##    → Dark condition mean: -109.33 NA 
##    → Difference: 337.67 NA
# Nativity main effect
cat("\n3. MAIN EFFECT OF NATIVITY:\n")
## 
## 3. MAIN EFFECT OF NATIVITY:
if(p_nativity < 0.05) {
  cat("   ✓ SIGNIFICANT MAIN EFFECT (p < 0.05)\n")
  cat("   → CO2 change differs significantly between Native and Non-Native plants\n")
  
  nativity_diff <- marginal_nativity$Mean_CO2[marginal_nativity$Nativity == "Native"] - 
                   marginal_nativity$Mean_CO2[marginal_nativity$Nativity == "Non-Native"]
  cat("   → Native mean:", 
      round(marginal_nativity$Mean_CO2[marginal_nativity$Nativity == "Native"], 2), "\n")
  cat("   → Non-Native mean:", 
      round(marginal_nativity$Mean_CO2[marginal_nativity$Nativity == "Non-Native"], 2), "\n")
  cat("   → Difference:", round(nativity_diff, 2), "\n")
} else {
  cat("   ✗ NO SIGNIFICANT MAIN EFFECT (p ≥ 0.05)\n")
}
##    ✗ NO SIGNIFICANT MAIN EFFECT (p ≥ 0.05)

Step 9: Estimated Marginal Means

# All treatment combinations
emm <- emmeans(model, ~ Nativity * Light)
cat("Estimated Marginal Means (all combinations):\n")
## Estimated Marginal Means (all combinations):
print(summary(emm))
##  Nativity   Light emmean    SE df lower.CL upper.CL
##  Non-Native Dark    -104  87.2 14   -290.8     83.1
##  Native     Dark    -115  87.2 14   -301.8     72.1
##  Non-Native Light    343 123.0 14     78.3    607.0
##  Native     Light    114 123.0 14   -150.4    378.4
## 
## Confidence level used: 0.95
# Marginal means for each factor
emm_nativity <- emmeans(model, ~ Nativity)
emm_light <- emmeans(model, ~ Light)

cat("\nMarginal Means by Nativity:\n")
## 
## Marginal Means by Nativity:
print(summary(emm_nativity))
##  Nativity    emmean   SE df lower.CL upper.CL
##  Non-Native 119.417 75.5 14    -42.5      281
##  Native      -0.417 75.5 14   -162.3      161
## 
## Results are averaged over the levels of: Light 
## Confidence level used: 0.95
cat("\nMarginal Means by Light:\n")
## 
## Marginal Means by Light:
print(summary(emm_light))
##  Light emmean   SE df lower.CL upper.CL
##  Dark    -109 61.6 14   -241.5     22.9
##  Light    228 87.2 14     41.4    415.3
## 
## Results are averaged over the levels of: Nativity 
## Confidence level used: 0.95

Step 10: Post-Hoc Pairwise Comparisons

All Pairwise Comparisons

cat("All Pairwise Comparisons (Tukey HSD):\n")
## All Pairwise Comparisons (Tukey HSD):
all_pairs <- pairs(emm, adjust = "tukey")
print(summary(all_pairs))
##  contrast                               estimate  SE df t.ratio p.value
##  (Non-Native Dark) - Native Dark              11 123 14   0.089  0.9997
##  (Non-Native Dark) - (Non-Native Light)     -446 151 14  -2.958  0.0455
##  (Non-Native Dark) - Native Light           -218 151 14  -1.443  0.4951
##  Native Dark - (Non-Native Light)           -458 151 14  -3.030  0.0398
##  Native Dark - Native Light                 -229 151 14  -1.516  0.4546
##  (Non-Native Light) - Native Light           229 174 14   1.312  0.5709
## 
## P value adjustment: tukey method for comparing a family of 4 estimates

Simple Effects: Light within Each Nativity

cat("Effect of Light within each Nativity level:\n")
## Effect of Light within each Nativity level:
emm_simple_light <- emmeans(model, ~ Light | Nativity)
simple_light_pairs <- pairs(emm_simple_light)
print(summary(simple_light_pairs))
## Nativity = Non-Native:
##  contrast     estimate  SE df t.ratio p.value
##  Dark - Light     -446 151 14  -2.958  0.0104
## 
## Nativity = Native:
##  contrast     estimate  SE df t.ratio p.value
##  Dark - Light     -229 151 14  -1.516  0.1518
cat("\nInterpretation:\n")
## 
## Interpretation:
cat("- For Native plants: Does Light significantly differ from Dark?\n")
## - For Native plants: Does Light significantly differ from Dark?
cat("- For Non-Native plants: Does Light significantly differ from Dark?\n")
## - For Non-Native plants: Does Light significantly differ from Dark?

Simple Effects: Nativity within Each Light Condition

cat("Effect of Nativity within each Light condition:\n")
## Effect of Nativity within each Light condition:
emm_simple_nativity <- emmeans(model, ~ Nativity | Light)
simple_nativity_pairs <- pairs(emm_simple_nativity)
print(summary(simple_nativity_pairs))
## Light = Dark:
##  contrast              estimate  SE df t.ratio p.value
##  (Non-Native) - Native       11 123 14   0.089  0.9302
## 
## Light = Light:
##  contrast              estimate  SE df t.ratio p.value
##  (Non-Native) - Native      229 174 14   1.312  0.2107
cat("\nInterpretation:\n")
## 
## Interpretation:
cat("- In Dark conditions: Do Native plants differ from Non-Native?\n")
## - In Dark conditions: Do Native plants differ from Non-Native?
cat("- In Light conditions: Do Native plants differ from Non-Native?\n")
## - In Light conditions: Do Native plants differ from Non-Native?

Step 11: Effect Sizes

# Eta-squared (proportion of variance explained)
ss_total <- sum((data$CO2_Change - mean(data$CO2_Change))^2)
ss_nativity <- anova_type3$`Sum Sq`[2]
ss_light <- anova_type3$`Sum Sq`[3]
ss_interaction <- anova_type3$`Sum Sq`[4]

eta_sq_nativity <- ss_nativity / ss_total
eta_sq_light <- ss_light / ss_total
eta_sq_interaction <- ss_interaction / ss_total

cat("Eta-squared (η²) - Proportion of variance explained:\n")
## Eta-squared (η²) - Proportion of variance explained:
cat("Nativity:", round(eta_sq_nativity, 3), "\n")
## Nativity: NA
cat("Light:", round(eta_sq_light, 3), "\n")
## Light: NA
cat("Interaction:", round(eta_sq_interaction, 3), "\n")
## Interaction: NA
cat("\nInterpretation of η²:\n")
## 
## Interpretation of η²:
cat("  Small: 0.01\n")
##   Small: 0.01
cat("  Medium: 0.06\n")
##   Medium: 0.06
cat("  Large: 0.14\n")
##   Large: 0.14
# Cohen's f
f_nativity <- sqrt(eta_sq_nativity / (1 - eta_sq_nativity))
f_light <- sqrt(eta_sq_light / (1 - eta_sq_light))
f_interaction <- sqrt(eta_sq_interaction / (1 - eta_sq_interaction))

cat("\nCohen's f:\n")
## 
## Cohen's f:
cat("Nativity:", round(f_nativity, 3), "\n")
## Nativity: NA
cat("Light:", round(f_light, 3), "\n")
## Light: NA
cat("Interaction:", round(f_interaction, 3), "\n")
## Interaction: NA
cat("\nInterpretation of Cohen's f:\n")
## 
## Interpretation of Cohen's f:
cat("  Small: 0.10\n")
##   Small: 0.10
cat("  Medium: 0.25\n")
##   Medium: 0.25
cat("  Large: 0.40\n")
##   Large: 0.40

Step 12: ANOVA Summary Table

summary_table <- data.frame(
  Source = c("Nativity", "Light", "Nativity × Light", "Residuals"),
  df = c(anova_type3$Df[2:5]),
  SS = round(anova_type3$`Sum Sq`[2:5], 2),
  MS = round(anova_type3$`Sum Sq`[2:5] / anova_type3$Df[2:5], 2),
  F_value = round(anova_type3$`F value`[2:5], 2),
  p_value = round(anova_type3$`Pr(>F)`[2:5], 4),
  Eta_squared = round(c(eta_sq_nativity, eta_sq_light, eta_sq_interaction, NA), 3)
)

print(summary_table)
##             Source df        SS        MS F_value p_value Eta_squared
## 1         Nativity  1    363.00    363.00    0.01  0.9302          NA
## 2            Light  1 398724.50 398724.50    8.75  0.0104          NA
## 3 Nativity × Light  1  47378.78  47378.78    1.04  0.3253          NA
## 4        Residuals 14 638160.33  45582.88      NA      NA          NA

Final Summary

Research Questions Answered

  1. Does CO2 differ based on Light condition?
    → Main effect of Light: p = 0.0104

  2. Does CO2 differ between Native and Non-Native plants?
    → Main effect of Nativity: p = 0.9302

  3. Does the effect of Light depend on Nativity (comparing slopes)?
    → Interaction: p = 0.3253

Key Results

if(p_interaction < 0.05) {
  cat("### ✓ SIGNIFICANT INTERACTION DETECTED\n\n")
  cat("The relationship between Light and CO2 change differs for Native vs Non-Native plants.\n\n")
  cat("**This means:**\n\n")
  cat("- The effect of Light is different in Native vs Non-Native plants\n")
  cat("- You cannot interpret main effects independently\n")
  cat("- Must examine simple effects to understand the pattern\n\n")
  cat("Look at the interaction plot to see the pattern:\n")
  cat("- Crossing lines indicate the factors work differently together\n")
  cat("- One group may benefit more from light than the other\n")
} else {
  cat("### ✗ NO SIGNIFICANT INTERACTION\n\n")
  cat("The effect of Light is similar for both Native and Non-Native plants.\n")
  cat("The effect of Nativity is similar in both Light and Dark conditions.\n")
  cat("Main effects can be interpreted independently.\n")
}

✗ NO SIGNIFICANT INTERACTION

The effect of Light is similar for both Native and Non-Native plants. The effect of Nativity is similar in both Light and Dark conditions. Main effects can be interpreted independently.

if(p_light < 0.05) {
  cat("\n### ✓ SIGNIFICANT MAIN EFFECT OF LIGHT\n\n")
  cat("Light condition significantly affects CO2 change (p < 0.05).\n\n")
  cat("- Light mean:", round(marginal_light$Mean_CO2[marginal_light$Light == "Light"], 2), "\n")
  cat("- Dark mean:", round(marginal_light$Mean_CO2[marginal_light$Light == "Dark"], 2), "\n\n")
  cat("This makes biological sense: photosynthesis in light, respiration in dark.\n")
}

✓ SIGNIFICANT MAIN EFFECT OF LIGHT

Light condition significantly affects CO2 change (p < 0.05).

  • Light mean: 228.33 NA
  • Dark mean: -109.33 NA

This makes biological sense: photosynthesis in light, respiration in dark.

if(p_nativity < 0.05) {
  cat("\n### ✓ SIGNIFICANT MAIN EFFECT OF NATIVITY\n\n")
  cat("Native and Non-Native plants differ significantly in CO2 change (p < 0.05).\n\n")
  cat("- Native mean:", round(marginal_nativity$Mean_CO2[marginal_nativity$Nativity == "Native"], 2), "\n")
  cat("- Non-Native mean:", round(marginal_nativity$Mean_CO2[marginal_nativity$Nativity == "Non-Native"], 2), "\n")
}

Statistical Reporting Template

A two-way ANOVA was conducted to examine the effects of plant nativity (Native vs Non-Native) and light condition (Light vs Dark) on CO2 change.

if(p_interaction < 0.05) {
  cat("A significant interaction was found between nativity and light condition (F = ", 
      round(anova_type3$`F value`[4], 2), ", p = ", round(p_interaction, 4), 
      "), indicating that the effect of light depends on plant nativity.")
} else {
  cat("No significant interaction was found (p = ", round(p_interaction, 4), "). ")
  
  if(p_light < 0.05) {
    cat("Light condition had a significant effect (F = ", 
        round(anova_type3$`F value`[3], 2), ", p = ", round(p_light, 4), 
        "), with higher CO2 change in light conditions. ")
  }
  
  if(p_nativity < 0.05) {
    cat("Nativity had a significant effect (F = ", 
        round(anova_type3$`F value`[2], 2), ", p = ", round(p_nativity, 4), ").")
  }
}

No significant interaction was found (p = 0.3253 ). Light condition had a significant effect (F = 8.75 , p = 0.0104 ), with higher CO2 change in light conditions.

Assumptions Check

  • Normality: Shapiro-Wilk p = 10^{-4}
  • Homogeneity of variance: Levene’s test p = 0.2252 ✓