【发布时间】:2011-06-12 17:50:10
【问题描述】:
我正在尝试测试向量的所有元素是否彼此相等。我提出的解决方案似乎有些迂回,都涉及检查length()。
x <- c(1, 2, 3, 4, 5, 6, 1) # FALSE
y <- rep(2, times = 7) # TRUE
unique():
length(unique(x)) == 1
length(unique(y)) == 1
与rle():
length(rle(x)$values) == 1
length(rle(y)$values) == 1
让我在评估元素之间的“平等”时包含一个容差值的解决方案是避免FAQ 7.31 问题的理想选择。
是否有我完全忽略的测试类型的内置函数? identical() 和 all.equal() 比较两个 R 对象,所以它们在这里不起作用。
编辑 1
以下是一些基准测试结果。使用代码:
library(rbenchmark)
John <- function() all( abs(x - mean(x)) < .Machine$double.eps ^ 0.5 )
DWin <- function() {diff(range(x)) < .Machine$double.eps ^ 0.5}
zero_range <- function() {
if (length(x) == 1) return(TRUE)
x <- range(x) / mean(x)
isTRUE(all.equal(x[1], x[2], tolerance = .Machine$double.eps ^ 0.5))
}
x <- runif(500000);
benchmark(John(), DWin(), zero_range(),
columns=c("test", "replications", "elapsed", "relative"),
order="relative", replications = 10000)
有了结果:
test replications elapsed relative
2 DWin() 10000 109.415 1.000000
3 zero_range() 10000 126.912 1.159914
1 John() 10000 208.463 1.905251
所以看起来diff(range(x)) < .Machine$double.eps ^ 0.5 是最快的。
【问题讨论】:
-
对于没有容忍度的相等,
max(x) == min(x)比diff(range(x))快一个数量级,并且可以处理字符和数字