Statistical Functions
Reviewed & published by Brayan K
Statistical functions are R's built-in toolkit for describing and testing data — means, spread, correlation, distributions, and hypothesis tests — all available in base R with no packages.
Part of the free R course at LearnCodingFast — hands-on lessons with worked examples and the output they print, plus practice exercises and a quick quiz.
By the end of this lesson you'll compute summary statistics, measure correlation between variables, run a t-test and read its p-value, and generate reproducible random numbers.
What You'll Learn in This Lesson
- Central tendency with mean() and median()
- Spread with sd(), var(), range(), and quantile()
- Correlation between two variables with cor()
- Category counts and proportions with table()
- Comparing groups with a t-test and p-value
- Reproducible random numbers with set.seed()
1️⃣ Summary Statistics
The core descriptors: mean() and median() for the center, sd() and var() for spread, and quantile() for percentiles.
# Base R is a statistics powerhouse — these need no packages.
x <- c(4, 8, 15, 16, 23, 42)
mean(x) # average -> [1] 18
median(x) # middle value -> [1] 15.5
sd(x) # std deviation -> [1] 13.49...
var(x) # variance -> [1] 182
range(x) # min and max -> [1] 4 42
quantile(x, 0.25) # 25th percentile -> 25%: 9.752️⃣ Correlation, summary(), and Categories
cor() measures how two variables move together, summary() prints a six-number overview, and table() / prop.table() count and proportion categories.
# Relationships between variables.
study <- c(2, 4, 6, 8, 10)
score <- c(50, 58, 71, 79, 92)
cor(study, score) # correlation, -1 to 1 -> [1] 0.9966...
# A full numeric summary in one call:
summary(score) # min, quartiles, mean, max
# Counting and proportions on a category:
grades <- c("A", "B", "A", "C", "A", "B")
table(grades) # counts
prop.table(table(grades)) # proportions3️⃣ Hypothesis Tests and Random Numbers
A t.test() compares two groups' means and reports a p-value (below 0.05 = significant). rnorm() draws random values; set.seed() makes them reproducible.
# A t-test asks: are two groups' means significantly different?
group_a <- c(20, 22, 19, 24, 21)
group_b <- c(28, 30, 27, 31, 29)
result <- t.test(group_a, group_b)
result$p.value # tiny p-value -> strong evidence of a difference
# -> [1] 0.000134 (far below 0.05)
# Random numbers for simulation (set.seed makes it reproducible):
set.seed(42)
round(rnorm(3, mean = 100, sd = 15), 1) # 3 draws from a normal distYour turn. Fill in the ___ blank, run it, and compare with the expected output.
# 🎯 YOUR TURN — replace each ___ then run it.
heights <- c(160, 172, 168, 181, 159, 175)
# 1) Print the mean and standard deviation, each rounded to 1 decimal
cat("Mean:", round(mean(heights), 1), "\n")
cat("SD:", round(___(heights), 1), "\n") # 👉 replace ___ with sd
# 2) Print the median
cat("Median:", median(heights), "\n")
# ✅ Expected output:
# Mean: 169.2
# SD: 8.6
# Median: 170Mini-Challenge: Describe a Dataset
Write it from the outline, run it, and check it against the example output. Computing several descriptors at once is exactly how you'd profile a new variable.
# 🎯 MINI-CHALLENGE: describe a dataset.
#
# Given:
# prices <- c(12, 15, 11, 22, 18, 30, 14, 25)
#
# 1. Print the mean and median.
# 2. Print the standard deviation, rounded to 2 decimals.
# 3. Print the interquartile range with IQR(prices).
# 4. Print how many prices are above the mean
# (hint: sum(prices > mean(prices))).
#
# ✅ Example output:
# Mean: 18.375 Median: 16.5
# SD: 6.5
# IQR: 9.75
# Above mean: 3
# your code hereCommon Errors (and the fix)
- mean()/sd() return NA — missing values in the data. Add na.rm = TRUE to skip them.
- cor() errors or gives NA — non-numeric input or NAs. Ensure both vectors are numeric and pass use = "complete.obs".
- Over-reading a p-value — "significant" doesn't mean "large" or "important". Report effect size and plot the data too.
- Random results change each run — call set.seed() before random functions for reproducibility.
Pro Tips
- 💡 Always visualise: stats can hide the shape of data — pair them with a histogram or scatter plot.
- 💡 summary() on a data frame: profiles every column at once, a great first look at new data.
- 💡 cor() on a matrix: cor(df_numeric) gives a full correlation matrix between all numeric columns.
📋 Quick Reference — Statistics
| Task | R Syntax |
|---|---|
| Center | mean(x) ; median(x) |
| Spread | sd(x) ; var(x) ; IQR(x) |
| Percentile | quantile(x, 0.9) |
| Correlation | cor(x, y) |
| Compare means | t.test(a, b) |
| Reproducible random | set.seed(1); rnorm(n) |
🎉 Lesson Complete!
- ✅ mean(), median(), sd() describe data
- ✅ cor() measures how variables move together
- ✅ summary() and table() profile data fast
- ✅ t.test() compares means; a p-value < 0.05 is significant
- ✅ set.seed() makes random results reproducible
Practice quiz
Which function computes the average of a numeric vector?
- median()
- mean()
- sum()
- mode()
Answer: mean(). mean() returns the arithmetic average.
Which function measures spread as the standard deviation?
- sd()
- range()
- var()
- IQR()
Answer: sd(). sd() returns the standard deviation; var() returns the variance.
What does cor(x, y) return for two numeric vectors?
- Their covariance
- Their sum
- A correlation between -1 and 1
- A p-value
Answer: A correlation between -1 and 1. cor() measures linear association on a -1 to 1 scale.
Which function counts occurrences of each category?
- mean()
- summary()
- quantile()
- table()
Answer: table(). table() tallies counts; prop.table() turns them into proportions.
In a t.test() result, what does a p-value below 0.05 conventionally indicate?
- Statistically significant evidence of a difference
- No difference at all
- A coding error
- A large effect size
Answer: Statistically significant evidence of a difference. Below 0.05 is treated as significant, though it says nothing about effect size.
Which function makes random number generation reproducible?
- rnorm()
- set.seed()
- runif()
- sample()
Answer: set.seed(). set.seed() fixes the random sequence so results repeat.
How do you compute the mean when the vector contains NA?
- mean(x, skip = TRUE)
- mean(na.omit)
- mean(x, na.rm = TRUE)
- mean(x, drop = NA)
Answer: mean(x, na.rm = TRUE). na.rm = TRUE drops NA values before computing the mean.
Which function returns the value at a given percentile?
- quantile()
- median()
- var()
- cor()
Answer: quantile(). quantile(x, 0.25) returns the 25th percentile.
What does summary() print for a numeric vector?
- Only the mean
- The correlation matrix
- Min, quartiles, median, mean, and max
- A p-value
Answer: Min, quartiles, median, mean, and max. summary() gives a six-number overview of the distribution.
Which function draws random values from a normal distribution?
- sample()
- runif()
- table()
- rnorm()
Answer: rnorm(). rnorm() draws from a normal distribution given a mean and sd.
Continue this course
- Previous: Joining Data
- Next: Data Types & Classes — numeric, character, logical and complex — plus class(), typeof() and coercion
- Quick reference: R cheat sheet › Stats & Models
Frequently asked questions
What summary statistics does base R provide out of the box?
A lot — and with no packages. mean() and median() give central tendency; sd() and var() measure spread; range(), min(), and max() give extremes; quantile() and IQR() describe the distribution's shape; and summary() prints a tidy six-number overview of any numeric vector. For categorical data, table() counts each category and prop.table() turns those counts into proportions. R was built by statisticians, so these are first-class, reliable, and fast.
What does correlation tell me, and how do I compute it?
Correlation, computed with cor(x, y), measures how strongly two numeric variables move together, on a scale from -1 to 1. A value near 1 means they rise together, near -1 means one rises as the other falls, and near 0 means little linear relationship. It's a quick way to spot associations — but remember correlation is not causation, and it only captures LINEAR relationships, so always plot your data too.
What is a p-value and how do I read a t-test result?
A t-test (t.test()) checks whether the means of two groups differ more than you'd expect by chance. The p-value is the probability of seeing a difference this large if there were truly no difference. By convention, a p-value below 0.05 is treated as 'statistically significant' evidence of a real difference. Read it cautiously: a small p-value suggests an effect exists, but says nothing about how big or important that effect is.
How do I generate random numbers reproducibly?
Functions like rnorm() (normal distribution), runif() (uniform), and sample() (random selection) generate random values. Because they're random, you'd get different results each run — which makes debugging and sharing hard. set.seed(number) fixes the random sequence so everyone running your code gets the same 'random' numbers. Always set.seed() before random operations in analyses you want to be reproducible.