This is not a bug. Your premise is that trim*n should not be truncated to an 
integer. However, you cannot trim a fraction of an observation. If you have 15 
observations and request a 5% trim, you are asking to remove 0.75 observations 
from each end. Because observations are discrete, R must choose an integer. R 
chooses floor(0.75) = 0.  One could have chosen round instead of floor, but 
both are reasonable choices.

Statgraphics is calculating an interpolated or fractional trimmed mean, which 
is a different statistical estimator than the standard discrete trimmed mean.

Ravi

________________________________
From: R-devel <[email protected]> on behalf of JUAN CARLOS GAVIRIA 
CHAVERRA via R-devel <[email protected]>
Sent: Thursday, July 30, 2026 15:09
To: [email protected] <[email protected]>
Subject: [Rd] Bug report: mean(..., trim) silently applies integer truncation 
when k = trim * n is non-integer


      External Email - Use Caution



Subject: Bug report: mean(..., trim) silently applies integer truncation
when k = trim * n is non-integer

Dear R Core Team,

I am writing to report a structural limitation in the mean(..., trim)
function in base R that has gone undetected for over three decades and
affects the overwhelming majority of practical uses of trimmed mean
computation.

--- NARRATIVE JUSTIFICATION ---

For more than three decades, researchers in econometrics, finance, public
health, environmental sciences and many other fields have trusted that
mean(..., trim = 0.05) applies exactly 5% trimming to their data. This
implicit trust is precisely what makes the integer truncation problem so
consequential: it affects any combination of n and trim that produces a
non-integer k = trim * n, which represents the overwhelming majority of
practical uses.

The problem has two manifestations. When k < 1 (Type A), R reduces k to
zero and returns the arithmetic mean, completely ignoring the requested
trimming without any warning. When k > 1 but non-integer (Type B), R trims
fewer observations than requested, with losses reaching 33% of the nominal
value, also without any warning.

The scope extends beyond direct users: packages such as WRS2 (hundreds of
thousands of downloads) use mean(x, tr) internally, propagating the
distortion silently to confidence intervals and hypothesis tests.

We are not requesting a change in the existing algorithm. We are requesting
transparency: a warning when the effective trimming differs from the
requested trimming, preserving complete backward compatibility.

The existence of sgmean as a separate package (CRAN v0.1.1) should not be
interpreted as a permanent solution. sgmean and mean(..., trim) produce
identical results whenever k = trim * n is an exact integer. The only
difference is that sgmean also handles non-integer k correctly. Directing
users to install a separate package to obtain the result that base R's own
mean() function should produce is not a solution � it is a transfer of
responsibility. The R Core Team has the unique opportunity to resolve this
at the root, ensuring that every R user benefits from correct trimmed mean
computation.

--- REPRODUCIBLE EXAMPLE ---

x <- c(850, 920, 980, 1050, 1120, 1180, 1250,
       1320, 1400, 1480, 1550, 1700, 1850, 2100, 8500)

# TYPE A: k < 1
cat('k requested:', 0.05 * 15, '| k applied:', floor(0.05 * 15), '\n')
# k requested: 0.75 | k applied: 0
mean(x)               # [1] 1816.667
mean(x, trim = 0.05)  # [1] 1816.667 -- SAME: no trimming applied
# Expected (Statgraphics): 1499.074

# TYPE B: k > 1, non-integer
cat('k requested:', 0.10 * 15, '| k applied:', floor(0.10 * 15), '| Loss:
33.3%\n')
mean(x, trim = 0.10)  # [1] 1376.923
# Expected (Statgraphics): 1365.833

--- CROSS-PLATFORM EVIDENCE ---

This bug exists identically in Python's scipy.stats.trim_mean, confirming
that integer truncation in trimmed mean computation is a systematic
limitation shared across the two most widely used scientific computing
environments in the world.

Software              | Type A (k=0.75) | Type B (k=1.50)
R base mean(...,trim) | 1816.667 (wrong)| 1376.923 (wrong)
Python trim_mean      | 1816.667 (wrong)| 1376.923 (wrong)
Statgraphics          | 1499.074 (correct) | 1365.833 (correct)
sgmean CRAN v0.1.1    | 1499.074 (correct) | 1365.833 (correct)

--- PROPOSED SOLUTION ---

Minimum fix: add a warning in mean.default() when k = trim * n is
non-integer:

if (k != floor(k)) {
  if (floor(k) == 0L) {
    warning(paste0('trim * length(x) = ', k, ' < 1. ',
      'No trimming applied (effective trim = 0%). ',
      'Consider sgmean::sgmean() for proportional trimming.'))
  } else {
    warning(paste0('trim * length(x) = ', k, ' is not an integer. ',
      'Effective trimming: ', round(floor(k)/length(x)*100,1), '% ',
      '(requested: ', trim*100, '%, loss: ',
      round((k-floor(k))/k*100,1), '%).'))
  }
}

--- AVAILABLE SOLUTION ---

A corrected implementation is available on CRAN:
install.packages('sgmean')
DOI: https://doi.org/10.32614/CRAN.package.sgmean
GitHub: 
https://github.com/jcarlosgaviria/sgmean<https://github.com/jcarlosgaviria/sgmean>

--- R VERSION ---

R version 4.5.3 (2026-03-11 ucrt)
Platform: x86_64-w64-mingw32/x64

Best regards,

Juan C. Gaviria-Chaverra
ALIADO-Analytics and Research for Decision Making
Department of Industrial Engineering, Universidad de Antioquia
Medellin, Colombia
[email protected]
ORCID: 0009-0008-9403-416X
GitHub: https://github.com/jcarlosgaviria<https://github.com/jcarlosgaviria>

--


"La informaci�n aqu� contenida es para uso exclusivo de la persona o
entidad de destino. Est� estrictamente prohibida su utilizaci�n, copia,
descarga, distribuci�n, modificaci�n y/o reproducci�n total o parcial, sin
el permiso expreso de Universidad de Antioquia, pues su contenido puede ser
de car�cter confidencial y/o contener material privilegiado. Si usted
recibi� esta informaci�n por error, por favor contacte en forma inmediata a
quien la envi� y borre este material de su computador. Universidad de
Antioquia no es responsable por la informaci�n contenida en esta
comunicaci�n, el directo responsable es quien la firma o el autor de la
misma."

______________________________________________
[email protected] mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel<https://stat.ethz.ch/mailman/listinfo/r-devel>

        [[alternative HTML version deleted]]

______________________________________________
[email protected] mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel

Reply via email to