Reputation: 161
I would like to return all numbers with 3 significant digits after the decimal, even if the third digit is zero.
For instance suppose I have
x <- 0.8579
y <- 0.21
z <- 924894.2595
Then if I do
x <- signif(x, digits=3)
y <- signif(y, digits=3)
z <- signif(z, digits=3)
I get x = 0.857 y=0.21 and z=924894
This is almost what I want. What i actually want is
x = 0.857 y=0.210 and z=924894
I have tried using
format(round(x,3), digits=3)
But doing this I get
x = 0.857 y=0.210 and z=924894.259
So now I have an issue on z, since I actually want z=924894
.
Does anyone know of an answer in between to solve my issue?
Upvotes: 0
Views: 846
Reputation: 160417
Your expected "signif digits" for 924894 is not correct, though, since it is showing 6 signif digits. If you want to "violate" that technicality, then perhaps
vec <- c(0.857,0.210,924894.259)
dig <- 3
sprintf(paste0("%0.", ifelse(vec >= (10^dig), "0", dig), "f"), vec)
# [1] "0.857" "0.210" "924894"
(I'm being a little sloppy with ifelse
here: technically, "0"
is character and dig
is numeric/integer. This should be discouraged in general, and is enforced by dplyr::if_else
and data.table::fifelse
. This might mean that the return value from the ifelse
expression may be character
(if anything is large enough) or integer
/numeric
(if nothing is large enough); fortunately, however, paste0
will deal with it exactly the same, so the slop of class-imprecision is acceptable here. If I wanted to be thorough, I'd use as.character(dig)
instead.)
An alternative, that reacts to the apparent scale of each number individually:
vec <- c(0.857,0.210,924894.259,1)
sprintf(paste0("%0.", pmax(floor(3 - log(abs(vec)+0.001, 10)), 0), "f"), vec)
# [1] "0.857" "0.210" "924894" "1.00"
Upvotes: 4