본문 바로가기

R/R을 이용한 데이터 처리&분석 실무

연산

반응형

이 절에서는 연산자와 벡터 연산, NA가 포함된 데이터에서의 연산에 대해서 알아본다. 연산자에서 특히 벡터 연산과 NA가 포함된 데이터를 다루는 방법은 다른 언어와 차이가 있는 부분이니 유의해서 보기 바란다.

 

수치 연산

지금까지 암시적으로 사용한 사칙연산(+,-,*,/)을 포함한 수치 연산에 대해 알아보자. 사칙 연산은 다른 언어와 크게 다르지 않지만 약간의 문법적 차이가 있다. 다음 표에 연산자와 함수를 정의했다.

연산자와 함수 의미
+,-,*,/ 사칙 연산
n %% m n을 m으로 나눈 나머지
n %/% m n을 m으로 나눈 몫
n^m n의 m승
exp(n) e의 m승
log(x,base=exp(1)) log_(base)(x). 만약 base가 지정되지 않으면 log_(e)(x)를 계산
log2(x), log10(x) 각각 log_2(x), log_10(x)를 계산
sin(x), cos(x), tan(x) 삼각 함수

 

위 연산자는 다른 프로그래밍 언어와 크게 다른 점은 없지만, 다음 절에서 다룰 벡터 연산을 사용해 다수의 데이터에 연산을 한 번에 수행할 수 있다는 점을 알아둘 만하다. 다음 1,2,3,4,5 각각에 2를 곱한 뒤 1을 더한 예다. 각 숫자를 개별적으로 연산하는 것이 아니라 벡터에 통째로 연산자를 적용하고 있음을 눈여겨보기 바란다.

>1:5*2+1
[1]3 5 7 9 11

 

벡터 연산

벡터 연산(Vectorized Computation)(또는 Array Programming)은 벡터 또는 리스트를 한 번에 연산하는 것을 말한다. 벡터 연산이 중요한 이유는 for 문 등을 사용해 값을 하나씩 처리해나가는 대신 벡터나 리스트를 한 번에 처리하는 것이 더 효율적이고 편리하기 때문이다. 가장 간단한 예로 다음과 같이 벡터에 저장된 값을 1씩 증가시키는 경우를 살펴보자.

>x<-c(1,2,3,4,5)
>x+1
[1] 2,3,4,5,6

 

벡터끼리 연산하는 것도 가능하다. 앞서 '진릿값'에서 설명했듯이 벡터 간 연산 시에는 &&가 아니라 &를 사용한다.

>x<-c(1,2,3,4,5)
>x+x
[1]2 4 6 8 10

>x==x
[1]TRUE TRUE TRUE TRUE TRUE 

>x==c(1,2,3,5,5)
[1]TRUE TRUE TRUE FALSE TRUE 

>c(T,T,T)&c(T,F,T)
[1]TRUE FALSE TRUE 

 

R의 함수들은 기본적으로 이러한 벡터 기반 연산을 지원한다. 예를 들어, 다음과 같이 sum(), mean(), median()등은 벡터를 곧바로 인자로 받을 수 있다.

>x<-c(1,2,3,4,5)
>sum(x)
[1] 15

>mean(x)
[1]3

>median(x)
[1]3

 

ifelse()도 한 번에 적용 가능하다. 다음은 2로 나눈 나머지를 사용해 짝수(even), 홀수(odd)를 판별하는 예다.

>x<-c(1,2,3,4,5)
>ifelse(x %% 2==0, "even", "odd")
[1] "odd", "even", "odd", "even", "odd"

 

벡터 연산을 사용하면 데이터 프레임(Data Frame)에 저장된 데이터 중 원하는 정보를 쉽게 얻을 수 있다. 기본 원리는 데이터 프레임에 진릿값을 지정해 특정 행을 얻어올 수 있다는 점을 이용하는 것이다. 다음은 1행, 3행, 5행에 TRUE를 지정해 해당 행들만 데이터 프레임에서 가져오는 예다.

>(d<-data.frame(x=c(1,2,3,4,5), y=c("a","b","c","d","e")))
   x y
1 1 a
2 2 b
3 3 c
4 4 d
5 5 e

>d[c(TRUE, FALSE, TRUE, FALSE, TRUE),]
   x y
1 1 a
3 3 c
5 5 e

 

따라서 행의 선택 기준이 되는 TRUE, FALSE를 벡터 연산으로 만들어주면 특정 행을 선택할 수 있게된다. 다음은 x 값이 짝수인 행만 선택한 예다.

>d[d$x %% 2==0,]
   x y
2 2 b
4 4 d

 

NA의 처리

NA는 값이 기록되지 않았거나 관측되지 않은 경우 데이터에 저장되는 값으로 '결측치'라고 부른다. 예를 들어, 인구 조사에서 특정 가구가 소득을 묻는 항목에 답을 하지 않았다면 해당 값은 NA로 기록될 것이다. 데이터에 NA가 포함되어 있을 경우 연산 결과가 다음과 같이 NA로 바뀌어버리므로 주의가 필요하다.

>NA&TRUE
[1]NA

>NA+1
[1]NA

 

이러한 문제점을 해결하기 위해 많은 R함수에서 na.rm을 함수 인자로 받는다. na.rm은 NA값이 있을 때 해당 값을 연산에서 제외할 것인지를 지정하는 데 사용한다. 다음 예를 살펴보자.

>sum(c(1,2,3,NA))
[1]NA

>sum(c(1,2,3,NA), na.rm=TRUE)
[1]6

 

이처럼 NA 값에 따라 처리를 다르게 하려면 na.fail, na.omit, na.exclude, na.pass 함수를 사용한다. 또 다른 예로, 잘 알려진 기계 학습 패키지 중 하나인 caret(Classification and regression Training)은 NA 처리 방법을 결정한다. 아래에 이 함수들을 보였다.

함수 의미
na.fail(object) object에 NA가 포함되어 있으면 실패한다.
na.omit(object) object에 NA가 포함되어 있으면 이를 제외한다.
na.exclude(object,...) object에 NA가 포함되어 있으면 이를 제외한다는 점에서 na.omit과 동일하다. 그러나 naresid, napredict를 사용하는 함수에서 NA로 제외한 행을 결과에 다시 추가한다는 점이 다르다.
na.pass(object) object에 NA가 포함되어 있더라도 통과시킨다.

 

다음 예는 이 함수들의 차이를 보여준다.

>(x<-data.frame(a=c(1,2,3),b=c("a",NA,"c"),c=c("a","b",NA)))
   a     b    c
1 1     a    a
2 2  <NA> c
3 3     b <NA>

>na.fail(x)
Error in na.fail.default(x) : missing values in object

>na.omit(x)
   a  b  c
1 1  a  a

>na.exclude(x)
   a  b  c
1 1  a  a

>na.pass(x)
   a    b    c
1 1    a    a
2 2 <NA> b
3 3    c  <NA>

 

 따라서 NA를 어떻게 처리할지를 na.action이라는 함수 인자로 받았다면 'na.action(데이터프레임)'을 실행해 현재 처리 중인 데이터를 사용자가 원하는 대로 정제할 수 있다.

 

 

R을 이용한 데이터 처리&분석 실무 中

반응형

'R > R을 이용한 데이터 처리&분석 실무' 카테고리의 다른 글

아이리스 데이터  (0) 2020.01.31
함수의 정의  (0) 2020.01.30
흐름 제어(조건문과 반복문)  (0) 2020.01.30
타입 판별, 타입변환  (0) 2020.01.29
데이터 프레임  (0) 2020.01.29