unround()
takes a rounded number and returns the range of the
original value: lower and upper bounds for the hypothetical earlier number
that was later rounded to the input number. It also displays a range with
inequation signs, showing whether the bounds are inclusive or not.
By default, the presumed rounding method is rounding up (or down) from 5.
See the Rounding
section for other methods.
Arguments
- x
String or numeric. Rounded number.
x
must be a string unlessdigits
is specified (most likely by a function that usesunround()
as a helper).- rounding
String. Rounding method presumably used to create
x
. Default is"up_or_down"
. For more, see sectionRounding
.- threshold
Integer. Number from which to round up or down. Other rounding methods are not affected. Default is
5
.- digits
Integer. This argument is meant to make
unround()
more efficient to use as a helper function so that it doesn't need to redundantly count decimal places. Don't specify it otherwise. Default isNULL
, in which case decimal places really are counted internally andx
must be a string.
Value
A tibble with seven columns: range
, rounding
, lower
,
incl_lower
, x
, incl_upper
, and upper
. The range
column is a handy
representation of the information stored in the columns from lower
to
upper
, in the same order.
Details
The function is vectorized over x
and rounding
. This can be
useful to unround multiple numbers at once, or to check how a single number
is unrounded with different assumed rounding methods.
If both vectors have a length greater than 1, it must be the same length. However, this will pair numbers with rounding methods, which can be confusing. It is recommended that at least one of these input vectors has length 1.
Why does x
need to be a string if digits
is not specified? In that
case, unround()
must count decimal places by itself. If x
then was
numeric, it wouldn't have any trailing zeros because these get dropped from
numerics.
Trailing zeros are as important for reconstructing boundary values as any other trailing digits would be. Strings don't drop trailing zeros, so they are used instead.
Rounding
Depending on how x
was rounded, the boundary values can
be inclusive or exclusive. The incl_lower
and incl_upper
columns in the
resulting tibble are TRUE
in the first case and FALSE
in the second.
The range
column reflects this with equation and inequation signs.
However, these ranges are based on assumptions about the way x
was
rounded. Set rounding
to the rounding method that hypothetically lead to
x
:
Value of rounding | Corresponding range |
"up_or_down" (default) | lower <= x <= upper |
"up" | lower <= x < upper |
"down" | lower < x <= upper |
"even" | (no fix range) |
"ceiling" | lower < x = upper |
"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 ) | (undefined; NA ) |
Base R's own round()
(R version >= 4.0.0), referenced by rounding = "even"
, is reconstructed in the same way as "up_or_down"
, but whether the
boundary values are inclusive or not is hard to predict. Therefore,
unround()
checks if they are, and informs you about it.
See also
For more about rounding "up"
, "down"
, or to "even"
, see
round_up()
.
For more about the less likely rounding
methods, "ceiling"
, "floor"
,
"trunc"
, and "anti_trunc"
, see round_ceiling()
.
Examples
# By default, the function assumes that `x`
# was either 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 `x` was rounded up, run this:
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()` which, broadly
# speaking, rounds to the nearest even number:
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 FALSE 2.7 FALSE 2.75
# Multiple input number-strings return
# multiple rows in the output data frame:
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