Statistical functions
TRIMMEAN
Matches all 131 recorded answers
Recorded: 131 workbook cells. How we measure this · See the Rust code
Local names in 40 languages
| Language | Name in Excel |
|---|---|
| Arabic | TRIMMEAN |
| Bulgarian | TRIMMEAN |
| Czech | TRIMMEAN |
| Danish | TRIMMIDDELVÆRDI |
| German | TRIMMEAN |
| Greek | TRIMMEAN |
| English (Australia) | TRIMMEAN |
| English (United Kingdom) | TRIMMEAN |
| English (United States) | TRIMMEAN |
| Spanish | MEDIA.ACOTADA |
| Estonian | TRIMMEAN |
| Finnish | KESKIARVO.TASATTU |
| French | MOYENNE.REDUITE |
| Hebrew | TRIMMEAN |
| Croatian | TRIMMEAN |
| Hungarian | RÉSZÁTLAG |
| Indonesian | TRIMMEAN |
| Italian | TRIMMEAN |
| Japanese | TRIMMEAN |
| Korean | TRIMMEAN |
| Lithuanian | TRIMMEAN |
| Latvian | TRIMMEAN |
| Norwegian | TRIMMET.GJENNOMSNITT |
| Dutch | GETRIMD.GEM |
| Polish | ŚREDNIA.WEWN |
| Portuguese (Brazil) | TRIMMEAN |
| Portuguese (Portugal) | MÉDIA.INTERNA |
| Romanian | TRIMMEAN |
| Russian | УРЕЗСРЕДНЕЕ |
| Slovak | TRIMMEAN |
| Slovenian | TRIMMEAN |
| Serbian (Latin) | TRIMMEAN |
| Swedish | TRIMMEDEL |
| Thai | TRIMMEAN |
| Turkish | KIRPORTALAMA işlevi |
| Ukrainian | TRIMMEAN |
| Vietnamese | TRIMMEAN |
| Chinese (Simplified) | TRIMMEAN |
| Chinese (Hong Kong) | TRIMMEAN |
| Chinese (Traditional) | TRIMMEAN |
Names from Microsoft's support site.
What it does
TRIMMEAN(array, percent)
TRIMMEAN(array, percent) returns the trimmed mean — the arithmetic mean of the data after
discarding an equal number of the largest and smallest values.
The trimming rule is the part that needs stating precisely, because it is not "discard
percent of the data". Microsoft documents it in two sentences: percent is "the fractional
number of data points to exclude from the calculation", and "TRIMMEAN rounds the number of
excluded data points down to the nearest multiple of 2". So with n numeric values:
total excluded = 2 · floor( n · percent / 2 )
excluded per end, k = floor( n · percent / 2 )
result = mean of the n − 2k values remaining after sorting
The documented example fixes the reading: with percent = 0.2 and 20 points, four points are
trimmed — two from the top and two from the bottom.
The rounding-down-to-an-even-count rule exists to keep the trim symmetric. An odd excluded
count would have to remove one more value from one end than the other, which would bias the
estimator; Excel would rather trim slightly less than trim asymmetrically. This is the right
choice, and it means the effective trimming fraction is generally below the requested
percent — a fact worth knowing before comparing TRIMMEAN results against a statistics
package that rounds differently. There is no universal convention here: implementations
variously round the per-end count down, round it to nearest, or interpolate between order
statistics, and they disagree on the same data by construction rather than by accident.
As an estimator, TRIMMEAN interpolates between two familiar ones:
percent | Result |
|---|---|
| 0 | AVERAGE(array) — no trimming |
| small | A robust mean: bounded influence from the tails |
large, n odd | approaches MEDIAN(array) |
Its breakdown point is the fraction trimmed from each end, k/n ≈ percent/2: that is the
proportion of arbitrarily corrupted observations the estimator tolerates before its value can be
driven anywhere. The mean has breakdown point 0; the median has ½. TRIMMEAN lets the caller
choose a point on that line, which is the whole reason robust location estimators exist (Tukey;
Huber, Robust Statistics; Hampel, Ronchetti, Rousseeuw & Stahel).
Note also what it is not: it is not a Winsorized mean, which replaces the extreme values with the nearest retained value rather than discarding them, and which therefore has a different variance and a different influence function. Excel offers no Winsorized mean.
Arguments
| Argument | Meaning | Required |
|---|---|---|
array | "The array or range of values to trim and average." | Yes |
percent | "The fractional number of data points to exclude from the calculation." | Yes |
Try it
Quirks
Result and edge cases
Returns Number.
percent = 0trims nothing and equalsAVERAGE(array). This should be an exact identity between two Excel surfaces, including in the last bits if both sum the same way — and it is therefore a good probe of whetherTRIMMEANreusesAVERAGE's accumulation.percentsmall enough thatn · percent < 2also trims nothing, because the floor of a quantity below 2, halved, is zero. So on a ten-point data set everypercentbelow0.2behaves identically topercent = 0. That is a large flat region that surprises people who expectpercent = 0.1to do something.- Ties at the trimming boundary. Trimming is by position in the sorted order, not by value, so when several observations tie at the cut point it does not matter which copies are removed — the retained multiset, and therefore the mean, is the same. This is a real robustness of the definition and it is worth knowing that no tie-breaking rule is needed.
n = 1with any admissiblepercentretains the single value.- Sort order and non-finite values. The definition depends on an ordering of the data. What happens with values that do not order conventionally, and how blanks and text interact with the sort, is undocumented.
arrayempty is undocumented; the engine's battery reports a value error for an empty range.
Errors
As documented on Microsoft's TRIMMEAN page:
| Error | Documented condition |
|---|---|
#NUM! | percent < 0 or percent > 1. |
That is the whole documented table. Undocumented, and therefore open: an empty array; the
percent = 1 even-n case that leaves no data; non-numeric contents of array; and a
nonnumeric percent.
Errors in either argument propagate under the universal coercion rule. The Handbook has not verified any of this against Excel.
How to implement
Numerical notes
TRIMMEAN is the rare statistical surface whose difficulty is combinatorial rather than
floating-point. The value is a mean of a subset, so once the subset is chosen the arithmetic is
ordinary; almost everything that can go wrong goes wrong in choosing it.
Selection, not sorting. A full sort is O(n log n) and is the obvious implementation, but the
function only needs the k-th smallest and k-th largest cut points; a two-sided quickselect
(Hoare's algorithm, or nth_element) does the job in expected linear time, and introselect
guarantees it. For the array-lifted case — many percent values against one array — sorting
once and reusing the order is obviously right, and an implementation that re-selects per element
does needless work.
The count arithmetic is integer arithmetic and should stay that way. floor(n · percent / 2)
computed in floating point can land on the wrong integer when n · percent is within rounding of
an even number: n = 20, percent = 0.2 gives n·percent = 4.000000000000001 or
3.9999999999999996 depending on how the product is formed, and the second rounds down to a
different trim count. This is a real, reachable discontinuity — one ulp in the product changes how
many observations are discarded, and therefore changes the answer by a visible amount rather than
by a rounding error. Any implementation of this function needs a defensible rule for forming the
count, and the Handbook does not know what Excel's is.
Summation of the retained values. The ordinary accumulation question applies: naive
left-to-right summation of a long retained set accumulates error proportional to n; pairwise or
compensated (Kahan/Neumaier) summation reduces it. One pleasant side effect of trimming is that
the retained values span a narrower range than the original data, so the sum is generally better
conditioned than AVERAGE's on the same input.
Sorting does not lose accuracy, but it does fix an order, and summing in sorted order is a
different floating-point sum from summing in sheet order. So TRIMMEAN(array, 0) and
AVERAGE(array) are mathematically identical and need not be identical in the last bit — which
makes their comparison a probe rather than a tautology.
The accuracy and convention behaviour of Excel's statistical procedures is a documented topic in the published literature; Morten Welinder's work on Gnumeric's statistical functions is the most concrete account, and the assessments by Knüsel and by McCullough & Wilson are the standing evaluations. The Handbook names them as the right reading and does not assert from them what any current build does.
Rust code
Show the CalcFunc source of this function
Quoted from the public repository DnaCalc/DnaCalc, crates calc-func and calc-fml, at commit 9e1884369a67. Comments are the source's own. A kernel shared with other functions appears once, on its module page.
TRIMMEAN · 5 lines · calc-func/src/catalogue/statistics.rs on GitHub49 trimmean "TRIMMEAN" (2, 2) [R "array", V "percent"] |s, a, sv| {
let mut values = list(s, a, 0, sv)?;
let percent = num(s, a, 1)?;
out(s, k::moment_stats_family::trimmean_kernel(&mut values, percent))
}
trimmean_kernel · 37 lines · calc-func/src/ported/moment_stats_family.rs on GitHubpub(crate) fn trimmean_kernel(values: &mut [f64], percent: f64) -> Result<f64, WorksheetErrorCode> {
if !percent.is_finite() {
return Err(WorksheetErrorCode::Value);
}
// A percent of 1 is #NUM! too, though Microsoft's page names only one above 1 (Excel
// 16.0.20430, 2026-10-25, dc-6au: `=TRIMMEAN(A1:A3,1)` #NUM!, `=TRIMMEAN(A1:A3,0.9999999999)` 2).
if !(0.0..1.0).contains(&percent) {
return Err(WorksheetErrorCode::Num);
}
if values.is_empty() {
return Err(WorksheetErrorCode::Num);
}
let mut sorted = values.to_vec();
sorted.sort_by(|a, b| a.partial_cmp(b).unwrap_or(std::cmp::Ordering::Equal));
let to_trim = (percent * values.len() as f64).floor() as usize;
let each_side = to_trim / 2;
if each_side * 2 >= values.len() {
return Err(WorksheetErrorCode::Num);
}
// Excel adds the kept values in their own order, not the sorted order (dc-j9k: 20 of 20
// TRIMMEAN readings in the catalogue oracle's sheet dcj9k_statistics; the sorted sum
// matched 18): each of the `each_side` smallest and largest values is left out once.
let mut trimmed: Vec<f64> = sorted[..each_side]
.iter()
.chain(sorted[sorted.len() - each_side..].iter())
.copied()
.collect();
let mut total = 0.0;
for value in values.iter() {
if let Some(at) = trimmed.iter().position(|t| t == value) {
trimmed.swap_remove(at);
} else {
total += value;
}
}
Ok(total / (values.len() - 2 * each_side) as f64)
}
Kernels shared with other functions
listcatalogue/statistics
Argument and result plumbing
No implementation has been published with a Handbook test suite for this function.
Version differences
No comparison between specific Excel builds is recorded here yet. This does not establish that all builds behave alike.
Alternatives
Relationships
AVERAGEis thepercent = 0case and the estimatorTRIMMEANis a robustification of.MEDIANis the limit as the trimming approaches everything, for oddn.TRIMMEANwith a largepercentandMEDIANshould agree exactly on odd-length data whenever the trim leaves a single value.AVERAGEIF/AVERAGEIFStrim by predicate rather than by rank; they are the other way to exclude outliers and they are not robust in the breakdown-point sense, because a predicate chosen from the data is itself corruptible.QUARTILE.EXC/PERCENTILE.INC/SMALL/LARGEare the other order-statistic surfaces, and the interpolation conventions they disagree about are the same family of convention disagreements that makeTRIMMEANnon-portable across statistics packages.STEYX,SKEW,SKEW.P,KURTshare this surface's implementing module in the reference engine — a module of moment statistics with one order statistic sitting inside it.- Confused with: a Winsorized mean (see above), and with "remove outliers then average", which is a data-dependent rule with no fixed breakdown point.
Named variants
No named variants are recorded yet.
Suggest a correction or contribute an implementation · For agents