Isn’t that the correct outcome? The user can change the number of digits if they want to see small values…
-- Change your thoughts and you change the world. --Dr. Norman Vincent Peale > On Dec 17, 2023, at 12:11 AM, Steve Martin <stevemartin...@gmail.com> wrote: > > Zapping a vector of small numbers to zero would cause problems when > printing the results of summary(). For example, if > zapsmall(c(2.220446e-16, ..., 2.220446e-16)) == c(0, ..., 0) then > print(summary(2.220446e-16), digits = 7) would print > Min. 1st Qu. Median Mean 3rd Qu. Max. > 0 0 0 0 0 0 > > The same problem can also appear when printing the results of > summary.glm() with show.residuals = TRUE if there's little dispersion > in the residuals. > > Steve > >> On Sat, 16 Dec 2023 at 17:34, Gregory Warnes <g...@warnes.net> wrote: >> >> I was quite suprised to discover that applying `zapsmall` to a scalar value >> has no apparent effect. For example: >> >>> y <- 2.220446e-16 >>> zapsmall(y,) >> [1] 2.2204e-16 >> >> I was expecting zapsmall(x)` to act like >> >>> round(y, digits=getOption('digits')) >> [1] 0 >> >> Looking at the current source code, indicates that `zapsmall` is expecting a >> vector: >> >> zapsmall <- >> function (x, digits = getOption("digits")) >> { >> if (length(digits) == 0L) >> stop("invalid 'digits'") >> if (all(ina <- is.na(x))) >> return(x) >> mx <- max(abs(x[!ina])) >> round(x, digits = if (mx > 0) max(0L, digits - as.numeric(log10(mx))) >> else digits) >> } >> >> If `x` is a non-zero scalar, zapsmall will never perform rounding. >> >> The man page simply states: >> zapsmall determines a digits argument dr for calling round(x, digits = dr) >> such that values close to zero (compared with the maximal absolute value) >> are ‘zapped’, i.e., replaced by 0. >> >> and doesn’t provide any details about how ‘close to zero’ is defined. >> >> Perhaps handling the special when `x` is a scalar (or only contains a single >> non-NA value) would make sense: >> >> zapsmall <- >> function (x, digits = getOption("digits")) >> { >> if (length(digits) == 0L) >> stop("invalid 'digits'") >> if (all(ina <- is.na(x))) >> return(x) >> mx <- max(abs(x[!ina])) >> round(x, digits = if (mx > 0 && (length(x)-sum(ina))>1 ) max(0L, digits - >> as.numeric(log10(mx))) else digits) >> } >> >> Yielding: >> >>> y <- 2.220446e-16 >>> zapsmall(y) >> [1] 0 >> >> Another edge case would be when all of the non-na values are the same: >> >>> y <- 2.220446e-16 >>> zapsmall(c(y,y)) >> [1] 2.220446e-16 2.220446e-16 >> >> Thoughts? >> >> >> Gregory R. Warnes, Ph.D. >> g...@warnes.net >> Eternity is a long time, take a friend! >> >> >> >> [[alternative HTML version deleted]] >> >> ______________________________________________ >> R-devel@r-project.org mailing list >> https://stat.ethz.ch/mailman/listinfo/r-devel [[alternative HTML version deleted]] ______________________________________________ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel