3판 맛보기) R에서 정수형(integer)과 실수형(numeric)
R에서 수치형(numeric)은 보통 실수를 의미한다.[아래 각주 1 참조] 실수는 많은 경우 출력되는 값과 저장된 값이 정확하게 일치하지 않는다. 왜냐하면 R에서 실수를 저장하는 방식은 2진법이고, 출력되는 방식은 10진법이기 때문이다. 예를 들어 3진법의 0.1은 1/3을 나타내고 10진법으로 는 0.333⋯이므로, 10진법으로 정확하게 나타낼 수 없다. (순환소수를 나타내는 0.3̇(위에 점) 같은 표기는 제외하자.) 2진법에서 0.1은 10진법 0.5와 같다. 따라서 10진법 0.5는 2진법으로도 정확하게 나타낼 수 있다. 하지만 10진법 0.1을 2진법으로 나타내보자.
$$0.1_{(10)} = 0.0001100110011⋯_{(2)}$$
R의 실수(numeric) 클래스로 숫자 정수를 나타낼 때에도 조심해야 한다. 다음을 보자.
3e+07 - 1 ## [1] 3e+07 3e+07 - 5 ## [1] 3e+07
30000000은 R의 실수 클래스(numeric) 이다. 실수 클래스로 정수를 나타낼 때에는 값이 커질 수록 정확한 값을 저장할 수 없다. 반면 정수 클래스는 정확한 값을 저장한다(정수 클래스임을 분명히 하기 위해 숫자 뒤에 L을 붙인다). 따라서 계산 결과도 정확하다.
30000000L - 1L ## [1] 29999999
R의 정수 클래스와 숫자 정수가 헷갈릴 수 있다. 숫자 정수란 우리가 흔히 생각하는 정수 이다. R의 정수 클래스란 우리가 생각하는 숫자 정수를 R에서 저장하는 방식을 의미한다. 서문에서도 얘기했듯이 R의 정수 클래스가 저장할 수 있는 정수는 크기에 제한이 있다. 현재 컴퓨터의 한계는 다음과 같이 확인할 수 있다.
.Machine$integer.max ## [1] 2147483647
다음과 같은 실험을 해보자. R의 실수 클래스는 더 큰 정수를 저장할 수 있다.
.Machine$integer.max + 1 ## [1] 2147483648 .Machine$integer.max + 1L ## Warning in .Machine$integer.max + 1L: 정수형 오버플로우에 의하여 생성된 ## NA입니다 ## [1] NA
이렇게 큰 정수를 사용하면 R은 자동으로 실수형을 바꾼다. 그리고 그렇게 변환된 실수형은 정확한 값이 아니기 때문에 여러가지 논리 오류가 발생할 수 있다. 이렇게 큰 수가 필요하지 않다고 생각할 수도 있겠지만, 요즘같은 빅데이터 시대에 id가 위에서 확인한 .Mahcine$integer.max를 초과하는 경우가 점점 늘어나고 있다.
[각주 1]
as.numeric()은 실수 타입으로 변환하지만, is.numeric()은 실수 또는 정수 여부를 가린다.
출처> R로 하는 빅데이터 분석: 데이터 전처리와 시각화
Leave a comment