我想查找grubbs.test
包的outliers
函数发现的异常值的索引(我从另一个SO回复here改编了它)
where = function(x) which(x==as.numeric(strsplit(grubbs.test(x)$alternative," ")[[1]][3]))
它的工作原理是检索grubbs结果显示的文本中的数字。这是一种黑客攻击,但它可以很好地用于数字:
df=c(0, 3, rnorm(10))
where(df) #[1] 2
当达到十进制数字时,文本与实际数字的数字不匹配:
df=c(0, sqrt(10), rnorm(10))
where(df) # integer(0)
有人有想法解决这个问题吗?或者另一种方法来查找grubbs测试最大异常值的索引?我试图在循环中使用它。
答案 0 :(得分:1)
问题是因为strsplit
返回stings而不是数字。在你的第二个例子中,我得到了:
[1] "highest" "value" "3.16227766016838" "is" "an" "outlier"
但第三个元素实际上不是数字3.16227766016838
的字符版本。实际上,从grubbs.test
返回的实数可能会有更多的小数位,这就是为什么==
运算符不会“捕获”它作为相等的原因。这可以在这里清楚地看到:
a<-sqrt(10)
> a == as.numeric(as.character(a))
[1] FALSE
有解决方法吗?
是有。
为了解决这个问题,只需使用almost.equal
函数,我就可以从this R-help帖子中复制:
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
函数的矢量化形式,它检查“近似”的相等性,以便捕获像你这样的案例。
让我们将您的功能转换为:
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
你有一个适用于十进制数的解决方案!!