STAT 204 – Introduction to Statistical Data Analysis
01 Oct 2025
For reproducibility:
Default values make functions flexible!
To see calculations, use print():
Only printed output is shown!
Positional vs named:
R doesn’t check unused arguments:
Write these functions:
my_range() - takes a vector and returns max - minstandardize() - takes a vector and returns (x - mean)/sdmy_summary() - takes a vector and returns a named list with mean, median, and sdTest your functions on:
Bonus: Modify my_summary() to handle NA values
R allows free variables in functions:
Warning: Avoid free variables unless you know what you’re doing! Can cause unexpected behavior.
Store frequently-used functions in a file:
Make sure the file is in your working directory or provide full path!
Pre-allocate memory!
Memory allocation is expensive!
Vectorized functions are much faster!
apply FunctionAdditional arguments passed to the function!
For common operations, use optimized functions:
Much faster!
We looked at two different ways to standardize the columns of a matrix:
Your task: Find a third approach and compare the computation time to the first two approaches. Post your solution on Ed Discussion.
Hint: Consider using sweep() or vectorization with matrix operations
expand.grid FunctionEvaluate functions on a 2D grid:
Finding the Minimum of a Function
Consider the following function:
\(f(x, y) = (1.5 - x + xy)^2 + (2.25 - x + xy^2)^2 + (2.625 - x + xy^3)^2\)
where possible inputs for \(x\) and \(y\) are from -4 to 4 in increments of 0.1.
Your tasks:
expand.grid()Hint: Use which.min() to find the index of the minimum value
Packages are collections of functions that extend R:
Popular packages 📦
R has excellent built-in help:
Other ways to get help 🆘
# A tibble: 344 × 8
species island bill_length_mm bill_depth_mm flipper_length_mm body_mass_g
<fct> <fct> <dbl> <dbl> <int> <int>
1 Adelie Torgersen 39.1 18.7 181 3750
2 Adelie Torgersen 39.5 17.4 186 3800
3 Adelie Torgersen 40.3 18 195 3250
4 Adelie Torgersen NA NA NA NA
5 Adelie Torgersen 36.7 19.3 193 3450
6 Adelie Torgersen 39.3 20.6 190 3650
7 Adelie Torgersen 38.9 17.8 181 3625
8 Adelie Torgersen 39.2 19.6 195 4675
9 Adelie Torgersen 34.1 18.1 193 3475
10 Adelie Torgersen 42 20.2 190 4250
# ℹ 334 more rows
# ℹ 2 more variables: sex <fct>, year <int>
# A tibble: 6 × 8
species island bill_length_mm bill_depth_mm flipper_length_mm body_mass_g
<fct> <fct> <dbl> <dbl> <int> <int>
1 Adelie Torgersen 39.1 18.7 181 3750
2 Adelie Torgersen 39.5 17.4 186 3800
3 Adelie Torgersen 40.3 18 195 3250
4 Adelie Torgersen NA NA NA NA
5 Adelie Torgersen 36.7 19.3 193 3450
6 Adelie Torgersen 39.3 20.6 190 3650
# ℹ 2 more variables: sex <fct>, year <int>
species island bill_length_mm bill_depth_mm
Adelie :152 Biscoe :168 Min. :32.10 Min. :13.10
Chinstrap: 68 Dream :124 1st Qu.:39.23 1st Qu.:15.60
Gentoo :124 Torgersen: 52 Median :44.45 Median :17.30
Mean :43.92 Mean :17.15
3rd Qu.:48.50 3rd Qu.:18.70
Max. :59.60 Max. :21.50
NA's :2 NA's :2
flipper_length_mm body_mass_g sex year
Min. :172.0 Min. :2700 female:165 Min. :2007
1st Qu.:190.0 1st Qu.:3550 male :168 1st Qu.:2007
Median :197.0 Median :4050 NA's : 11 Median :2008
Mean :200.9 Mean :4202 Mean :2008
3rd Qu.:213.0 3rd Qu.:4750 3rd Qu.:2009
Max. :231.0 Max. :6300 Max. :2009
NA's :2 NA's :2
tibble [344 × 8] (S3: tbl_df/tbl/data.frame)
$ species : Factor w/ 3 levels "Adelie","Chinstrap",..: 1 1 1 1 1 1 1 1 1 1 ...
$ island : Factor w/ 3 levels "Biscoe","Dream",..: 3 3 3 3 3 3 3 3 3 3 ...
$ bill_length_mm : num [1:344] 39.1 39.5 40.3 NA 36.7 39.3 38.9 39.2 34.1 42 ...
$ bill_depth_mm : num [1:344] 18.7 17.4 18 NA 19.3 20.6 17.8 19.6 18.1 20.2 ...
$ flipper_length_mm: int [1:344] 181 186 195 NA 193 190 181 195 193 190 ...
$ body_mass_g : int [1:344] 3750 3800 3250 NA 3450 3650 3625 4675 3475 4250 ...
$ sex : Factor w/ 2 levels "female","male": 2 1 1 NA 1 2 1 2 NA NA ...
$ year : int [1:344] 2007 2007 2007 2007 2007 2007 2007 2007 2007 2007 ...
Explore the penguins! (8 minutes) 🐧
Working with a partner:
View(penguins) to open the data in a spreadsheet-like viewmean(penguins$bill_length_mm, na.rm = TRUE))table(penguins$island))Discuss: What interesting patterns do you notice? 🔍
For small datasets:
Text file with headers:
Tips for preparing data:
Same number of columns per row
Use NA for missing data
Remove special characters
Replace spaces in headers with underscores
authors <- data.frame(
surname = c("Tukey", "Venables", "Tierney", "Ripley", "McNeil"),
nationality = c("US", "AUS", "US", "UK", "AUS")
)
books <- data.frame(
name = c("Tukey", "Venables", "Tierney", "Ripley", "Ripley", "McNeil", "R Core"),
title = c("Exploratory Data Analysis", "Modern Applied Statistics",
"LISP-STAT", "Spatial Statistics", "Stochastic Simulation",
"Interactive Data Analysis", "An Introduction to R")
)
m1 <- merge(authors, books, by.x = "surname", by.y = "name")Only matching rows are kept by default!
A variable may be classified as:
A dataframe may contain variables of different types.
Data may have additional structure as well. For example, when data are collected over time, we have time series data which is indexed by time. Similarly, when data are collected over a spatial domain, we have spatial data which is indexed by a location.
Example: body and brain size of mammals (two quantitative variables)
body brain
Arctic fox 3.385 44.5
Owl monkey 0.480 15.5
Mountain beaver 1.350 8.1
Cow 465.000 423.0
Grey wolf 36.330 119.5
Goat 27.660 115.0
body brain
Min. : 0.005 Min. : 0.14
1st Qu.: 0.600 1st Qu.: 4.25
Median : 3.342 Median : 17.25
Mean : 198.790 Mean : 283.13
3rd Qu.: 48.203 3rd Qu.: 166.00
Max. :6654.000 Max. :5712.00
\[\rho_{X,Y} = \frac{\text{Cov}(X, Y)}{\text{SD}(X) \times \text{SD}(Y)} = \frac{E[(X - \mu_X)(Y - \mu_Y)]}{\sigma_X \sigma_Y}\]
\[r_{xy} = \frac{S_{xy}}{\sqrt{S_{xx}S_{yy}}}\]
where:
Example: IQ of twins separated near birth
Foster Biological Social
1 82 82 high
2 80 90 high
3 88 91 high
4 108 115 high
5 116 115 high
6 117 129 high
7 132 131 high
8 71 78 middle
9 75 79 middle
10 93 82 middle
11 95 97 middle
12 88 100 middle
13 111 107 middle
14 63 68 low
15 77 73 low
16 86 81 low
17 83 85 low
18 93 87 low
19 97 87 low
20 87 93 low
21 94 94 low
22 96 95 low
23 112 97 low
24 113 97 low
25 106 103 low
26 107 106 low
27 98 111 low
Numeric Summary
Another way to display this data is through a scatterplot
The function coplot displays several plots on the same scale. The syntax y~x|a means plots of y vs. x are conditional on a (order from bottom and from left)
the lattice library also allows us to make conditional plots, which may be easier to read
Working with your neighbor (8 minutes)
Let’s explore the twins dataset from the UsingR package:
Your tasks:
IQ_diff <- twins$Foster - twins$BiologicalPost your findings on Ed Discussion!
Example: data from a study comparing brain size and intelligence; 40 individuals; brain size measured by MRI; 8 variables
Here’s the table in proper markdown format:
| Variable | Description |
|---|---|
| Gender | Male or Female |
| FSIQ | Full Scale IQ scores based on four Wechsler (1981) subtests |
| VIQ | Verbal IQ scores based on four Wechsler (1981) subtests |
| PIQ | Performance IQ scores based on four Wechsler (1981) subtests |
| Weight | Body weight in pounds |
| Height | Height in inches |
| MRI_Count | total pixel Count from the 18 MRI scans |
Note the missing values under weight and height
Gender FSIQ VIQ PIQ
Length:40 Min. : 77.00 Min. : 71.0 Min. : 72.00
Class :character 1st Qu.: 89.75 1st Qu.: 90.0 1st Qu.: 88.25
Mode :character Median :116.50 Median :113.0 Median :115.00
Mean :113.45 Mean :112.3 Mean :111.03
3rd Qu.:135.50 3rd Qu.:129.8 3rd Qu.:128.00
Max. :144.00 Max. :150.0 Max. :150.00
Weight Height MRI_Count
Min. :106.0 Min. :62.00 Min. : 790619
1st Qu.:135.2 1st Qu.:66.00 1st Qu.: 855918
Median :146.5 Median :68.00 Median : 905399
Mean :151.1 Mean :68.53 Mean : 908755
3rd Qu.:172.0 3rd Qu.:70.50 3rd Qu.: 950078
Max. :192.0 Max. :77.00 Max. :1079549
NA's :2 NA's :1
Missing values:
The by function allows us to consider summaries by group
The pairs function can be used to display scatterplots for all pairs of (numeric) variables
The variables FSIQ, VIQ, and PIQ have strong positive correlation
FSIQ VIQ PIQ Weight Height MRI_Count
FSIQ 1.00 0.95 0.93 NA NA 0.36
VIQ 0.95 1.00 0.78 NA NA 0.34
PIQ 0.93 0.78 1.00 NA NA 0.39
Weight NA NA NA 1 NA NA
Height NA NA NA NA 1 NA
MRI_Count 0.36 0.34 0.39 NA NA 1.00
FSIQ VIQ PIQ Weight Height MRI_Count
FSIQ 1.00 0.95 0.93 -0.05 -0.09 0.36
VIQ 0.95 1.00 0.78 -0.08 -0.07 0.34
PIQ 0.93 0.78 1.00 0.00 -0.08 0.39
Weight -0.05 -0.08 0.00 1.00 0.70 0.51
Height -0.09 -0.07 -0.08 0.70 1.00 0.60
MRI_Count 0.36 0.34 0.39 0.51 0.60 1.00
Controlling for body size (measured as weight): Identifying missing data:
Partner work (10 minutes)
Investigate the relationship between brain size and IQ scores:
Your tasks:
plot(..., col=as.integer(as.factor(Gender)))by()Bonus: Control for body size by creating MRI_per_Weight <- MRI_Count/Weight and recalculate the correlation with FSIQ. Does this change your conclusions?
Share your insights on Ed Discussion!
Resources:
?function_name??keywordPractice makes perfect!
![]()
STAT 204 – Intro to Statistical Data Analysis