coins
H T
6 4
STAT 204 – Introduction to Statistical Data Analysis
01 Oct 2025
Categorical data represents groups or categories rather than numerical measurements.
Examples:
Survey responses (Yes/No, Agree/Disagree)
Demographics (Gender, Race, Education Level)
Classifications (Disease status, Product type)
Today’s goals:
Create and visualize categorical data
Test if observed frequencies match expected frequencies (goodness of fit)
Test if two categorical variables are independent (contingency tables)
coins
H T
6 4
Basic functions:
table() – counts frequencies
barplot() – visualizes frequencies
prop.table() – converts counts to proportions
Example: Do car crashes occur on different days with the same frequency?
| Day | Mon | Tue | Wed | Thu | Fri | Sat | Sun |
|---|---|---|---|---|---|---|---|
| Fatalities | 20 | 20 | 22 | 22 | 29 | 36 | 31 |
Hypothesis:
\(H_0\): Crashes are equally likely on all days (uniform distribution)
\(H_A\): Some days have more crashes than others
[1] 180
[1] 25.71429 25.71429 25.71429 25.71429 25.71429 25.71429 25.71429
Chi-squared test for given probabilities
data: accidents
X-squared = 9.2333, df = 6, p-value = 0.1609
Interpretation: very small p-value indicates evidence to reject \(H_0\). We will talk about p-values later in the quarter :).
d_matrix <- cbind(accidents, expected_accidents)
rownames(d_matrix) <- c("Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun")
colnames(d_matrix) <- c("Observed", "Expected")
weekday_colors_pastel <- c(
Mon = "#B3CDE3", # Light blue
Tue = "#CCEBC5", # Light green
Wed = "#DECBE4", # Light purple
Thu = "#FED9A6", # Light orange
Fri = "#FFE6CC", # Light peach
Sat = "#FBB4AE", # Light coral
Sun = "#E5D8BD" # Light tan
)
barplot(d_matrix, beside=TRUE,
col = weekday_colors_pastel,
ylab = "Number of Fatalities")Weekend days show the largest deviations from expected values
Partner work (10 minutes)
A die is rolled 60 times with the following results:
| Face | 1 | 2 | 3 | 4 | 5 | 6 |
|---|---|---|---|---|---|---|
| Count | 8 | 12 | 9 | 11 | 13 | 7 |
Your tasks:
Discuss: What p-value would convince you the die is unfair?
Question: Is there an association between two categorical variables?
Example: Using the built-in UCBAdmissions dataset
Admission decision (Admitted/Rejected)
Gender (Male/Female)
, , Dept = A
Gender
Admit Male Female
Admitted 512 89
Rejected 313 19
, , Dept = B
Gender
Admit Male Female
Admitted 353 17
Rejected 207 8
, , Dept = C
Gender
Admit Male Female
Admitted 120 202
Rejected 205 391
, , Dept = D
Gender
Admit Male Female
Admitted 138 131
Rejected 279 244
, , Dept = E
Gender
Admit Male Female
Admitted 53 94
Rejected 138 299
, , Dept = F
Gender
Admit Male Female
Admitted 22 24
Rejected 351 317
Gender
Admit Male Female
Admitted 1198 557
Rejected 1493 1278
This shows admissions by gender at UC Berkeley (famous for Simpson’s Paradox!)
Gender
Admit Male Female
Admitted 0.6826211 0.3173789
Rejected 0.5387947 0.4612053
Reading mosaic plots:
Width = proportion of total in that category
Height = conditional proportion
Hypotheses: - \(H_0\): Admission and Gender are independent - \(H_A\): There is an association between Admission and Gender
Test statistic: \[X^2 = \sum_{\text{all cells}} \frac{(\text{observed} - \text{expected})^2}{\text{expected}}\]
Under \(H_0\), this follows \(\chi^2_{(r-1)(c-1)}\) distribution
Pearson's Chi-squared test with Yates' continuity correction
data: admit_data
X-squared = 91.61, df = 1, p-value < 2.2e-16
Gender
Admit Male Female
Admitted 1043.461 711.5389
Rejected 1647.539 1123.4611
Gender
Admit Male Female
Admitted 4.784093 -5.793466
Rejected -3.807325 4.610614
Interpretation: Statistically significant association between gender and admission
Residuals show which cells differ most from independence:
\[\text{Residual} = \frac{\text{observed} - \text{expected}}{\sqrt{\text{expected}}}\]
Gender
Admit Male Female
Admitted 4.784093 -5.793466
Rejected -3.807325 4.610614
Large positive residual: More than expected under independence
Large negative residual: Fewer than expected under independence
Partner work (12 minutes)
Use the built-in Titanic dataset to examine survival by class:
Class
Survived 1st 2nd 3rd Crew
No 122 167 528 673
Yes 203 118 178 212
Your tasks:
mosaicplot(..., shade = TRUE)Discuss: What do the residuals tell you about survival patterns?
Shading enhances mosaic plots by showing residuals:
Color coding:
Blue shades: More than expected (positive residuals)
Red shades: Fewer than expected (negative residuals)
Darker colors = larger residuals
, , Sex = Male
Eye
Hair Brown Blue Hazel Green
Black 32 11 10 3
Brown 53 50 25 15
Red 10 10 7 7
Blond 3 30 5 8
, , Sex = Female
Eye
Hair Brown Blue Hazel Green
Black 36 9 5 2
Brown 66 34 29 14
Red 16 7 7 7
Blond 4 64 5 8
Eye
Hair Brown Blue Hazel Green
Black 68 20 15 5
Brown 119 84 54 29
Red 26 17 14 14
Blond 7 94 10 16
Pearson's Chi-squared test
data: hair_eye
X-squared = 138.29, df = 9, p-value < 2.2e-16
Observation: Strong association – certain combinations (e.g., Blond/Blue) are more common than expected
Partner work (15 minutes)
Use the HairEyeColor dataset to answer:
Does the relationship between hair and eye color differ by sex?
Your tasks:
prop.table(male_data, margin = 1)Discussion questions: - Are the associations similar for males and females? - Which hair/eye combinations show the strongest associations? - How would you report these findings?
Self-study guide
Understanding the math behind chisq.test():
Male Female
Admitted 1043.461 711.5389
Rejected 1647.539 1123.4611
[1] 92.20528
[1] 0
Self-study guide
When chi-square tests are valid:
Warning signs: - Small expected counts → Fisher’s exact test - Non-independent observations → Different methods needed
Fisher's Exact Test for Count Data
data: matrix(c(3, 1, 1, 5), nrow = 2)
p-value = 0.1905
alternative hypothesis: true odds ratio is not equal to 1
95 percent confidence interval:
0.40161 930.24692
sample estimates:
odds ratio
10.29391
| Test Type | Question | R Function | Key Output |
|---|---|---|---|
| Goodness of Fit | Do observed frequencies match expected? | chisq.test(x) |
p-value |
| Independence | Are two variables associated? | chisq.test(table) |
p-value, residuals |
| Visualization | See patterns | mosaicplot(..., shade=T) |
Color-coded residuals |
Workflow:
Create table with table() or use built-in dataset
Visualize with barplot() or mosaicplot()
Test with chisq.test()
Examine residuals to understand patterns
Report findings with context
Good practices:
✓ Always visualize before testing
✓ Check expected counts (should be ≥ 5)
✓ Examine residuals to understand where associations exist
✓ Report both statistical and practical significance
Common mistakes:
✗ Ignoring small expected counts
✗ Testing without looking at the data first
✗ Only reporting p-values without interpretation
✗ Treating ordinal categories as nominal
John Tukey and other statisticians devised a collection of methods for exploratory data analysis.
Key distinction:
Today’s goal: Learn to explore data systematically before formal analysis
Tukey’s framework centers on four themes:
We’ll explore each through practical examples!
Dataset: 1995 data about colleges from U.S. News and World Report
Private Apps Accept Enroll Top10perc Top25perc
Abilene Christian University Yes 1660 1232 721 23 52
Adelphi University Yes 2186 1924 512 16 29
Adrian College Yes 1428 1097 336 22 50
Agnes Scott College Yes 417 349 137 60 89
Alaska Pacific University Yes 193 146 55 16 44
Albertson College Yes 587 479 158 38 62
F.Undergrad P.Undergrad Outstate Room.Board Books
Abilene Christian University 2885 537 7440 3300 450
Adelphi University 2683 1227 12280 6450 750
Adrian College 1036 99 11250 3750 400
Agnes Scott College 510 63 12960 5450 450
Alaska Pacific University 249 869 7560 4120 800
Albertson College 678 41 13500 3335 500
Personal PhD Terminal S.F.Ratio perc.alumni Expend
Abilene Christian University 2200 70 78 18.1 12 7041
Adelphi University 1500 29 30 12.2 16 10527
Adrian College 1165 53 66 12.9 30 8735
Agnes Scott College 875 92 97 7.7 37 19016
Alaska Pacific University 1500 76 72 11.9 2 10922
Albertson College 675 67 73 9.4 11 9727
Grad.Rate
Abilene Christian University 60
Adelphi University 56
Adrian College 54
Agnes Scott College 59
Alaska Pacific University 15
Albertson College 55
Question: What patterns can we discover about graduation rates?
Let’s start with a simple view of graduation rates:
What do you notice?
Distribution shape
Potential outliers
Range of values
Does private vs. public status matter?
Observation: Private colleges appear to have higher graduation rates overall
Boxplots are resistant – they’re not overly influenced by outliers
The boxplot clearly shows the median and quartiles for each group
Partner work (10 minutes)
The boxplot object stores useful information:
[,1] [,2]
[1,] 24 24
[2,] 46 58
[3,] 55 69
[4,] 65 81
[5,] 93 100
Your tasks:
b.output$out and b.output$groupOutstate (out-of-state tuition) by Private statusDiscuss: Why might outliers exist in graduation rates? Are they errors or legitimate cases?
Self-study guide
[1] 98 100 10 95 15 18 118 21 22 21 15 21
[1] 1 1 1 1 2 2 2 2 2 2 2 2
Boxplots identify outliers as values beyond 1.5 × IQR from the quartiles
Question: How does student quality (top 25% of HS class) relate to graduation rate?
Clear positive relationship – but how do we quantify it?
Tukey’s resistant line is robust to outliers:
Interpretation: For every 1% increase in top 25% composition, graduation rate increases by ~0.43%
plot(College$Top25perc, College$Grad.Rate,
xlab="Percent of new students from top 25% of class",
ylab="Graduation Rate")
abline(coef(fit), col='red', lwd=2) # Resistant line
abline(lm(Grad.Rate~Top25perc, data=College), col='blue', lwd=2) # OLS
legend("bottomright", legend=c("Resistant Line", "OLS"),
col=c("red", "blue"), lwd=2)Notice how similar they are when outliers aren’t extreme!
Residuals show what the model misses:
What to look for:
Random scatter → good model
Patterns → model is missing something
Outliers → unusual cases to investigate
Partner work (10 minutes)
Using the College dataset:
Accept (applications accepted) vs Apps (applications received)line()) and regular regression (lm())Discuss: - Are there outliers? - Do the two lines differ substantially? - What does the residual plot tell you?
Example: BGSU enrollment from 1955 to 1970
Problem: The relationship is clearly not linear – it curves upward


