我很感激如何做到这一点,所以我们可以相互比较。
这是一个开头的:
is.natural <- function(x)
{
x>0 && identical(round(x), x)
}
答案 0 :(得分:5)
docs提出了类似的方法,所以我怀疑你会变得更好。请记住包含epsilon以考虑精度问题!
is.naturalnumber <-
function(x, tol = .Machine$double.eps^0.5) x > tol & abs(x - round(x)) < tol
is.naturalnumber(1) # is TRUE
(x <- seq(1,5, by=0.5) )
is.naturalnumber( x ) #--> TRUE FALSE TRUE ...
答案 1 :(得分:3)
请注意,identical()
也会检查存储类型:is.natural(1L)
返回FALSE
,因为typeof(1L)
为integer
但typeof(round(1L))
为{ {1}}。作为marcog的替代方案,我建议使用以下函数,使用double
进行检查并处理复数:
all.equal()
答案 2 :(得分:2)
另一个解决方案是使用一些算术:
is.natural2 <- function(x,tol=.Machine$double.eps^0.5){
sign(x) - abs(x-round(x)) >= 1-tol
}
现在,当检查所有解决方案时,结果发现Tal和caracal之一没有给出正确的结果:
is.natural <- function(x)
{
x>0 & identical(round(x), x)
}
is.natural2 <- function(x,tol=.Machine$double.eps^0.5){
sign(x) - abs(x-round(x)) >= 1-tol
}
is.natural3 <- function(x, dig=15){ x > 0 & zapsmall(x, dig) == round(x) }
is.natural4 <- function(x,tol=.Machine$double.eps^0.5){
x > 0 &
isTRUE(all.equal(x,round(x),
tolerance=tol,
check.attributes=FALSE,
check.names=FALSE))
}
is.naturalnumber <- function(x, tol = .Machine$double.eps^0.5){
x > 0 & abs(x - round(x)) < tol
}
然后:
> X <- (seq(0,3,by=0.5)^0.5)^2
> is.natural(X)
[1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE # wrong
> is.natural2(X)
[1] FALSE FALSE TRUE FALSE TRUE FALSE TRUE
> is.natural3(X)
[1] FALSE FALSE TRUE FALSE TRUE FALSE TRUE
> is.natural4(X)
[1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE # wrong
> is.naturalnumber(X)
[1] FALSE FALSE TRUE FALSE TRUE FALSE TRUE
关于时间安排:
> X <- (seq(0,1000000,by=0.5)^0.5)^2
> system.time(is.natural2(X))
user system elapsed
0.24 0.03 0.26
> system.time(is.natural3(X))
user system elapsed
0.67 0.00 0.67
> system.time(is.naturalnumber(X))
user system elapsed
0.22 0.01 0.23
这使得marcog成为赢家。
答案 3 :(得分:2)
您应该始终记住整数大小限制:.Machine$integer.max
。即使您进行某种“检查”,如果给定的数值超出限制,R会将其视为double
,并以不同的方式存储。
> (x <- as.integer(.Machine$integer.max + 1))
[1] NA
Warning message:
NAs introduced by coercion
> (x <- as.double(.Machine$integer.max + 1))
[1] 2147483648
> typeof(x)
[1] "double"
> x <- 2147483647L
> typeof(x)
[1] "integer"
> x <- 2147483648L
Warning message:
non-integer value 2147483648 qualified with L; using numeric value
> typeof(x)
[1] "double"
答案 4 :(得分:1)
您需要两个测试:大于0并且足够接近整数。相同的()测试经常失败,因为它还会检查无关的属性和存储模式。 zapsmall提供将舍入限制为特定数量的数字的能力,并且以可以应用于候选值的向量的方式这样做。如果需要,您可以调整有效位数。
is.natural <- function(x, dig=15){ x > 0 &
zapsmall(x, dig) == round(x) &
x < .Machine$integer.max }
x <- (2^0.5)^2
x ==2
# [1] FALSE (machine mathematics)
is.natural(x)
# [1] TRUE
编辑:关于检查范围是一个很好的观点,因此添加了。