x <- iris$Sepal.Length
mean(x) # arithmetic mean[1] 5.843333
median(x) # middle value (robust to outliers)[1] 5.8
# mode: the most frequent value (base R)
freq <- table(x)
as.numeric(names(freq)[which.max(freq)])[1] 5
Central tendency, variability and grouped summaries — mean, median, mode, range, IQR, variance and SD — the modern way with rstatix and base R
Learn to compute descriptive statistics in R — the measures of central tendency (mean, median, mode) and variability (range, interquartile range, variance, standard deviation) — with base R and the pipe-friendly rstatix get_summary_stats(), including grouped summaries and a quick visual.
June 23, 2026
July 7, 2026
mean(), median(), and the mode (most frequent value — no base function, so compute it from a frequency table).range()/min()/max(), the interquartile range IQR(), the variance var() and the standard deviation sd().rstatix::get_summary_stats() computes all of these at once, and by group with group_by().Descriptive statistics describe and summarise your data before you test anything — the shape of a distribution, where it is centred, and how spread out it is. They split into two families:
This lesson computes each with base R and with the pipe-friendly rstatix get_summary_stats(), using the built-in iris data.
The mean and median have base-R functions; the mode (most frequent value) does not, so we read it off a frequency table:
[1] 5.843333
[1] 5.8
[1] 5
The mean (5.84) and median (5.80) are close, indicating a fairly symmetric distribution; the mode is the single most common value.
Mean vs median. The mean uses every value, so it is pulled by outliers; the median is the middle value, so it is robust. When they diverge sharply, the distribution is skewed — a cue to check normality or consider a transformation.
[1] 4.3 7.9
[1] 1.3
[1] 0.6856935
[1] 0.8280661
The standard deviation (0.83) is the most reported measure of spread — the typical distance of a value from the mean, in the original units. The IQR (the middle 50%) is its robust counterpart, unaffected by extreme values.
rstatix::get_summary_stats() returns the common summaries in one tidy table — choose the set with type ("common", "mean_sd", "median_iqr", "full"):
# A tibble: 1 × 10
variable n min max median iqr mean sd se ci
<fct> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 Sepal.Length 150 4.3 7.9 5.8 1.3 5.84 0.828 0.068 0.134
The real power is per group — pipe group_by() first to summarise each species at once:
# A tibble: 3 × 5
Species variable n mean sd
<fct> <fct> <dbl> <dbl> <dbl>
1 setosa Sepal.Length 50 5.01 0.352
2 versicolor Sepal.Length 50 5.94 0.516
3 virginica Sepal.Length 50 6.59 0.636
This is the table behind every group comparison — the means and SDs you report alongside a t-test or ANOVA.
Numbers and a picture together. A boxplot shows the median, IQR and outliers per group; add the mean and jittered points:
Summarise a different variable or dataset. The sandbox boots on first Run.
Ask Prova “summarise my data — give me the mean, median, SD and IQR for each group, and a plot to go with it” — it answers with rstatix code you can run on your own data. The runtime is the judge. Ask Prova →
There is no mode() function for the most frequent value. Base R’s mode() returns the storage type of an object, not the statistical mode. Compute the statistical mode from a frequency table: names(which.max(table(x))).
Missing values give NA. mean(x), sd(x) and friends return NA if x contains NA. Add na.rm = TRUE (e.g. mean(x, na.rm = TRUE)); get_summary_stats() handles missing values for you.
You reported the variance instead of the SD. The variance is in squared units; the standard deviation (its square root) is in the original units and is what readers expect — report sd().
Use rstatix: data %>% group_by(grouping_var) %>% get_summary_stats(variable, type = "mean_sd"). It returns one row per group with the chosen statistics (count, mean, SD, median, IQR, etc.). This is the standard way to produce the descriptive table that accompanies a t-test or ANOVA.
The mean is the arithmetic average (sum ÷ count) and uses every value, so outliers pull it. The median is the middle value when sorted, so it is robust to outliers and skew. When they differ a lot, the distribution is skewed — the median is the better summary of “typical”.
There is no built-in statistical-mode function (mode() returns the object’s type). Build a frequency table and take the most frequent: names(which.max(table(x))). For a numeric vector wrap it in as.numeric().
Report the standard deviation in most contexts — it is the square root of the variance and is expressed in the original units, so it is directly interpretable as the typical distance from the mean. The variance (squared units) is mainly an intermediate quantity.
iris$Petal.Length, then a grouped get_summary_stats() by species. Fill the blank.Fill the blank with Species. For question 2, recall which measure is robust to the long tail of a skewed distribution.
For question 2: the median. Income is strongly right-skewed (a few very high earners), which inflates the mean; the median (the middle value) is unaffected by the long tail and better represents the typical person.
You can now compute descriptive statistics in R: central tendency (mean(), median(), and the mode from a frequency table) and variability (range(), IQR(), var(), sd()), or all of them at once — and by group — with rstatix::get_summary_stats(). Pair the table with a boxplot or histogram, and you have the summary that opens every analysis and accompanies every test.
Prove you can do it. Master the whole Statistical Assumptions in R series — track your path, build projects, and earn a certificate.
Go Pro — unlimited Prova on your own data and a verifiable certificate that proves the skill.
from $15/mo billed yearly
✓ You're Pro — keep going. The runtime is the judge.
Ready to level up?
Get new R & Python lessons by email
Practical, reproducible, no spam. Unsubscribe anytime.
Double opt-in. We never share your email.
Every result on this page was produced by the code shown, run at build time against a pinned R environment — edit any block and Run to reproduce it yourself.
@online{2026,
author = {},
title = {Descriptive {Statistics} in {R:} {Summarise} and {Describe}
{Your} {Data}},
date = {2026-06-23},
url = {https://www.datanovia.com/learn/biostatistics/assumptions/descriptive-statistics-in-r},
langid = {en}
}