首页>Program>source

我正在尝试测试向量的所有元素是否彼此相等.我想出的解决方案似乎有些round回,都涉及检查 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

一个让我包括一个用于评估要素之间"平等"的容差值的解决方案将是避免常见问题解答7.31问题。

我是否完全忽略了针对测试类型的内置函数? identical()all.equal() 比较两个R对象,所以它们在这里不起作用。

Edit 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 最快。

最新回答
  • 2021-1-9
    1 #

    我使用这种方法,将平均值除以最小值和最大值:

    # Determine if range of vector is FP 0.
    zero_range <- function(x, tol = .Machine$double.eps ^ 0.5) {
      if (length(x) == 1) return(TRUE)
      x <- range(x) / mean(x)
      isTRUE(all.equal(x[1], x[2], tolerance = tol))
    }
    

    如果您更认真地使用它,则可能要在计算范围和均值之前删除缺失的值。

  • 2021-1-9
    2 #

    如果它们都是数字值,那么tol是您的公差. ..

    all( abs(y - mean(y)) < tol )
    

    是解决您问题的方法。

    EDIT:

    在查看了此答案和其他答案并进行了一些基准测试之后,得出的结果是Dwin答案的两倍.

    abs(max(x) - min(x)) < tol
    

    这比 diff(range(x))快了一点 自从 diff-应该没什么不同 和 abs 有两个数字.请求范围应该优化获取最小值和最大值.都 diffrange 是原始函数.但是,时机并没有。

  • 2021-1-9
    3 #

    为什么不简单地使用方差:

    var(x) == 0
    

    如果 x的所有元素 相等,您将获得 0的方差

  • 2021-1-9
    4 #

    > isTRUE(all.equal( max(y) ,min(y)) )
    [1] TRUE
    > isTRUE(all.equal( max(x) ,min(x)) )
    [1] FALSE
    

    另一条相同的话:

    > diff(range(x)) < .Machine$double.eps ^ 0.5
    [1] FALSE
    > diff(range(y)) < .Machine$double.eps ^ 0.5
    [1] TRUE
    

  • 2021-1-9
    5 #

    您可以使用 identical()all.equal() 通过将第一个元素与所有其他元素进行比较,从而有效地将比较范围扩大了:

    R> compare <- function(v) all(sapply( as.list(v[-1]), 
    +                         FUN=function(z) {identical(z, v[1])}))
    R> compare(x)
    [1] FALSE
    R> compare(y)
    [1] TRUE
    R>
    

    这样,您可以将任何epsilon添加到 identical() 根据需要。

  • java:使用Bouncy Castle签署CSR
  • javascript:CORS是执行跨域AJAX请求的安全方法吗?