检查数字是否为整数

Rom*_*rik 92 integer r rounding

我很惊讶地发现R没有附带一个方便的函数来检查数字是否为整数.

is.integer(66) # FALSE
Run Code Online (Sandbox Code Playgroud)

帮助文件警告:

is.integer(x)不测试是否x 包含整数!为此,请使用round,如is.wholenumber(x)示例中的函数 .

该示例将此自定义函数作为"解决方法"

is.wholenumber <- function(x, tol = .Machine$double.eps^0.5)  abs(x - round(x)) < tol
is.wholenumber(1) # is TRUE
Run Code Online (Sandbox Code Playgroud)

如果我必须编写一个函数来检查整数,假设我没有阅读上面的注释,我会编写一个函数,它会像

check.integer <- function(x) {
    x == round(x)
}
Run Code Online (Sandbox Code Playgroud)

我的方法会在哪里失败?如果你穿着我的假想鞋,你的工作会是什么?

Jam*_*mes 111

另一种方法是检查小数部分:

x%%1==0
Run Code Online (Sandbox Code Playgroud)

要么,

min(abs(c(x%%1, x%%1-1))) < tol
Run Code Online (Sandbox Code Playgroud)

如果你想在一定的容忍范围内检查.

  • `as.integer(x)== x`有什么问题?它不会像`is.integer(x)`那样拒绝3或3.0,它会捕获3.1. (3认同)
  • 公差检查建议真的有效吗?`x &lt;- 5-1e-8;x%%1` 给出 0.9999999 (这意味着如果 `tol==1e-5` 例如)`x` 不是整数。 (2认同)
  • @James,我认为它应该是`min(abs(c(x %% 1,x %% 1-1)))<tol`而不是`abs(min(x %% 1,x %% 1-1) ))<tol`否则,任何整数都会得到"FALSE"... (2认同)

Ite*_*tor 29

这是一个使用更简单的功能而且没有黑客的解决方案:

all.equal(a, as.integer(a))
Run Code Online (Sandbox Code Playgroud)

更重要的是,如果您愿意,可以一次测试整个矢量.这是一个功能:

testInteger <- function(x){
  test <- all.equal(x, as.integer(x), check.attributes = FALSE)
  if(test == TRUE){ return(TRUE) }
  else { return(FALSE) }
}
Run Code Online (Sandbox Code Playgroud)

您可以将其更改为*apply在矢量,矩阵等情况下使用.

  • 最后一个`if``else`可以用`isTRUE(test)`来完成.实际上,只需更换`if``seject`子句和`return`语句,因为R会自动返回上一次评估的结果. (10认同)
  • ``testInteger(1.0000001)``[1] FALSE``testInteger(1.00000001)``[1] TRUE (6认同)
  • `all(a == as.integer(a))`绕过这个问题!' (3认同)

And*_*edd 10

阅读R语言文档,as.integer更多地与数字的存储方式有关,而不是实际上等于整数.is.integer测试数字是否声明为整数.您可以通过在其L后面添加一个整数来声明它.

> is.integer(66L)
[1] TRUE
> is.integer(66)
[1] FALSE
Run Code Online (Sandbox Code Playgroud)

函数也round将返回一个声明的整数,这就是你正在做的事情x==round(x).这种方法的问题是你认为实际上是一个整数.该示例使用较低的精度来测试等效性.

> is.wholenumber(1+2^-50)
[1] TRUE
> check.integer(1+2^-50)
[1] FALSE
Run Code Online (Sandbox Code Playgroud)

因此,根据您的应用程序,您可能会遇到麻烦.


Vit*_*hKa 9

这是一个显然可靠的方式:

check.integer <- function(N){
    !grepl("[^[:digit:]]", format(N,  digits = 20, scientific = FALSE))
}

check.integer(3243)
#TRUE
check.integer(3243.34)
#FALSE
check.integer("sdfds")
#FALSE
Run Code Online (Sandbox Code Playgroud)

该解决方案还允许使用科学记数法表示整数:

> check.integer(222e3)
[1] TRUE
Run Code Online (Sandbox Code Playgroud)

  • -1这比`is.wholenumber`或其他答案中提供的任何其他解决方案更糟糕.这些不应该是不同的:`check.integer(1e22); check.integer(1e23)`.你可以明显改变正则表达式来解决这个问题,但这种方法很糟糕.(评论来自installr包中的归属.) (5认同)
  • @VitoshKa喜欢你的回答!虽然您错过了一点,但没有小数点的负数也是整数;)我相应地修改了您的代码. (4认同)

Ani*_*iko 8

您似乎没有看到需要包含一些容错.如果所有整数都以整数形式输入,则不需要它,但有时它们会因算术运算而失去一些精度.例如:

> 2/49*49
[1] 2
> check.integer(2/49*49)
[1] FALSE 
> is.wholenumber(2/49*49)
[1] TRUE
Run Code Online (Sandbox Code Playgroud)

请注意,这不是R的弱点,所有计算机软件都有一定的精度限制.

  • 以防万一有些人不太清楚这里发生的事情...如果你输入as.integer(2/49*49)就得1![顺便说一句,令人非常沮丧的是,R没有将初始计算的结果显示为2.0来表示该值具有一些小数部分)请参阅... http://stackoverflow.com/questions/1535021/whats-在-最大-R-疑难杂症,你已运行,横跨/ 3398868#3398868 (3认同)

aL3*_*3xa 6

来自Hmisc::spss.get:

all(floor(x) == x, na.rm = TRUE)
Run Code Online (Sandbox Code Playgroud)

更安全的选择,恕我直言,因为它"绕过"机器精度问题.如果你尝试is.integer(floor(1)),你会得到FALSE.顺便说一下,如果你的整数大于.Machine$integer.max值,那么你的整数将不会保存为整数,默认情况下为2147483647,所以要么改变integer.max值,要么做替代检查......


小智 5

您可以使用简单的 if 条件,例如:

if(round(var) != var)­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
Run Code Online (Sandbox Code Playgroud)