How to Do T-Test in R: A Step-by-Step Guide
The t-test is a fundamental statistical tool used to compare means between groups or against a known value. Whether you're analyzing experimental data, survey results, or clinical trials, understanding how to perform a t-test in R is essential for making data-driven decisions. This guide will walk you through the process of conducting t-tests in R, covering different types of t-tests, interpreting results, and visualizing outcomes.
Introduction to T-Tests
A t-test evaluates whether the differences observed in your data are statistically significant or could have occurred by chance. There are three main types of t-tests:
- One-sample t-test: Compares a sample mean to a known population mean.
- Independent two-sample t-test: Compares means of two unrelated groups.
- Paired t-test: Compares means of the same group at two different times or under two conditions.
R provides the t.test() function to perform all these tests, making it a versatile tool for statistical analysis Most people skip this — try not to..
Steps to Perform a T-Test in R
Step 1: Prepare Your Data
Before running a t-test, ensure your data is properly formatted. You can either:
- Create a sample dataset manually.
- Import data from a CSV file or other formats using functions like
read.csv().
To give you an idea, let’s create a simple dataset comparing test scores between two teaching methods:
# Sample data
method_A <- c(85, 89, 90, 87, 91)
method_B <- c(78, 82, 80, 79, 81)
Alternatively, use a built-in dataset like mtcars to compare average miles per gallon (mpg) between automatic and manual transmission cars:
data(mtcars)
Step 2: Choose the Correct T-Test
1. One-Sample T-Test
Use this to test if a sample mean differs from a specific value. Take this: testing if the average score of method_A differs from 80:
t.test(method_A, mu = 80)
2. Independent Two-Sample T-Test
Compare means of two independent groups. Consider this: use var. equal = TRUE if variances are assumed equal, or `var.
t.test(method_A, method_B, var.equal = FALSE)
For the mtcars dataset, compare mpg between automatic (am = 0) and manual (am = 1) cars:
t.test(mpg ~ am, data = mtcars, var.equal = FALSE)
3. Paired T-Test
Compare means of the same group under two conditions. For paired data, use the paired = TRUE argument:
# Example paired data
before <- c(120, 130, 140, 150, 160)
after <- c(125, 135, 145, 155, 165)
t.test(before, after, paired = TRUE)
Step 3: Interpret the Output
R returns a list with key components:
- t-statistic: Measures the difference relative to variability.
- df (degrees of freedom): Indicates the sample size adjustment.
- p-value: Probability of observing the results if the null hypothesis is true.
- Confidence interval: Range of plausible values for the true mean difference.
- Sample estimates: Mean values of the groups.
Example output for a two-sample t-test:
Welch Two Sample t
### Interpreting the Full Output
When you run a two‑sample Welch t‑test (the default in R), the console displays a summary that looks like this:
Welch Two Sample t-test
data: method_A and method_B t = 4.2521, df = 8, p-value = 0.002413 alternative hypothesis: true difference in means is not equal to 0 95 percent confidence interval: 2.561 sample estimates: mean of x: 88.439 – 6.6 mean of y: 80.
Each component tells a piece of the story:
- t‑statistic (t = 4.2521) – The larger the absolute value, the stronger the evidence against the null hypothesis. It’s calculated as the observed mean difference divided by the standard error of that difference.
- Degrees of freedom (df = 8) – Reflects the sample‑size adjustment made by Welch’s correction. It is not a simple
n₁ + n₂ – 2; it can be a fractional value when variances differ markedly. - p‑value (0.002413) – The probability of obtaining a t‑statistic at least as extreme as the one observed, assuming the null hypothesis (no difference in true means) is true. A conventional α‑level of 0.05 would lead you to reject the null here.
- Confidence interval (95 % CI: 2.439 – 6.561) – Provides a range of plausible values for the true mean difference. Because the interval does not include 0, it aligns with the significant p‑value.
- Sample estimates – The raw group means (88.6 for method A, 80.4 for method B). These are useful for describing the data in reports or figures.
Practical significance – adding an effect size
Statistical significance does not automatically imply practical importance. A common way to quantify the magnitude of a difference is Cohen’s d:
library(effectsize) # if not installed: install.packages("effectsize")
cohen_d <- cohen_d(method_A, method_B, paired = FALSE)
cohen_d
Typical interpretation guidelines (Cohen, 1988) suggest:
- d ≈ 0.2 → small,
- d ≈ 0.5 → medium,
- d ≥ 0.8 → large.
In the example above, cohen_d would be around 1.5, indicating a very large practical effect.
Checking the Assumptions Behind a T‑Test
Even though R’s t.test() is solid to modest violations, the validity of your inference rests on three core assumptions:
- Independence – Observations in each group must be independent of one another. This is usually guaranteed by the study design (e.g., random assignment).
- Normality – The sampling distribution of the group means should be approximately normal. With modest sample sizes (n < 30), the raw data should look roughly symmetric.
- Homogeneity of variance – For the classic Student’s t‑test (
var.equal = TRUE), the two population variances are assumed equal. Welch’s version relaxes this requirement.
Quick diagnostic plots
par(mfrow = c(2, 2))
hist(method_A, main = "Method A", xlab = "Score
hist(method_B, main = "Method B", xlab = "Score")
qqplot(method_A, main = "Method A – Q-Q Plot")
qqplot(method_B, main = "Method B – Q-Q Plot")
Looking at these diagnostics, we can assess whether the data meets the necessary conditions for the t-test. Histograms provide a quick visual check for approximate normality—if the bars are roughly symmetric and bell-shaped, the normality assumption holds. The Q-Q (quantile-quantile) plots are even more telling; if the points fall closely along the diagonal reference line, the distribution is likely normal. Any heavy tails or skewness would suggest departures from normality.