Hello, Though I agree with what Ravi and Gabriel have said, I believe the OP might have a point.
Inline. -------- Mensagem reencaminhada -------- Assunto: [Rd] Bug report: mean(..., trim) silently applies integer truncation when k = trim * n is non-integer Data: Thu, 30 Jul 2026 14:09:05 -0500 De: JUAN CARLOS GAVIRIA CHAVERRA via R-devel <[email protected]> Responder-Para: JUAN CARLOS GAVIRIA CHAVERRA <[email protected]> Para: [email protected] 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. There are base functions whose documentation mentions coercion to integer by truncation. From ?dim section Arguments > value > for the default method, either NULL or a numeric vector, which is coerced to integer (by truncation). And from ?mean, section Value > If trim is non-zero, a symmetrically trimmed mean is computed with a fraction of trim observations deleted from each end before the mean is computed. A warning is too much, it would seem there was something wrong or worrying going on, when there isn't. But the documentation could include that the trimmed fraction is coerced to integer and how it is done. Maybe > If trim is non-zero, a symmetrically trimmed mean is computed with a fraction of trim observations deleted from each end before the mean is computed. The fraction is coerced to integer (by truncation). Hope this helps, Rui Barradas 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 --- 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 -- "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 [[alternative HTML version deleted]] ______________________________________________ [email protected] mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
