[ACTUALIZAR] ============================================= ===============
Con respecto a la respuesta [VIEJA] aquí abajo, descubrí que funcionaba porque puse todos los números en un solo vector atómico; uno de ellos era un personaje, por lo que todos se convierten en personajes.
Si usamos una lista (por lo tanto, la coerción no ocurre) todas las pruebas pasan correctamente menos una:, 1/(1 - 0.98)
que sigue siendo un numeric
. Esto se debe a que el tol
parámetro está por defecto 100 * .Machine$double.eps
y ese número está lejos de ser un 50
poco menos del doble. Entonces, básicamente, para este tipo de números, ¡ tenemos que decidir nuestra tolerancia!
Entonces, si desea que todas las pruebas se conviertan TRUE
, puedeassertive::is_whole_number(x, tol = 200 * .Machine$double.eps)
De todos modos, confirmo que IMO asertivo sigue siendo la mejor solución.
A continuación, un reprex para esta [ACTUALIZACIÓN].
expect_trues_c <- c(
cl = sqrt(2)^2,
pp = 9.0,
t = 1 / (1 - 0.98),
ar0 = 66L,
ar1 = 66,
ar2 = 1 + 2^-50,
v = 222e3,
w1 = 1e4,
w2 = 1e5,
v2 = "1000000000000000000000000000000000001",
an = 2 / 49 * 49,
ju1 = 1e22,
ju2 = 1e24,
al = floor(1),
v5 = 1.0000000000000001 # this is under machine precision!
)
str(expect_trues_c)
#> Named chr [1:15] "2" "9" "50" "66" "66" "1" "222000" "10000" "1e+05" ...
#> - attr(*, "names")= chr [1:15] "cl" "pp" "t" "ar0" ...
assertive::is_whole_number(expect_trues_c)
#> Warning: Coercing expect_trues_c to class 'numeric'.
#> 2 9 50
#> TRUE TRUE TRUE
#> 66 66 1
#> TRUE TRUE TRUE
#> 222000 10000 100000
#> TRUE TRUE TRUE
#> 1e+36 2 1e+22
#> TRUE TRUE TRUE
#> 9.9999999999999998e+23 1 1
#> TRUE TRUE TRUE
expect_trues_l <- list(
cl = sqrt(2)^2,
pp = 9.0,
t = 1 / (1 - 0.98),
ar0 = 66L,
ar1 = 66,
ar2 = 1 + 2^-50,
v = 222e3,
w1 = 1e4,
w2 = 1e5,
v2 = "1000000000000000000000000000000000001",
an = 2 / 49 * 49,
ju1 = 1e22,
ju2 = 1e24,
al = floor(1),
v5 = 1.0000000000000001 # this is under machine precision!
)
str(expect_trues_l)
#> List of 15
#> $ cl : num 2
#> $ pp : num 9
#> $ t : num 50
#> $ ar0: int 66
#> $ ar1: num 66
#> $ ar2: num 1
#> $ v : num 222000
#> $ w1 : num 10000
#> $ w2 : num 1e+05
#> $ v2 : chr "1000000000000000000000000000000000001"
#> $ an : num 2
#> $ ju1: num 1e+22
#> $ ju2: num 1e+24
#> $ al : num 1
#> $ v5 : num 1
assertive::is_whole_number(expect_trues_l)
#> Warning: Coercing expect_trues_l to class 'numeric'.
#> There was 1 failure:
#> Position Value Cause
#> 1 3 49.999999999999957 fractional
assertive::is_whole_number(expect_trues_l, tol = 200 * .Machine$double.eps)
#> Warning: Coercing expect_trues_l to class 'numeric'.
#> 2.0000000000000004 9 49.999999999999957
#> TRUE TRUE TRUE
#> 66 66 1.0000000000000009
#> TRUE TRUE TRUE
#> 222000 10000 100000
#> TRUE TRUE TRUE
#> 1e+36 1.9999999999999998 1e+22
#> TRUE TRUE TRUE
#> 9.9999999999999998e+23 1 1
#> TRUE TRUE TRUE
expect_falses <- list(
bb = 5 - 1e-8,
pt1 = 1.0000001,
pt2 = 1.00000001,
v3 = 3243.34,
v4 = "sdfds"
)
str(expect_falses)
#> List of 5
#> $ bb : num 5
#> $ pt1: num 1
#> $ pt2: num 1
#> $ v3 : num 3243
#> $ v4 : chr "sdfds"
assertive::is_whole_number(expect_falses)
#> Warning: Coercing expect_falses to class 'numeric'.
#> Warning in as.this_class(x): NAs introduced by coercion
#> There were 5 failures:
#> Position Value Cause
#> 1 1 4.9999999900000001 fractional
#> 2 2 1.0000001000000001 fractional
#> 3 3 1.0000000099999999 fractional
#> 4 4 3243.3400000000001 fractional
#> 5 5 <NA> missing
assertive::is_whole_number(expect_falses, tol = 200 * .Machine$double.eps)
#> Warning: Coercing expect_falses to class 'numeric'.
#> Warning: NAs introduced by coercion
#> There were 5 failures:
#> Position Value Cause
#> 1 1 4.9999999900000001 fractional
#> 2 2 1.0000001000000001 fractional
#> 3 3 1.0000000099999999 fractional
#> 4 4 3243.3400000000001 fractional
#> 5 5 <NA> missing
Creado el 2019-07-23 por el paquete reprex (v0.3.0)
[ANTIGUO] ============================================= ==================
En mi opinión, la mejor solución proviene del assertive
paquete (que, por el momento, resuelve todos los ejemplos positivos y negativos en este hilo):
are_all_whole_numbers <- function(x) {
all(assertive::is_whole_number(x), na.rm = TRUE)
}
are_all_whole_numbers(c(
cl = sqrt(2)^2,
pp = 9.0,
t = 1 / (1 - 0.98),
ar0 = 66L,
ar1 = 66,
ar2 = 1 + 2^-50,
v = 222e3,
w1 = 1e4,
w2 = 1e5,
v2 = "1000000000000000000000000000000000001",
an = 2 / 49 * 49,
ju1 = 1e22,
ju2 = 1e24,
al = floor(1),
v5 = 1.0000000000000001 # difference is under machine precision!
))
#> Warning: Coercing x to class 'numeric'.
#> [1] TRUE
are_all_not_whole_numbers <- function(x) {
all(!assertive::is_whole_number(x), na.rm = TRUE)
}
are_all_not_whole_numbers(c(
bb = 5 - 1e-8,
pt1 = 1.0000001,
pt2 = 1.00000001,
v3 = 3243.34,
v4 = "sdfds"
))
#> Warning: Coercing x to class 'numeric'.
#> Warning in as.this_class(x): NAs introduced by coercion
#> [1] TRUE
Creado el 2019-07-23 por el paquete reprex (v0.3.0)
round(x)
se implementa correctamente, el resultado de aplicarlo a un número entero siempre sería ese número entero ...