【问题标题】:How to check if each element in a vector is integer or not in R?如何检查向量中的每个元素在R中是否为整数?
【发布时间】:2012-04-11 21:00:46
【问题描述】:

假设我有一个向量 y,我想检查 y 中的每个元素是否为整数,如果不是,则停止并显示错误消息。我试过is.integer(y),但是不行。

【问题讨论】:

  • 定义“整数”究竟是什么是一个难题——您需要从“整数”与整数数据类型的意义上阐明整数。您很少直接在 R 中处理数据类型整数(但这就是 is.integer 测试的目的)——请查看 Martin Maechler 提供的 is.whole():stat.ethz.ch/pipermail/r-help/2003-April/032471.html
  • 当你停下来时,你想知道你停在哪里...即第一个不是整数?一个向量只包含一种数据类型。因此,您不能将整数表示为整数,而只能将整数表示为整数。即使这样也有点问题,因为并非所有整数都是整数。您还需要容忍与整数的偏差。将这些内容的答案添加到您的问题中。

标签: r vector integer


【解决方案1】:

最简单(也是最快!)的事情可能是这样的:

stopifnot( all(y == floor(y)) )

...所以尝试一下:

y <- c(3,4,9)
stopifnot( all(y == floor(y)) ) # OK

y <- c(3,4.01,9)
stopifnot( all(y == floor(y)) ) # ERROR!

如果你想要更好的错误信息:

y <- c(3, 9, NaN)
if (!isTRUE(all(y == floor(y)))) stop("'y' must only contain integer values")

【讨论】:

  • 输入yc('A', 2, 3, 4)的情况呢?
【解决方案2】:

你可以这样做:

   y <- c(3,3.1,1,2.3)
   (y - floor(y)) == 0
    [1]  TRUE FALSE  TRUE FALSE

   (y - round(y)) == 0

如果您想要一个单一的TRUEFALSE 用于整个事情,请将其放入all(),例如:

   all((y - round(y)) == 0)
    [1] FALSE

【讨论】:

  • 每个元素都有一个 TRUE/FALSE 值很好,因为 R 是一种矢量化语言。
【解决方案3】:

这是另一种方式(使用与 Justin 相同的技巧,将每个数字与强制转换为“整数”类型的数字进行比较):

R> v1 = c(1,2,3)
R> v2 = c(1,2,3.5)
R> sapply(v1, function(i) i == as.integer(i))
[1] TRUE TRUE TRUE
R> sapply(v2, function(i) i == as.integer(i))
[1]  TRUE  TRUE FALSE

进行测试:

R> all(sapply(v2, function(i) i == as.integer(i)))
[1] FALSE

【讨论】:

    【解决方案4】:

    不确定 Tim 的方式和这个方式哪个更快,但是:

    > x <- 1:5
    > y <- c(x, 2.0)
    > z <- c(y, 4.5)
    > all.equal(x, as.integer(x))
    [1] TRUE
    > all.equal(y, as.integer(y))
    [1] TRUE
    > all.equal(z, as.integer(z))
    [1] "Mean relative difference: 0.1111111"
    > 
    

    或:

    all((z - as.integer(z))==0)
    

    【讨论】:

    • 您可以使用identical() 代替all.equal(),因为all.equal(3.00000001,3L) 并不是真正的TRUE
    • @BenBarnes identical(y, as.integer(y)) 为我返回 FALSE,但是是的,你是对的。减法技术可能更简单一点......
    • 我认为@mweylandt 和@John 的cmets 关于问题的模棱两可是正确的(这就是我试图得到的)。 is.integer(2.0) 在 R 看来是 FALSE,但出于其他意图和目的,它是一个很好的整数。
    • @BenBarnes 再次正确,提问者提供的更多细节将有助于确定正确的方法是什么。
    【解决方案5】:

    我走的方向与蒂姆完全不同(我更喜欢他的方向,尽管我的方法适用于混合向量,即带有整数等的字符向量):

    int.check <- function(vect) {
        vect <- as.character(vect)
        sapply(vect, function(x) all(unlist(strsplit(x, ""))%in% 0:9))
    }
    
    x <- c(2.0, 1111,"x", 2.4)
    int.check(x)
    

    编辑:更改了函数,因为它仅适用于字符向量。

    这也适用于类字符的向量,以防您有一个混合了各种数字但已被强制转换为字符的字符向量。

    【讨论】:

    • ...虽然很慢。 y&lt;-1:1e5; system.time( int.check(y) ) 大约需要 1.8 秒。我的版本需要 0.01 或更少 ;-)
    • 哦,是的,如果你有一个数字向量,这绝对不是要走的路,只是一个不同的方法但是看看你的方法在y&lt;-c(1:1e5, "x") 上是如何工作的; )
    • PS 我得到 4.12 秒还不错。
    • 顺便说一句,“1e6”不应该被认为是整数吗? int.check("1e6") 返回 FALSE。
    【解决方案6】:

    检查以下内容有助于我们在脚本中使用清晰的 if 条件。

    sff <- 5
    
    if(!(is.integer(sff) == is.character(sff))){ 
      sff
    } else {
      "hello"
    }
    

    给予

    hello
    

    sff &lt;- 'a' 给出'a' 作为结果。

    【讨论】:

    • 你能解释一下这个条件在做什么吗?我不能。
    【解决方案7】:

    如果您有浮点表示错误,请尝试:

    round( y, TOLERANCE.DIGITS ) %% 1 == 0
    

    在我的应用程序中,我遇到了严重的浮点表示错误,例如:

    > dictionary$beta[3]
    [1] 89
    > floor(dictionary$beta[3])
    [1] 88
    > as.integer( dictionary$beta )[3]
    [1] 88
    > dictionary$beta[3] %% 1
    [1] 1
    

    除以一的余数是一。我发现在取整数之前我必须四舍五入。我认为在您希望将上述 89 计为整数的情况下,所有这些测试都会失败。 “all.equal”函数旨在成为处理浮点表示错误的最佳方法,但是:

    all.equal( 88, 89 );
    

    在我的情况下,会(并且确实)对整数值检查给出假阴性。

    编辑:在基准测试中,我发现:

    (x == as.integer(x)) 
    

    是普遍最佳表演者。

    (x == floor(x))
    ((x - as.integer(x)) == 0)
    

    通常工作得很好,通常也一样快。

    (x %% 1 <= tolerance)
    

    有效,但不如其他人快

    !(is.character(all.equal(x, as.integer(x)))) 
    

    当向量不是整数时,性能糟糕(当然是因为估计差异会很麻烦)。

    identical(x, as.integer(x)) 
    

    当向量都是整数值时,返回不正确结果(假设问题是为了检查整数值,而不是整数类型)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-25
      • 2013-12-12
      • 1970-01-01
      • 1970-01-01
      • 2012-07-14
      • 2021-08-04
      相关资源
      最近更新 更多