[r] 숫자가 정수인지 확인

R에 숫자가 정수인지 확인하는 편리한 기능이 없다는 사실에 놀랐습니다.

is.integer(66) # FALSE

도움말 파일은 경고 :

is.integer(x)x
정수 가 포함되어 있는지 테스트하지 않습니다 ! 이를 위해 예제 round의 함수 is.wholenumber(x)에서 와 같이를
사용 하십시오.

이 예제에는 “해결 방법”으로이 사용자 지정 함수가 있습니다.

is.wholenumber <- function(x, tol = .Machine$double.eps^0.5)  abs(x - round(x)) < tol
is.wholenumber(1) # is TRUE

위의 주석을 읽지 않았다고 가정하고 정수를 확인하는 함수를 작성해야한다면,

check.integer <- function(x) {
    x == round(x)
}

내 접근 방식은 어디에서 실패합니까? 당신이 내 가상의 입장에 있었다면 당신은 어떤 일을 할 것입니까?



답변

또 다른 대안은 분수 부분을 확인하는 것입니다.

x%%1==0

또는 특정 허용 오차 내에서 확인하려는 경우 :

min(abs(c(x%%1, x%%1-1))) < tol


답변

다음은 더 간단한 기능을 사용하고 해킹이없는 솔루션입니다.

all.equal(a, as.integer(a))

또한 원하는 경우 전체 벡터를 한 번에 테스트 할 수 있습니다. 다음은 함수입니다.

testInteger <- function(x){
  test <- all.equal(x, as.integer(x), check.attributes = FALSE)
  if(test == TRUE){ return(TRUE) }
  else { return(FALSE) }
}

*apply벡터, 행렬 등의 경우에 사용하도록 변경할 수 있습니다 .


답변

R 언어 문서를 읽는 as.integer것은 실제로 정수와 동일한 경우보다 숫자가 저장되는 방법과 더 관련 이 있습니다. is.integer숫자가 정수로 선언되었는지 테스트합니다. L뒤에 a를 넣어 정수를 선언 할 수 있습니다 .

> is.integer(66L)
[1] TRUE
> is.integer(66)
[1] FALSE

또한 같은 함수 round는 선언 된 정수를 반환합니다 x==round(x). 이 접근 방식의 문제는 실제로 정수라고 생각하는 것입니다. 이 예에서는 동등성을 테스트하기 위해 정밀도가 낮습니다.

> is.wholenumber(1+2^-50)
[1] TRUE
> check.integer(1+2^-50)
[1] FALSE

따라서 응용 프로그램에 따라 그런 식으로 문제가 발생할 수 있습니다.


답변

분명히 신뢰할 수있는 방법은 다음과 같습니다.

check.integer <- function(N){
    !grepl("[^[:digit:]]", format(N,  digits = 20, scientific = FALSE))
}

check.integer(3243)
#TRUE
check.integer(3243.34)
#FALSE
check.integer("sdfds")
#FALSE

이 솔루션은 과학적 표기법의 정수도 허용합니다.

> check.integer(222e3)
[1] TRUE


답변

일부 오류 허용 범위를 통합 할 필요가없는 것 같습니다. 모든 정수가 정수로 입력되면 필요하지 않지만 때로는 정밀도를 잃는 산술 연산의 결과로 제공됩니다. 예를 들면 :

> 2/49*49
[1] 2
> check.integer(2/49*49)
[1] FALSE
> is.wholenumber(2/49*49)
[1] TRUE

이것은 R의 약점이 아니며 모든 컴퓨터 소프트웨어에는 약간의 정밀도 한계가 있습니다.


답변

에서 Hmisc::spss.get:

all(floor(x) == x, na.rm = TRUE)

훨씬 더 안전한 옵션 인 IMHO는 기계 정밀도 문제를 “우회”하기 때문입니다. 시도 is.integer(floor(1))하면 FALSE. BTW, 귀하의 정수는 .Machine$integer.max값 보다 크면 정수로 저장되지 않습니다. 기본값은 2147483647이므로 integer.max값을 변경 하거나 대체 검사를 수행하십시오.


답변

다음과 같은 간단한 if 조건을 사용할 수 있습니다.

if(round(var) != var)­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­