programing

숫자가 정수인지 확인합니다.

lastmoon 2023. 6. 6. 10:36
반응형

숫자가 정수인지 확인합니다.

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벡터, 행렬 등의 경우

신뢰할 수 있는 한 가지 방법이 있습니다.

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

언어 중, R 중읽는를서설,as.integer숫자가 실제로 정수와 동일한 경우보다 숫자가 저장되는 방식과 더 많은 관련이 있습니다. is.integer숫자가 정수로 선언되었는지 여부를 테스트합니다.다을입력여정선수있다습니언할수를음을 넣어 할 수 .L그 후에

> 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

따라서 애플리케이션에 따라 문제가 발생할 수 있습니다.

오류 허용도를 일부 통합할 필요가 없다고 생각하는 것 같습니다.모든 정수가 정수로 입력된 경우에는 필요하지 않지만, 때때로 정밀도가 떨어지는 산술 연산의 결과로 발생하기도 합니다.예:

> 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참로고, 정가다크보다 ..Machine$integer.max값. 즉, 기본값으로 2147483647이므로, 다음을 변경합니다.integer.max값을 지정하거나 대체 검사를 수행합니다.

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

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

R에서 숫자가 숫자인지 정수인지는 클래스 함수에 의해 결정될 수 있습니다.일반적으로 모든 숫자는 숫자로 저장되며 숫자를 정수로 명시적으로 정의하려면 숫자 뒤에 'L'을 지정해야 합니다.

예:

x <- 1

클래스(x)

"스캐너덜너덜

x <- 1L

클래스(x)

"스캐너덜너덜

이것이 필요했던 것이기를 바랍니다.감사합니다 :)

[업데이트] ==============================================================

아래 [OLD] 답변과 관련하여, 저는 모든 숫자를 하나의 원자 벡터에 넣었기 때문에 효과가 있다는 것을 발견했습니다. 그 중 하나는 문자였기 때문에 모든 사람이 문자가 됩니다.

목록을 사용할 경우(따라서 강제 적용은 발생하지 않음) 모든 테스트가 올바르게 통과하지만 다음 중 하나만 사용할 수 있습니다.1/(1 - 0.98)그것은 a로 남아있습니다.numeric왜냐하면tol매개 변수는 기본값입니다.100 * .Machine$double.eps그리고 그 숫자는 거리가 멉니다.50그것의 두 배보다 조금 적습니다.그래서, 기본적으로, 이런 종류의 숫자들에 대해, 우리는 우리의 관용을 결정해야 합니다!

그래서 당신이 원한다면 모든 시험이TRUE,넌 할 수 있다.assertive::is_whole_number(x, tol = 200 * .Machine$double.eps)

어쨌든, 저는 IMO 주장이 최선의 해결책임을 확인합니다.

이 [UPDATE]에 대한 설명입니다.

expect_trues_c <- c(
  cl = sqrt(2)^2,
  pp = 9.0,
  t = 1 / (1 - 0.98),
  ar0 = 66L,
  ar1 = 66,
  ar2 = 1 + 2^-50,
  v = 222e3,
  w1 = 1e4,
  w2 = 1e5,
  v2 = "1000000000000000000000000000000000001",
  an = 2 / 49 * 49,
  ju1 = 1e22,
  ju2 = 1e24,
  al = floor(1),
  v5 = 1.0000000000000001 # this is under machine precision!
)

str(expect_trues_c)
#>  Named chr [1:15] "2" "9" "50" "66" "66" "1" "222000" "10000" "1e+05" ...
#>  - attr(*, "names")= chr [1:15] "cl" "pp" "t" "ar0" ...
assertive::is_whole_number(expect_trues_c)
#> Warning: Coercing expect_trues_c to class 'numeric'.
#>                      2                      9                     50 
#>                   TRUE                   TRUE                   TRUE 
#>                     66                     66                      1 
#>                   TRUE                   TRUE                   TRUE 
#>                 222000                  10000                 100000 
#>                   TRUE                   TRUE                   TRUE 
#>                  1e+36                      2                  1e+22 
#>                   TRUE                   TRUE                   TRUE 
#> 9.9999999999999998e+23                      1                      1 
#>                   TRUE                   TRUE                   TRUE



expect_trues_l <- list(
  cl = sqrt(2)^2,
  pp = 9.0,
  t = 1 / (1 - 0.98),
  ar0 = 66L,
  ar1 = 66,
  ar2 = 1 + 2^-50,
  v = 222e3,
  w1 = 1e4,
  w2 = 1e5,
  v2 = "1000000000000000000000000000000000001",
  an = 2 / 49 * 49,
  ju1 = 1e22,
  ju2 = 1e24,
  al = floor(1),
  v5 = 1.0000000000000001 # this is under machine precision!
)

