[r] 단일 벡터의 모든 요소가 같은지 테스트
벡터의 모든 요소가 서로 같은지 테스트하려고합니다. 내가 생각해 낸 솔루션은 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
가장 빠른 것 같습니다 .
답변
평균으로 나눈 후 최소값과 최대 값을 비교하는이 방법을 사용합니다.
# 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))
}
이것을 더 심각하게 사용한다면 범위와 평균을 계산하기 전에 누락 된 값을 제거하고 싶을 것입니다.
답변
단순히 분산을 사용하지 않는 이유 :
var(x) == 0
의 모든 요소 x
가 같으면의 분산을 얻습니다 0
.
답변
모두 숫자 값이면 tol이 허용 오차이면 …
all( abs(y - mean(y)) < tol )
귀하의 문제에 대한 해결책입니다.
편집하다:
이것과 다른 답변을 살펴보고 몇 가지를 벤치마킹 한 후 DWin 답변보다 두 배 빠른 속도로 다음이 나옵니다.
abs(max(x) - min(x)) < tol
이것은 조금 놀라 울 정도로 빠르게보다 diff(range(x))
이후 diff
보다 훨씬 다른 안 -
및 abs
두 개의 번호. 범위를 요청하면 최소값과 최대 값을 최적화해야합니다. diff
및 둘 다 range
기본 함수입니다. 하지만 타이밍은 거짓말이 아닙니다.
답변
> 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
답변
첫 번째 요소를 다른 모든 요소 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>
이렇게하면 identical()
필요에 따라 엡실론을 추가 할 수 있습니다 .
답변
그냥 확인할 수 있습니다 all(v==v[1])
답변
이 질문에 계속해서 계속 돌아 오므로 대답이 실제로 (불일치가 발생하는 순간 멈출 것이기 때문에) 동일한 속도를 가질 경우 Rcpp
일반적으로 어떤 R
솔루션 보다 훨씬 더 빠른 솔루션 FALSE
이 있습니다. 대답이이면 가장 빠른 R 솔루션입니다 TRUE
. 예를 들어 OP 벤치 마크의 system.time
경우이 기능을 사용하여 정확히 0으로 클럭합니다.
library(inline)
library(Rcpp)
fast_equal = cxxfunction(signature(x = 'numeric', y = 'numeric'), '
NumericVector var(x);
double precision = as<double>(y);
for (int i = 0, size = var.size(); i < size; ++i) {
if (var[i] - var[0] > precision || var[0] - var[i] > precision)
return Rcpp::wrap(false);
}
return Rcpp::wrap(true);
', plugin = 'Rcpp')
fast_equal(c(1,2,3), 0.1)
#[1] FALSE
fast_equal(c(1,2,3), 2)
#[2] TRUE