safeInteger.RdUsers often accidentally create floating point numeric variables
when they really mean integers, such as c(1, 2, 3), when they
should have done c(1L, 2L, 3L). Before running as.integer()
to coerce the variable, we'd rather be polite and ask the variable
"do you mind being treated as if you are an integer?" This
function checks to see if the variable is "close enough" to being
an integer, and then coerces as integer. Otherwise, it returns
NULL. And issues a warning.
safeInteger(
x,
tol = .Machine$double.eps,
digits = 7,
vmax = .Machine$integer.max,
verbose = FALSE
)Either an integer vector or the original variable
First, calculate absolute value of differences between x
and as.integer(x). Second, find out if the sum of those
differences is smaller than tol. If so, then x can
reasonably be coerced to an integer.
Be careful with the return. The correct return value for variables that should not be coerced as integer is uncertain at this point. We've tested various strategies, sometimes returning FALSE, NULL, or just the original variable.
x1 <- c(1, 2, 3, 4, 5, 6)
is.integer(x1)
#> [1] FALSE
is.double(x1)
#> [1] TRUE
is.numeric(x1)
#> [1] TRUE
(x1int <- safeInteger(x1))
#> [1] 1 2 3 4 5 6
is.integer(x1int)
#> [1] TRUE
is.double(x1int)
#> [1] FALSE
is.numeric(x1int)
#> [1] TRUE
x2 <- rnorm(100)
x2int <- safeInteger(x2)
head(x2int)
#> NULL
x3 <- factor(x1, labels = c(LETTERS[1:6]))
x3int <- safeInteger(x3)