## ----setup, include = FALSE--------------------------------------------------- knitr::opts_chunk$set( collapse = TRUE, comment = "#>", fig.width = 7, fig.height = 5, fig.align = 'center', dev = "png", warning = FALSE, message = FALSE ) ## ----libraries---------------------------------------------------------------- library(ggmosaic2) library(vcdExtra) library(dplyr) ## ----theme-setup, include = FALSE--------------------------------------------- # Set theme globally to avoid repetition theme_set(theme_mosaic()) ## ----table-form--------------------------------------------------------------- # HairEyeColor is already in table form str(HairEyeColor) class(HairEyeColor) # Examine the 3-way table structure HairEyeColor # Total observations sum(HairEyeColor) ## ----color-table-------------------------------------------------------------- color_table(HairEyeColor, shade = "freq") ## ----frequency-form----------------------------------------------------------- # Convert table to frequency form hair_freq <- as.data.frame(HairEyeColor) head(hair_freq, 10) nrow(hair_freq) # 32 cells in the 4 × 4 × 2 table # Verify totals match sum(hair_freq$Freq) ## ----case-form---------------------------------------------------------------- # Convert frequency form to case form using vcdExtra::expand.dft() hair_case <- expand.dft(hair_freq, freq = "Freq") head(hair_case, 10) nrow(hair_case) # 592 individual observations # Structure str(hair_case) ## ----conversions-------------------------------------------------------------- # Case → Frequency (count occurrences) hair_case |> count(Hair, Eye, Sex, name = "Freq") |> head() # Frequency → Table hair_table <- xtabs(Freq ~ Hair + Eye + Sex, data = hair_freq) identical(hair_table, HairEyeColor) # Table → Frequency (already shown) # Frequency → Case (already shown) ## ----mosaic-3way-frequency, fig.height=5-------------------------------------- # From frequency form (most common) ggplot(data = hair_freq, aes(weight = Freq, x = product(Hair, Eye, Sex), fill = Eye)) + geom_mosaic() + labs(title = "Three-Way Mosaic: Hair × Eye × Sex", subtitle = "Frequency form with weight aesthetic") ## ----mosaic-3way-case, fig.height=5------------------------------------------- # From case form ggplot(data = hair_case, aes(x = product(Hair, Eye, Sex), fill = Eye)) + geom_mosaic() + labs(title = "Three-Way Mosaic: Hair × Eye × Sex", subtitle = "Case form without weight") ## ----mosaic-conds, fig.height=5----------------------------------------------- # Condition on Sex ggplot(data = hair_freq, aes(weight = Freq, x = product(Hair, Eye), conds = product(Sex), fill = Eye)) + geom_mosaic() + labs(title = "Hair × Eye | Sex", subtitle = "Conditioned on Sex") ## ----default-shading---------------------------------------------------------- ggplot(data = hair_freq, aes(weight = Freq, x = product(Hair, Eye), fill = Eye)) + geom_mosaic() + labs(title = "Hair × Eye Color: Default Shading", subtitle = "Fill shows Eye color levels") ## ----residual-2way------------------------------------------------------------ ggplot(data = hair_freq, aes(weight = Freq, x = product(Hair, Eye))) + geom_mosaic(expected = "independence") + scale_fill_residual() + labs(title = "Hair × Eye Color: Independence Model", subtitle = "Blue = more than expected, Red = fewer than expected") ## ----residual-labels---------------------------------------------------------- ggplot(data = hair_freq, aes(weight = Freq, x = product(Hair, Eye))) + mosaic_settings(expected = "independence") + geom_mosaic() + scale_fill_residual() + geom_mosaic_text(display_values = "residual", format_digits = 1, size = 3.5, colour = "black") + labs(title = "Hair × Eye Independence Model with Residual Values", subtitle = "Numbers show Pearson residuals") ## ----residual-3way------------------------------------------------------------ ggplot(data = hair_freq, aes(weight = Freq, x = product(Hair, Eye, Sex))) + geom_mosaic(expected = "independence") + scale_fill_residual() + labs(title = "Hair × Eye × Sex: Complete Independence", subtitle = "Model: ~ Hair + Eye + Sex (no interactions)") ## ----custom-model------------------------------------------------------------- # Model: Hair and Eye are associated, but independent of Sex ggplot(data = hair_freq, aes(weight = Freq, x = product(Hair, Eye, Sex))) + geom_mosaic(expected = ~ Hair * Eye + Sex) + scale_fill_residual() + labs(title = "Model: (Hair × Eye) Independent of Sex", subtitle = "~ Hair * Eye + Sex") ## ----expected-values---------------------------------------------------------- ggplot(data = hair_freq, aes(weight = Freq, x = product(Hair, Eye))) + mosaic_settings(expected = "independence") + geom_mosaic() + scale_fill_residual() + geom_mosaic_text(display_values = "expected", format_digits = 1, size = 3.5, colour = "black") + labs(title = "Expected Frequencies Under Independence", subtitle = "Compare with observed to see associations") ## ----observed-values---------------------------------------------------------- ggplot(data = hair_freq, aes(weight = Freq, x = product(Hair, Eye))) + geom_mosaic(aes(fill = Eye)) + geom_mosaic_text(display_values = "observed", format_digits = 0, size = 3.5, colour = "white") + labs(title = "Observed Frequencies", subtitle = "Actual counts in each cell") ## ----session-info------------------------------------------------------------- sessionInfo()