如何检查数字和转换为数字的字符串之间的相等性(矢量化)

How to check equality between number and string converted to number (vectorized)

我想找到 outliers 包的 grubbs.test 函数发现的异常值的索引(我从另一个 SO 答案 here 改编而来)

where = function(x) which(x==as.numeric(strsplit(grubbs.test(x)$alternative," ")[[1]][3]))

它通过检索 grubbs 结果显示的文本中的数字来工作。这有点像 hack,但效果很好,比方说,对于整数:

df=c(0, 3, rnorm(10))
where(df) #[1] 2

当涉及到十进制数时,文本与实际数字的数字并不总是匹配:

df=c(0, sqrt(10), rnorm(10))
where(df) # integer(0)

有人有解决该问题的想法吗?或者另一种方法来找到 grubbs 测试最大异常值的索引?我试图在循环中使用它。

问题是因为 strsplit returns 刺痛而不是数字。在你的第二个例子中,我得到:

[1] "highest"          "value"            "3.16227766016838" "is"               "an"               "outlier"   

但第三个元素并不是数字的字符版本 3.16227766016838。事实上,从 grubbs.test 返回的实数可能有更多的小数位,这就是为什么 == 运算符不 'catch' 它作为相等。这可以在这里清楚地看到:

a<-sqrt(10)
> a == as.numeric(as.character(a))
[1] FALSE

有解决办法吗?

有。

为了解决这个问题,只需使用我冒昧从 this R-help post:

复制的 almost.equal 函数
almost.equal <- function (x, y, tolerance=.Machine$double.eps^0.5,
                          na.value=TRUE)
{
  answer <- rep(na.value, length(x))
  test <- !is.na(x)
  answer[test] <- abs(x[test] - y) < tolerance
  answer
}

上述函数是 all.equal 函数的矢量化形式,它检查 'approximate' 相等性,以便捕获像您这样的情况。

让我们将您的函数转换为:

where = function(x) {
  which(almost.equal(x, as.numeric(strsplit(grubbs.test(x)$alternative," ")[[1]][3])))
}

现在让我们检查一下:

> df=c(0, 3, rnorm(10))
> where(df)
[1] 2

并且:

> df=c(0, sqrt(10), rnorm(10))
> where(df)
[1] 2

而且您有一个适用于十进制数的解决方案!!