unround() takes a rounded number and returns the range of
values that would have been rounded to it: a lower and an upper bound,
and whether each is inclusive. The default rounding method is
"up_or_down"; see Rounding for the others.
Arguments
- x
String or numeric. The rounded number. Must be a string unless
digitsis specified. A missing or infinitexhasNAbounds.- rounding
String. The rounding method assumed to have produced
x. Default is"up_or_down". See Rounding.- threshold
Numeric. For the
"*_from"methods, the point within a step at which rounding switches direction, in tenths of a step; greater than0and less than10. Default is5. Seeround_up_from().- digits
Integer. The number of decimal places in
x. Default isNULL, in which case it is counted from the stringx. Specify it if the number is already known, as a function that usesunround()as a helper would.- symmetric
Logical. If
TRUE, negative numbers are assumed to have been rounded like their absolute values under"up","down", and the"*_from"methods. Default isFALSE. Must not beTRUEwith a"ties_*"method; seereround().
Value
A tibble with the columns range, rounding, lower,
incl_lower, x, incl_upper, and upper. range summarizes the
columns from lower to upper.
Details
x is a string by default so that its trailing zeros can be
counted, since a numeric value loses them. If the number of decimal places
is known, pass it as digits, and x may be numeric.
bound_numerators() and sum_range() derive their bounds from the
same internal functions as unround(), so they always agree with it.
All arguments are vectorized. Those of length greater than 1 must have the
same length and are paired element by element. Pairing x with
rounding in this way gives a warning.
Rounding
Whether a bound is inclusive depends on the rounding
method. Under "up", a value on the lower bound rounds up to x, but a
value on the upper bound rounds up past it. The range column shows the
bounds with the appropriate signs:
Value of rounding | Corresponding range |
"up_or_down" (default) | lower <= x <= upper |
"up", "ties_up" | lower <= x < upper |
"down", "ties_down" | lower < x <= upper |
"ties_away" (positive x) | lower <= x < upper |
"ties_away" (negative x) | lower < x <= upper |
"ties_zero" (positive x) | lower < x <= upper |
"ties_zero" (negative x) | lower <= x < upper |
"ties_away", "ties_zero" (zero x) | lower < x < upper |
"even", "ties_even" | lower <= x <= upper |
"ceiling" | lower < x = upper |
"floor" | lower = x < upper |
"ceiling_or_floor" | lower < x < upper |
"trunc" (positive x) | lower = x < upper |
"trunc" (negative x) | lower < x = upper |
"trunc" (zero x) | lower < x < upper |
"anti_trunc" (positive x) | lower < x = upper |
"anti_trunc" (negative x) | lower = x < upper |
"anti_trunc" (zero x) | lower = x = upper (all 0) |
"up_from" | lower <= x < upper |
"down_from" | lower < x <= upper |
"up_from_or_down_from" | lower <= x <= upper |
threshold only applies to the three "*_from" methods. It moves their
range without widening it; each spans exactly one step at every
threshold.
The "ties_*" methods each name a complete tie-breaking procedure, so
giving symmetric = TRUE with them is an error; see round_ties_up().
Under "even", both bounds are reported as inclusive. base::round()
decides a tie on the binary double, so whether a value on a bound rounds
to x cannot be predicted from its decimal digits. Treating both bounds
as inclusive can only widen the range, which is the safe direction for
error detection.
See also
round_up() for rounding up or down from 5, and
round_ceiling() for the one-directional methods.
Examples
# By default, `x` may have been rounded up or down:
unround(x = "2.7")
#> # A tibble: 1 × 7
#> range rounding lower incl_lower x incl_upper upper
#> <chr> <chr> <dbl> <lgl> <chr> <lgl> <dbl>
#> 1 2.65 <= x(2.7) <= 2.75 up_or_down 2.65 TRUE 2.7 TRUE 2.75
# If it was rounded up, the upper bound is exclusive:
unround(x = "2.7", rounding = "up")
#> # A tibble: 1 × 7
#> range rounding lower incl_lower x incl_upper upper
#> <chr> <chr> <dbl> <lgl> <chr> <lgl> <dbl>
#> 1 2.65 <= x(2.7) < 2.75 up 2.65 TRUE 2.7 FALSE 2.75
# Likewise with rounding down...
unround(x = "2.7", rounding = "down")
#> # A tibble: 1 × 7
#> range rounding lower incl_lower x incl_upper upper
#> <chr> <chr> <dbl> <lgl> <chr> <lgl> <dbl>
#> 1 2.65 < x(2.7) <= 2.75 down 2.65 FALSE 2.7 TRUE 2.75
# ...and with `base::round()`:
unround(x = "2.7", rounding = "even")
#> # A tibble: 1 × 7
#> range rounding lower incl_lower x incl_upper upper
#> <chr> <chr> <dbl> <lgl> <chr> <lgl> <dbl>
#> 1 2.65 <= x(2.7) <= 2.75 even 2.65 TRUE 2.7 TRUE 2.75
# One row per input value:
unround(x = c(3.6, "5.20", 5.174))
#> # A tibble: 3 × 7
#> range rounding lower incl_lower x incl_upper upper
#> <chr> <chr> <dbl> <lgl> <chr> <lgl> <dbl>
#> 1 3.55 <= x(3.6) <= 3.65 up_or_do… 3.55 TRUE 3.6 TRUE 3.65
#> 2 5.195 <= x(5.20) <= 5.205 up_or_do… 5.20 TRUE 5.20 TRUE 5.20
#> 3 5.1735 <= x(5.174) <= 5.1745 up_or_do… 5.17 TRUE 5.174 TRUE 5.17