숫자가 정수인지 확인합니다.
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
'programing' 카테고리의 다른 글
Android:그릴 수 있는 왼쪽 여백 및/또는 패딩 (0) | 2023.06.06 |
---|---|
웹 앱에서 새로운 Firebase Analytics 기능을 사용하려면 어떻게 해야 합니까? (0) | 2023.06.06 |
':app:checkDebugDuplicateClass' 작업을 실행하지 못했습니다.아이오닉 4 안드로이드 (0) | 2023.06.06 |
ggplot2에서 글꼴 변경 (0) | 2023.06.06 |
판다 데이터 프레임 열 dtype 할당 (0) | 2023.06.06 |