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
