lake | mean_length | sd_length | se_length | count |
---|---|---|---|---|
I3 | 265.6061 | 28.30378 | 3.483954 | 66 |
I8 | 362.5980 | 52.33901 | 5.182334 | 102 |
Center - mean, median, mode
Spread - range, variance, standard deviation
Center - mean, median, mode
Spread - range, variance, standard deviation
Center - mean, median, mode
Spread - range, variance, standard deviation
lake | mean_length | sd_length | se_length | count |
---|---|---|---|---|
I3 | 265.6061 | 28.30378 | 3.483954 | 66 |
I8 | 362.5980 | 52.33901 | 5.182334 | 102 |
The goals for today
In the more typical case DON’T know the population σ or standard deviation
Instead, we use Student’s t distribution
When sample sizes are small, the t-distribution is more appropriate than the normal distribution.
Small sample sizes
When population standard deviation is unknown
Calculating confidence intervals
Conducting t-tests
When sample sizes are small, the t-distribution is more appropriate than the normal distribution.
Small sample sizes
When population standard deviation is unknown
Calculating confidence intervals
Conducting t-tests
Practice Exercise 4: Using the t-distribution
Let’s compare confidence intervals using the normal approximation (z) versus the t-distribution for our fish data.
# Calculate CI using both z and t distributions for a smaller subset
small_sample <- grayling_df %>%
filter(lake == "I3") %>%
slice_sample(n = 10)
# Calculate statistics
sample_mean <- mean(small_sample$length_mm)
sample_sd <- sd(small_sample$length_mm)
sample_n <- nrow(small_sample)
sample_se <- sample_sd / sqrt(sample_n)
# Calculate confidence intervals
z_ci_lower <- sample_mean - 1.96 * sample_se
z_ci_upper <- sample_mean + 1.96 * sample_se
# For t-distribution, get critical value for 95% CI with df = n-1
t_crit <- qt(0.975, df = sample_n - 1)
t_ci_lower <- sample_mean - t_crit * sample_se
t_ci_upper <- sample_mean + t_crit * sample_se
# Display results
cat("Mean:", round(sample_mean, 1), "mm\n")
Mean: 279.2 mm
Standard deviation: 20.03 mm
Standard error: 6.33 mm
95% CI using z: 266.8 to 291.6 mm
95% CI using t: 264.9 to 293.5 mm
t critical value: 2.262 vs z critical value: 1.96
To calculate CI for sample from “unknown” population:
Where:
Here is a t-table
One-tailed questions: area of distribution left or (right) of a certain value
Two-tailed questions refer to area between certain values
Let’s calculate CIs again:
Use two-sided test
So:
We want to test if the mean fish length in I3 differs from 240mm.
Activity: Define hypotheses and identify assumptions
H₀: μ = 240 (The mean fish length in I3 is 240mm)
H₁: μ ≠ 240 (The mean fish length in I3 is not 240mm)
# Filter for just windward side needles
# YOUR TASK: Test normality of windward pine needle lengths
# QQ Plot
qqPlot(i3_df$length_mm,
main = "QQ Plot for length of Grayling",
ylab = "Sample Quantiles")
[1] 53 35
Practice Exercise 1: One-Sample t-Test
Let’s perform a one-sample t-test to determine if the mean fish length in I3 Lake differs from 240 mm:
# what is the mean
i3_mean <- mean(i3_df$length_mm, na.rm=TRUE)
cat("Mean:", round(i3_mean, 1), "mm\n")
Mean: 265.6 mm
# Perform a one-sample t-test
t_test_result <- t.test(i3_df$length_mm, mu = 240)
# View the test results
t_test_result
One Sample t-test
data: i3_df$length_mm
t = 7.3497, df = 65, p-value = 4.17e-10
alternative hypothesis: true mean is not equal to 240
95 percent confidence interval:
258.6481 272.5640
sample estimates:
mean of x
265.6061
Interpret this test result by answering these questions:
Hypothesis testing is a systematic way to evaluate research questions using data.
Key components:
Decision rule: Reject Ho if p-value < α == p < 0.05
Hypothesis testing is a systematic way to evaluate research questions using data.
Key components:
Null hypothesis (H₀): Typically assumes “no effect” or “no difference”
Alternative hypothesis (Hₐ): The claim we’re trying to support
Statistical test: Method for evaluating evidence against H₀
P-value: Probability of observing our results (or more extreme) if H₀ is true
Significance level (α): Threshold for rejecting H₀, typically 0.05
Decision rule: Reject H₀ if p-value < α
Activity: Interpret the t-test results
How to report this result in a scientific paper:
“A two-tailed, one-sample t-test at α=0.05 showed that the mean pine needle length on the windward side (… mm, SD = …) [was/was not] significantly different from the expected 55 mm, t(…) = …, p = …”
For example
How would you assess this question using what we learned?
This is what we will do with the pine needles…
For example
How would you assess this question using what we learned?
# Now create a boxplot to visualize the difference in fish lengths between these lakes:
pine_df <- read_csv("data/pine_needles.csv")
# Create a boxplot comparing the two lakes
pine_wind_plot <- pine_df %>%
ggplot(aes(x = wind, y = length_mm, fill = wind)) +
geom_boxplot() +
labs(title = "Pine Needle Lengths by Wind Exposure",
x = "Position",
y = "Length (mm)",
fill = "Wind Position") +
scale_fill_manual(values = c("lee" = "forestgreen", "wind" = "skyblue"),
labels = c("lee" = "Leeward", "wind" = "Windward"))
pine_wind_plot
Practice Exercise 2: Formulating Hypotheses
For the following research questions about pine needles write the null and alternative hypotheses:
What are the hypotheses?
Ho =
Ha =
Now, let’s compare pine needle lengths between windward and leeward sides of trees.
Question: Is there a significant difference in needle length between the windward and leeward sides?
This requires a two-sample t-test.
Two-sample t-test compares means from two independent groups.
where:
Practice Exercise 3: Calculate summary statistics grouped by wind exposure
Before conducting the test, we need to understand the data for each group.
You need this and the graph to see what is going on ….
group_summary <- pine_df %>%
group_by(wind) %>%
summarize(
mean_length = mean(length_mm),
sd_length = sd(length_mm),
n = n(),
se_length = sd_length / sqrt(n)
)
print(group_summary)
# A tibble: 2 × 5
wind mean_length sd_length n se_length
<chr> <dbl> <dbl> <int> <dbl>
1 lee 20.4 2.45 24 0.500
2 wind 14.9 1.91 24 0.390
Practice Exercise 5: Using GGPLOT to get summary stats
GGplot also has code to make the mean and standard error plots we are interested in along whit a lot of others
# Assuming your dataframe is called df
pine_mean_se_plot <- ggplot(pine_df, aes(x = wind, y = length_mm, color = wind)) +
stat_summary(fun = mean, geom = "point") +
stat_summary(fun.data = mean_se, geom = "errorbar", width = 0.2) +
labs(title = "Mean Pine Needle Length by Wind Exposure",
x = "Wind Exposure",
y = "Mean Length (mm)") +
coord_cartesian(ylim = c(0,25))+
scale_color_manual(values = c("lee" = "forestgreen", "wind" = "skyblue"),
labels = c("lee" = "Leeward", "wind" = "Windward"))+
theme_classic()
pine_mean_se_plot
For a two-sample t-test, we need to check:
If assumptions are violated:
Practice Exercise 7: Test normality of windward pine needle lengths
qqplots
Note you need to test each groups separately…
# how do you make separate dataframes to do this on?
# Separate data by groups
windward_data <- pine_df %>% filter(wind == "wind")
leeward_data <- pine_df %>% filter(wind == "lee")
head(leeward_data)
# A tibble: 6 × 6
date group n_s wind tree_no length_mm
<chr> <chr> <chr> <chr> <dbl> <dbl>
1 3/20/25 cephalopods n lee 1 20
2 3/20/25 cephalopods n lee 1 21
3 3/20/25 cephalopods n lee 1 23
4 3/20/25 cephalopods n lee 1 25
5 3/20/25 cephalopods n lee 1 21
6 3/20/25 cephalopods n lee 1 16
Practice Exercise 9: Test normality of windward pine needle lengths
Shapiro-Wilk test
Note you need to test each groups separately…
Practice Exercise 11: Test normality of leeward pine needle lengths
Shapiro-Wilk test
Note you need to test each groups separately…
Practice Exercise 12: Test Normality at one time
There are always a lot of ways to do this in R
# there are always two ways
# Test for normality using Shapiro-Wilk test for each wind group
# All in one pipeline using tidyverse approach
normality_results <- pine_df %>%
group_by(wind) %>%
summarize(
shapiro_stat = shapiro.test(length_mm)$statistic,
shapiro_p_value = shapiro.test(length_mm)$p.value,
normal_distribution = if_else(shapiro_p_value > 0.05, "Normal", "Non-normal")
)
# Print the results
print(normality_results)
# A tibble: 2 × 4
wind shapiro_stat shapiro_p_value normal_distribution
<chr> <dbl> <dbl> <chr>
1 lee 0.955 0.343 Normal
2 wind 0.961 0.451 Normal
Practice Exercise 13: Test equal variances
Levenes test can be done on the original dataframe
# Method 1: Using car package's leveneTest
# This is often preferred as it's more robust to departures from normality
levene_result <- leveneTest(length_mm ~ wind, data = pine_df)
print("Levene's Test for Homogeneity of Variance:")
[1] "Levene's Test for Homogeneity of Variance:"
Levene's Test for Homogeneity of Variance (center = median)
Df F value Pr(>F)
group 1 1.2004 0.2789
46
Now we can compare the mean pine needle lengths between windward and leeward sides.
Ho: μ₁ = μ₂ (The mean needle lengths are equal)
Ha: μ₁ ≠ μ₂ (The mean needle lengths are different)
Deciding between:
Standard t-test (equal variances)
Welch’s t-test (unequal variances)
Note the Levenes Test should be NOT SIGNIFICANT - What is the null hypothesis
Levene's Test for Homogeneity of Variance (center = median)
Df F value Pr(>F)
group 1 1.2004 0.2789
46
Now we can do a two sample TTEST
Calculate t-statistic manually (optional)
YOUR CODE HERE:
t = (mean1 - mean2) / sqrt((s1^2/n1) + (s2^2/n2))
Tip
# YOUR TASK: Conduct a two-sample t-test
# Use var.equal=TRUE for standard t-test or var.equal=FALSE for Welch's t-test
# Standard t-test (if variances are equal)
t_test_result <- t.test(length_mm ~ wind, data = pine_df, var.equal = TRUE)
print("Standard two-sample t-test:")
[1] "Standard two-sample t-test:"
Two Sample t-test
data: length_mm by wind
t = 8.6792, df = 46, p-value = 3.01e-11
alternative hypothesis: true difference in means between group lee and group wind is not equal to 0
95 percent confidence interval:
4.224437 6.775563
sample estimates:
mean in group lee mean in group wind
20.41667 14.91667
Interpret the results of the two-sample t-test
What can we conclude about the needle lengths on windward vs. leeward sides?
How to report this result in a scientific paper:
“A two-tailed, two-sample t-test at α=0.05 showed [a significant/no significant] difference in needle length between windward (M = …, SD = …) and leeward (M = …, SD = …) sides of pine trees, t(…) = …, p = ….”
Interpret the results of the two-sample t-test
What can we conclude about the needle lengths on windward vs. leeward sides?
How to report this result in a scientific paper:
“A two-tailed, two-sample t-test at α=0.05 showed [a significant/no significant] difference in needle length between windward (M = …, SD = …) and leeward (M = …, SD = …) sides of pine trees, t(…) = …, p = ….”
Common assumptions for t-tests:
What can we do if our data violates these assumptions?
Alternatives when assumptions are violated:
In this activity, we’ve:
Key takeaways: