단일 숫자 벡터의 모든 요소 간 동일성 검정
벡터의 모든 요소가 서로 동일한지 테스트하려고 합니다.제가 생각해 낸 해결책은 확인과 관련된 다소 우회적인 것처럼 보입니다.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
가장 빠릅니다.
단순히 분산을 사용하지 않는 이유:
var(x) == 0
만약 모든 요소들이x
같다면, 당신은 다음의 분산을 얻을 것입니다.0
그러나 이것은 이중 및 정수에서만 작동합니다.
아래 설명을 기준으로 편집:
더 일반적인 옵션은 벡터에서 고유한 요소의 길이를 확인하는 것입니다. 이 경우 1이어야 합니다.이는 분산을 계산할 수 있는 이중 및 정수 이외의 모든 클래스에서 작동한다는 장점이 있습니다.
length(unique(x)) == 1
모두 숫자 값이면 공차라면...
all( abs(y - mean(y)) < tol )
당신의 문제에 대한 해결책입니다.
편집:
이것과 다른 답변을 살펴보고 몇 가지를 벤치마킹한 결과 다음과 같은 내용이 DW의 답변보다 두 배 이상 빠르게 나타납니다.
abs(max(x) - min(x)) < tol
이것은 보다 약간 놀랍도록 빠릅니다.diff(range(x))
부터diff
과 크게 다르지 않아야 합니다.-
그리고.abs
두 개의 숫자로범위를 요청하면 최소값과 최대값을 얻는 것이 최적화됩니다.둘다요.diff
그리고.range
원시 함수입니다.하지만 타이밍은 거짓말이 아닙니다.
게다가, @Waldi가 지적했듯이,abs
여기는 불필요합니다.
저는 최소값과 최대값을 비교하는 이 방법을 평균으로 나눈 후 사용합니다.
# 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))
}
이 값을 더 심각하게 사용하는 경우 범위와 평균을 계산하기 전에 결측값을 제거할 수 있습니다.
확인만 하시면 됩니다.all(v==v[1])
> 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()
필요에 따라
제가 이 질문에 계속 반복해서 돌아오니까, 여기에.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
벡터의 요소뿐만 아니라 목록의 모든 요소가 동일한지 확인할 수 있는 기능을 특별히 작성했습니다.물론 문자 벡터와 다른 모든 유형의 벡터도 잘 처리합니다.또한 적절한 오류 처리 기능이 있습니다.
all_identical <- function(x) {
if (length(x) == 1L) {
warning("'x' has a length of only 1")
return(TRUE)
} else if (length(x) == 0L) {
warning("'x' has a length of 0")
return(logical(0))
} else {
TF <- vapply(1:(length(x)-1),
function(n) identical(x[[n]], x[[n+1]]),
logical(1))
if (all(TF)) TRUE else FALSE
}
}
이제 몇 가지 예를 들어 보겠습니다.
x <- c(1, 1, 1, NA, 1, 1, 1)
all_identical(x) ## Return FALSE
all_identical(x[-4]) ## Return TRUE
y <- list(fac1 = factor(c("A", "B")),
fac2 = factor(c("A", "B"), levels = c("B", "A"))
)
all_identical(y) ## Return FALSE as fac1 and fac2 have different level order
실제로 min, mean 또는 max를 사용할 필요는 없습니다.John의 답변에 기초하여:
all(abs(x - x[[1]]) < tolerance)
여기서는 데이터 프레임을 제외한 최소 최대 트릭을 사용하는 대안을 제시합니다.는 열을 예에서 비있고하의 를 비교하고 .apply
행에 대해 1로 변경할 수 있습니다.
valid = sum(!apply(your_dataframe, 2, function(x) diff(c(min(x), max(x)))) == 0)
한다면valid == 0
이 같은 .
을 하는 다른 data.table
및 패지키와 되는, 열호환니다됩과문자.NA
이라uniqueN(x) == 1
언급URL : https://stackoverflow.com/questions/4752275/test-for-equality-among-all-elements-of-a-single-numeric-vector
'UFO ET IT' 카테고리의 다른 글
EPLUS C#에서 테이블 확장 (0) | 2023.06.22 |
---|---|
단순 HTTP 서버에서 액세스 제어 사용 (0) | 2023.06.22 |
Java에서 Oracle의 사용 재개(JDBC, 준비된 설명문) (0) | 2023.06.22 |
데이터 프레임 열의 데이터 유형 결정 (0) | 2023.06.22 |
문자열에 숫자가 포함되어 있는지 탐지하는 방법은 무엇입니까? (0) | 2023.06.22 |