Red flag: Residuals show a clear pattern (not random!) → poor model fit
Exponential growth model: \[\text{Enrollment} = a \times \exp(b \times \text{Year})\]
Taking the log of both sides: \[\log(\text{Enrollment}) = \log(a) + b \times \text{Year}\]
Now we have a linear relationship in log-transformed data!


Much better! Residuals now appear random with no pattern
Interpretation: - Intercept: log(enrollment) when Year = 0 (not meaningful here) - Slope (0.063): Each year, log(enrollment) increases by 0.063 - This means enrollment grows by approximately 6.3% per year (exponential growth)
Partner work (10 minutes)
The dataset below shows population growth:
Your tasks:
Population vs Year – what pattern do you see?log(Population) variable and plot it vs YearDiscuss: Which model fits better? What does this suggest about population growth?
Self-study guide
Different relationships need different transformations:
| Pattern | Transformation | When to Use |
|---|---|---|
| Exponential growth | log(y) |
Data growing multiplicatively |
| Power relationship | log(x) and log(y) |
Both variables span large ranges |
| Square root | sqrt(y) |
Count data with increasing variance |
| Inverse | 1/x or 1/y |
Asymptotic relationships |
Rule of thumb: If residuals show patterns, try transforming!
| Theme | What We Did | Key Tool |
|---|---|---|
| Revelation | Discovered patterns with graphics | Stripcharts, scatterplots |
| Resistance | Used outlier-robust methods | Boxplots, resistant lines |
| Residuals | Checked model fit | Residual plots |
| Reexpression | Transformed to reveal patterns | Log transformation |
Key principle: EDA is iterative – plot, model, check residuals, transform if needed, repeat!
1. PLOT the data (revelation)
↓
2. CHECK for outliers (resistance)
↓
3. FIT a model
↓
4. EXAMINE residuals
↓
5. TRANSFORM if needed (reexpression)
↓
6. REPEAT until satisfied
Remember: EDA comes before formal hypothesis testing!
Partner work (15 minutes)
Using the mtcars dataset, perform a complete EDA:
Goal: Understand the relationship between hp (horsepower) and mpg (fuel efficiency)
line() and lm()log(mpg) or log(hp)Present: Be ready to share your findings – which model works best?
Source: Barter, R. L., & Yu, B. (2024). Veridical Data Science, Chapter 5. MIT Press. Available at https://vdsbook.com/05-data_viz
Source: Veridic Data Science
Central Tendency:
Mean: Average value; sensitive to outliers
Median: Middle value; robust to outliers
Spread:
Variance/Standard Deviation: Measure of variability around the mean
Interquartile Range (IQR): Difference between 75th and 25th percentiles
Covariance & Correlation:
Covariance: Measures how two variables vary together (scale-dependent)
Correlation: Standardized measure between -1 and 1
Key Principle: Always ensure comparability when making comparisons (e.g., use rates per capita rather than raw counts when populations differ)
Before presenting EDA results, evaluate them using the PCS Framework:
Before presenting EDA results, evaluate them using the PCS Framework:
Assess robustness to perturbations:
Data perturbations: Add noise to test if conclusions hold
Cleaning judgment calls: Try alternative imputation methods
Visualization choices: Test different chart types, filtering decisions, color schemes
Bottom Line: Your EDA findings should be stable across reasonable alternative judgment calls and resistant to plausible data variations.
Books:
Exploratory Data Analysis by John Tukey (classic!)
R for Data Science by Wickham & Grolemund (modern approach)
Veridic Data Science by Bin Yu & Rebecca L. Barter (modern approach)
R Functions to Remember:
Visualization: plot(), boxplot(), hist(), stripchart()
Resistant methods: median(), IQR(), line()
Transformations: log(), sqrt(), exp()
Residuals: residuals() or fit$residuals
Practice: EDA skills improve with experience – explore many datasets!
Today we’ll cover:
In-class focus: We’ll spend most time on ggplot2 as it’s more intuitive and widely used in modern data science.
Key function: plot() creates basic visualizations
We’ll see a few examples, but detailed customization is in the reference slides.
Partner work (10 minutes)
Using the mtcars dataset:
mpg vs wt (weight)pch = 19)Bonus: Add a lowess smoothing line in red
Discuss: What relationship do you observe?
The following slides contain useful reference material for customizing base R graphics. Review these on your own time.
Self-study guide
Parameters in the function plot:
Self-study guide
Common type values: - "p" for points (default) - "l" for lines - "b" for both - "h" for histogram-like vertical lines
Self-study guide
Self-study guide
Mileage depends on the number of cylinders:
Self-study guide
Self-study guide
Creating custom plots from scratch:
Self-study guide
Self-study guide
Common parameters:
xlim and ylim – axis rangesxaxt="n" and yaxt="n" – suppress axespch – plotting symbols (1-25)cex – size of symbolslwd – line widthcol – colorslty – line types (1-6)Self-study guide
[1] "white" "aliceblue" "antiquewhite"
[4] "antiquewhite1" "antiquewhite2" "antiquewhite3"
[7] "antiquewhite4" "aquamarine" "aquamarine1"
[10] "aquamarine2" "aquamarine3" "aquamarine4"
[13] "azure" "azure1" "azure2"
[16] "azure3" "azure4" "beige"
[19] "bisque" "bisque1" "bisque2"
[22] "bisque3" "bisque4" "black"
[25] "blanchedalmond" "blue" "blue1"
[28] "blue2" "blue3" "blue4"
[31] "blueviolet" "brown" "brown1"
[34] "brown2" "brown3" "brown4"
[37] "burlywood" "burlywood1" "burlywood2"
[40] "burlywood3" "burlywood4" "cadetblue"
[43] "cadetblue1" "cadetblue2" "cadetblue3"
[46] "cadetblue4" "chartreuse" "chartreuse1"
[49] "chartreuse2" "chartreuse3" "chartreuse4"
[52] "chocolate" "chocolate1" "chocolate2"
[55] "chocolate3" "chocolate4" "coral"
[58] "coral1" "coral2" "coral3"
[61] "coral4" "cornflowerblue" "cornsilk"
[64] "cornsilk1" "cornsilk2" "cornsilk3"
[67] "cornsilk4" "cyan" "cyan1"
[70] "cyan2" "cyan3" "cyan4"
[73] "darkblue" "darkcyan" "darkgoldenrod"
[76] "darkgoldenrod1" "darkgoldenrod2" "darkgoldenrod3"
[79] "darkgoldenrod4" "darkgray" "darkgreen"
[82] "darkgrey" "darkkhaki" "darkmagenta"
[85] "darkolivegreen" "darkolivegreen1" "darkolivegreen2"
[88] "darkolivegreen3" "darkolivegreen4" "darkorange"
[91] "darkorange1" "darkorange2" "darkorange3"
[94] "darkorange4" "darkorchid" "darkorchid1"
[97] "darkorchid2" "darkorchid3" "darkorchid4"
[100] "darkred" "darksalmon" "darkseagreen"
[103] "darkseagreen1" "darkseagreen2" "darkseagreen3"
[106] "darkseagreen4" "darkslateblue" "darkslategray"
[109] "darkslategray1" "darkslategray2" "darkslategray3"
[112] "darkslategray4" "darkslategrey" "darkturquoise"
[115] "darkviolet" "deeppink" "deeppink1"
[118] "deeppink2" "deeppink3" "deeppink4"
[121] "deepskyblue" "deepskyblue1" "deepskyblue2"
[124] "deepskyblue3" "deepskyblue4" "dimgray"
[127] "dimgrey" "dodgerblue" "dodgerblue1"
[130] "dodgerblue2" "dodgerblue3" "dodgerblue4"
[133] "firebrick" "firebrick1" "firebrick2"
[136] "firebrick3" "firebrick4" "floralwhite"
[139] "forestgreen" "gainsboro" "ghostwhite"
[142] "gold" "gold1" "gold2"
[145] "gold3" "gold4" "goldenrod"
[148] "goldenrod1" "goldenrod2" "goldenrod3"
[151] "goldenrod4" "gray" "gray0"
[154] "gray1" "gray2" "gray3"
[157] "gray4" "gray5" "gray6"
[160] "gray7" "gray8" "gray9"
[163] "gray10" "gray11" "gray12"
[166] "gray13" "gray14" "gray15"
[169] "gray16" "gray17" "gray18"
[172] "gray19" "gray20" "gray21"
[175] "gray22" "gray23" "gray24"
[178] "gray25" "gray26" "gray27"
[181] "gray28" "gray29" "gray30"
[184] "gray31" "gray32" "gray33"
[187] "gray34" "gray35" "gray36"
[190] "gray37" "gray38" "gray39"
[193] "gray40" "gray41" "gray42"
[196] "gray43" "gray44" "gray45"
[199] "gray46" "gray47" "gray48"
[202] "gray49" "gray50" "gray51"
[205] "gray52" "gray53" "gray54"
[208] "gray55" "gray56" "gray57"
[211] "gray58" "gray59" "gray60"
[214] "gray61" "gray62" "gray63"
[217] "gray64" "gray65" "gray66"
[220] "gray67" "gray68" "gray69"
[223] "gray70" "gray71" "gray72"
[226] "gray73" "gray74" "gray75"
[229] "gray76" "gray77" "gray78"
[232] "gray79" "gray80" "gray81"
[235] "gray82" "gray83" "gray84"
[238] "gray85" "gray86" "gray87"
[241] "gray88" "gray89" "gray90"
[244] "gray91" "gray92" "gray93"
[247] "gray94" "gray95" "gray96"
[250] "gray97" "gray98" "gray99"
[253] "gray100" "green" "green1"
[256] "green2" "green3" "green4"
[259] "greenyellow" "grey" "grey0"
[262] "grey1" "grey2" "grey3"
[265] "grey4" "grey5" "grey6"
[268] "grey7" "grey8" "grey9"
[271] "grey10" "grey11" "grey12"
[274] "grey13" "grey14" "grey15"
[277] "grey16" "grey17" "grey18"
[280] "grey19" "grey20" "grey21"
[283] "grey22" "grey23" "grey24"
[286] "grey25" "grey26" "grey27"
[289] "grey28" "grey29" "grey30"
[292] "grey31" "grey32" "grey33"
[295] "grey34" "grey35" "grey36"
[298] "grey37" "grey38" "grey39"
[301] "grey40" "grey41" "grey42"
[304] "grey43" "grey44" "grey45"
[307] "grey46" "grey47" "grey48"
[310] "grey49" "grey50" "grey51"
[313] "grey52" "grey53" "grey54"
[316] "grey55" "grey56" "grey57"
[319] "grey58" "grey59" "grey60"
[322] "grey61" "grey62" "grey63"
[325] "grey64" "grey65" "grey66"
[328] "grey67" "grey68" "grey69"
[331] "grey70" "grey71" "grey72"
[334] "grey73" "grey74" "grey75"
[337] "grey76" "grey77" "grey78"
[340] "grey79" "grey80" "grey81"
[343] "grey82" "grey83" "grey84"
[346] "grey85" "grey86" "grey87"
[349] "grey88" "grey89" "grey90"
[352] "grey91" "grey92" "grey93"
[355] "grey94" "grey95" "grey96"
[358] "grey97" "grey98" "grey99"
[361] "grey100" "honeydew" "honeydew1"
[364] "honeydew2" "honeydew3" "honeydew4"
[367] "hotpink" "hotpink1" "hotpink2"
[370] "hotpink3" "hotpink4" "indianred"
[373] "indianred1" "indianred2" "indianred3"
[376] "indianred4" "ivory" "ivory1"
[379] "ivory2" "ivory3" "ivory4"
[382] "khaki" "khaki1" "khaki2"
[385] "khaki3" "khaki4" "lavender"
[388] "lavenderblush" "lavenderblush1" "lavenderblush2"
[391] "lavenderblush3" "lavenderblush4" "lawngreen"
[394] "lemonchiffon" "lemonchiffon1" "lemonchiffon2"
[397] "lemonchiffon3" "lemonchiffon4" "lightblue"
[400] "lightblue1" "lightblue2" "lightblue3"
[403] "lightblue4" "lightcoral" "lightcyan"
[406] "lightcyan1" "lightcyan2" "lightcyan3"
[409] "lightcyan4" "lightgoldenrod" "lightgoldenrod1"
[412] "lightgoldenrod2" "lightgoldenrod3" "lightgoldenrod4"
[415] "lightgoldenrodyellow" "lightgray" "lightgreen"
[418] "lightgrey" "lightpink" "lightpink1"
[421] "lightpink2" "lightpink3" "lightpink4"
[424] "lightsalmon" "lightsalmon1" "lightsalmon2"
[427] "lightsalmon3" "lightsalmon4" "lightseagreen"
[430] "lightskyblue" "lightskyblue1" "lightskyblue2"
[433] "lightskyblue3" "lightskyblue4" "lightslateblue"
[436] "lightslategray" "lightslategrey" "lightsteelblue"
[439] "lightsteelblue1" "lightsteelblue2" "lightsteelblue3"
[442] "lightsteelblue4" "lightyellow" "lightyellow1"
[445] "lightyellow2" "lightyellow3" "lightyellow4"
[448] "limegreen" "linen" "magenta"
[451] "magenta1" "magenta2" "magenta3"
[454] "magenta4" "maroon" "maroon1"
[457] "maroon2" "maroon3" "maroon4"
[460] "mediumaquamarine" "mediumblue" "mediumorchid"
[463] "mediumorchid1" "mediumorchid2" "mediumorchid3"
[466] "mediumorchid4" "mediumpurple" "mediumpurple1"
[469] "mediumpurple2" "mediumpurple3" "mediumpurple4"
[472] "mediumseagreen" "mediumslateblue" "mediumspringgreen"
[475] "mediumturquoise" "mediumvioletred" "midnightblue"
[478] "mintcream" "mistyrose" "mistyrose1"
[481] "mistyrose2" "mistyrose3" "mistyrose4"
[484] "moccasin" "navajowhite" "navajowhite1"
[487] "navajowhite2" "navajowhite3" "navajowhite4"
[490] "navy" "navyblue" "oldlace"
[493] "olivedrab" "olivedrab1" "olivedrab2"
[496] "olivedrab3" "olivedrab4" "orange"
[499] "orange1" "orange2" "orange3"
[502] "orange4" "orangered" "orangered1"
[505] "orangered2" "orangered3" "orangered4"
[508] "orchid" "orchid1" "orchid2"
[511] "orchid3" "orchid4" "palegoldenrod"
[514] "palegreen" "palegreen1" "palegreen2"
[517] "palegreen3" "palegreen4" "paleturquoise"
[520] "paleturquoise1" "paleturquoise2" "paleturquoise3"
[523] "paleturquoise4" "palevioletred" "palevioletred1"
[526] "palevioletred2" "palevioletred3" "palevioletred4"
[529] "papayawhip" "peachpuff" "peachpuff1"
[532] "peachpuff2" "peachpuff3" "peachpuff4"
[535] "peru" "pink" "pink1"
[538] "pink2" "pink3" "pink4"
[541] "plum" "plum1" "plum2"
[544] "plum3" "plum4" "powderblue"
[547] "purple" "purple1" "purple2"
[550] "purple3" "purple4" "red"
[553] "red1" "red2" "red3"
[556] "red4" "rosybrown" "rosybrown1"
[559] "rosybrown2" "rosybrown3" "rosybrown4"
[562] "royalblue" "royalblue1" "royalblue2"
[565] "royalblue3" "royalblue4" "saddlebrown"
[568] "salmon" "salmon1" "salmon2"
[571] "salmon3" "salmon4" "sandybrown"
[574] "seagreen" "seagreen1" "seagreen2"
[577] "seagreen3" "seagreen4" "seashell"
[580] "seashell1" "seashell2" "seashell3"
[583] "seashell4" "sienna" "sienna1"
[586] "sienna2" "sienna3" "sienna4"
[589] "skyblue" "skyblue1" "skyblue2"
[592] "skyblue3" "skyblue4" "slateblue"
[595] "slateblue1" "slateblue2" "slateblue3"
[598] "slateblue4" "slategray" "slategray1"
[601] "slategray2" "slategray3" "slategray4"
[604] "slategrey" "snow" "snow1"
[607] "snow2" "snow3" "snow4"
[610] "springgreen" "springgreen1" "springgreen2"
[613] "springgreen3" "springgreen4" "steelblue"
[616] "steelblue1" "steelblue2" "steelblue3"
[619] "steelblue4" "tan" "tan1"
[622] "tan2" "tan3" "tan4"
[625] "thistle" "thistle1" "thistle2"
[628] "thistle3" "thistle4" "tomato"
[631] "tomato1" "tomato2" "tomato3"
[634] "tomato4" "turquoise" "turquoise1"
[637] "turquoise2" "turquoise3" "turquoise4"
[640] "violet" "violetred" "violetred1"
[643] "violetred2" "violetred3" "violetred4"
[646] "wheat" "wheat1" "wheat2"
[649] "wheat3" "wheat4" "whitesmoke"
[652] "yellow" "yellow1" "yellow2"
[655] "yellow3" "yellow4" "yellowgreen"
Tip: Use RColorBrewer package for colorblind-safe palettes
Self-study guide
Advantages over base R:
Philosophy: Grammar of Graphics - build plots by combining data, aesthetics, and geometric objects
Three essential components:
aes()) – map variables to visual propertiesgeom_*()) – how to display the datatibble [42,080 × 6] (S3: tbl_df/tbl/data.frame)
$ PUMA : chr [1:42080] "00705" "01301" "00200" "01321" ...
$ SALARY: num [1:42080] 12000 5700 0 0 0 0 30000 0 0 1800 ...
$ WEIGHT: num [1:42080] 5 68 81 36 66 34 144 88 50 48 ...
$ AGE : num [1:42080] 18 19 37 20 18 85 32 63 37 19 ...
$ RACE : num [1:42080] 1 1 1 1 6 1 1 1 3 9 ...
$ HICOV : num [1:42080] 1 1 1 1 1 1 1 1 2 1 ...
Categorical variable:
Continuous variable:
Scatterplot:
Boxplot by group:
Bar plot (summary statistic):
Partner work (10 minutes)
Using the palmerpenguins::penguins dataset:
bill_length_mmbill_length_mm vs bill_depth_mmDiscuss: What patterns do you notice in bill dimensions?
aes())Inside aes() - maps data to visuals:
Outside aes() - fixed values:
Critical distinction: Use aes() when mapping to variables, set directly when using constants
By one variable:
By two variables:
Partner work (10 minutes)
Using penguins data, create a visualization that:
facet_wrap() to create separate panels by islandgeom_smooth()theme_bw() or theme_minimal())Discuss: - How do the relationships differ across islands? - Which species tends to be largest?
Same plot, different approaches:
Base R:

ggplot2:
Key takeaways:
Recommendation: Use ggplot2 for most tasks, especially for publication-quality graphics
General - Data Visualization Catalogue - Veridic Data Science
ggplot2: - ggplot2 documentation - R Graphics Cookbook - ggplot2 cheat sheet
Base R: - See reference slides (gray background) - ?plot, ?par for help
Practice: The best way to learn is by creating many plots!
![]()
STAT 204 – Intro to Statistical Data Analysis