str(expect_trues_l)
#> List of 15
#>  $ cl : num 2
#>  $ pp : num 9
#>  $ t  : num 50
#>  $ ar0: int 66
#>  $ ar1: num 66
#>  $ ar2: num 1
#>  $ v  : num 222000
#>  $ w1 : num 10000
#>  $ w2 : num 1e+05
#>  $ v2 : chr "1000000000000000000000000000000000001"
#>  $ an : num 2
#>  $ ju1: num 1e+22
#>  $ ju2: num 1e+24
#>  $ al : num 1
#>  $ v5 : num 1
assertive::is_whole_number(expect_trues_l)
#> Warning: Coercing expect_trues_l to class 'numeric'.
#> There was 1 failure:
#>   Position              Value      Cause
#> 1        3 49.999999999999957 fractional
assertive::is_whole_number(expect_trues_l, tol = 200 * .Machine$double.eps)
#> Warning: Coercing expect_trues_l to class 'numeric'.
#>     2.0000000000000004                      9     49.999999999999957 
#>                   TRUE                   TRUE                   TRUE 
#>                     66                     66     1.0000000000000009 
#>                   TRUE                   TRUE                   TRUE 
#>                 222000                  10000                 100000 
#>                   TRUE                   TRUE                   TRUE 
#>                  1e+36     1.9999999999999998                  1e+22 
#>                   TRUE                   TRUE                   TRUE 
#> 9.9999999999999998e+23                      1                      1 
#>                   TRUE                   TRUE                   TRUE



expect_falses <- list(
  bb = 5 - 1e-8,
  pt1 = 1.0000001,
  pt2 = 1.00000001,
  v3 = 3243.34,
  v4 = "sdfds"
)

str(expect_falses)
#> List of 5
#>  $ bb : num 5
#>  $ pt1: num 1
#>  $ pt2: num 1
#>  $ v3 : num 3243
#>  $ v4 : chr "sdfds"
assertive::is_whole_number(expect_falses)
#> Warning: Coercing expect_falses to class 'numeric'.
#> Warning in as.this_class(x): NAs introduced by coercion
#> There were 5 failures:
#>   Position              Value      Cause
#> 1        1 4.9999999900000001 fractional
#> 2        2 1.0000001000000001 fractional
#> 3        3 1.0000000099999999 fractional
#> 4        4 3243.3400000000001 fractional
#> 5        5               <NA>    missing
assertive::is_whole_number(expect_falses, tol = 200 * .Machine$double.eps)
#> Warning: Coercing expect_falses to class 'numeric'.

#> Warning: NAs introduced by coercion
#> There were 5 failures:
#>   Position              Value      Cause
#> 1        1 4.9999999900000001 fractional
#> 2        2 1.0000001000000001 fractional
#> 3        3 1.0000000099999999 fractional
#> 4        4 3243.3400000000001 fractional
#> 5        5               <NA>    missing

reprex 패키지(v0.3.0)에 의해 2019-07-23에 생성되었습니다.

[OLD] =================================================================

IMO 최고의 솔루션은assertive패키지(현재로서는 이 스레드에서 모든 긍정적인 예와 부정적인 예를 해결합니다.):

are_all_whole_numbers <- function(x) {
  all(assertive::is_whole_number(x), na.rm = TRUE)
}

are_all_whole_numbers(c(
  cl = sqrt(2)^2,
  pp = 9.0,
  t = 1 / (1 - 0.98),
  ar0 = 66L,
  ar1 = 66,
  ar2 = 1 + 2^-50,
  v = 222e3,
  w1 = 1e4,
  w2 = 1e5,
  v2 = "1000000000000000000000000000000000001",
  an = 2 / 49 * 49,
  ju1 = 1e22,
  ju2 = 1e24,
  al = floor(1),
  v5 = 1.0000000000000001 # difference is under machine precision!
))
#> Warning: Coercing x to class 'numeric'.
#> [1] TRUE

are_all_not_whole_numbers <- function(x) {
  all(!assertive::is_whole_number(x), na.rm = TRUE)
}

are_all_not_whole_numbers(c(
  bb = 5 - 1e-8,
  pt1 = 1.0000001,
  pt2 = 1.00000001,
  v3 = 3243.34,
  v4 = "sdfds"
))
#> Warning: Coercing x to class 'numeric'.
#> Warning in as.this_class(x): NAs introduced by coercion
#> [1] TRUE

reprex 패키지(v0.3.0)에 의해 2019-07-23에 생성되었습니다.

사용자 고유의 함수를 작성하지 않으려면 패키지 설치 프로그램에서 시도하십시오.현재 그것은 VitoshKa의 답변을 사용합니다.

또한 패키지 varhandle에서 시도해 보십시오. varhandle은 벡터화되는 이점이 있습니다.

Once는 또한 사용할 수 있습니다.dplyr::near:

library(dplyr)

near(a, as.integer(a))

모든 벡터에 적용됩니다.a및 허용 오차 매개 변수(선택 사항)가 있습니다.

벡터의 경우m,m[round(m) != m]정수가 아닌 벡터의 값 인덱스를 반환합니다.

저는 당신이 무엇을 성취하려고 하는지 잘 모르겠습니다.하지만 여기 몇 가지 생각이 있습니다.
정수로 변환:
num = as.integer(123.2342)
변수가 정수인지 확인합니다.
is.integer(num)
typeof(num)=="integer"

언급URL : https://stackoverflow.com/questions/3476782/check-if-the-number-is-integer

반응형