Lovetoken

저는 개발 취향을 가진 데이터 분석가 Jr. 입니다.

Navigation
 » Home
 » About Me
 » Github

R에서 연산자의 우선순위

08 Sep 2015 » R



Operator in R

R은 다양한 연산자(Operator)를 가지고 있다.
사칙연산 시 사용되는 -, +, *, / 뿐만 아니라
==, !=, <=, >= 와 같은 비교연산자,
=, <-, ?, : 등과 같은 것도 모두 연산자에 포함된다.
더 이야기하면 %blahblah% 꼴로 생긴 사용자가 따로 정의할 수 있는 연산자도 얼마든지 만들 수 있다.
이렇게 많은 연산자가 코드 한 줄에 다양하게 사용된다면 고려해야할 것이 연산자의 실행 우선순위가 있겠다.

?Syntax 를 R콘솔에 작성하여 실행하면 기본연산자들의 목록이 수행절차에 대한 우선순위별로 정리된 문서가 뜬다.
예를 들어 곱셈 *과 덧셈 +이 같이 있는 식의 경우, 곱셈을 먼저 계산하고 그 다음 덧셈을 계산해야 할 것이다.
이 경우 덧셈과 곱셈 중 우선순위는 곱셈이 더 높은 것이다.
이처럼 R의 다양한 연산자들이 조합될 때 계산의 순서를 결정짓는 우선순위를 알고싶다면 ?Syntax 로 열리는 도움말을 참고한다.
아래의 그림이 도움말을 연 경우인데 맨 위의 연산자가 가장 높은 순으로 계산수행이 시작된다.





Question

연산자에 대한 자주 나오는 질문들이 있는데 대표적으로 몇 개만 나열해 보았다.
연산자의 우선순위에 대해 정확히 알게 된다면 해결되는 문제들이다.


<-= 의 차이가 무엇인가요??

<-= 는 오른쪽에 반환되는 값을 왼쪽에 할당하는 할당연산자1로 의미는 똑같다.
하지만 한가지 차이가 = 보다는 <- 이 더 우선적으로 실행된다는 차이가 존재할 뿐이다.
예를 들어 B 객체에 25 라는 값을 입력하고 AB를 입력하는 코드를 다음과 같이 작성하였다고 가정할 때 굳이 <-, = 두개의 할당연산자를 혼용해 보았다.

A <- B = 25

그런데 위의 코드가 정상적으로 동작할까?
그렇지 않다.

왜냐하면 = 보다 <- 가 먼저 수행이 될 텐데 B 객체에는 세상에 존재하지 않는 친구이다.
따라서 A 에 할당시켜야 하는 값을 R은 알지 못하여 에러가 난다.

## Error in A <- B = 25 : object 'A' not found

B 가 25라는 값으로 먼저 할당되기 위하여 아래와 같은 방법들을 이용하게 될 것이다.

  • 한 줄짜리 코드를 단락을 나누어 수행순서 강제 변경
B <- 25
A <- B
  • 괄호를 이용하여 수행순서 강제 변경
A <- (B = 25)
  • 정말로 연산자의 우선순위를 고려한 코딩
A = B <- 25
  • 할당연산자를 통일시킴
A = B = 25
A <- B <- 25


음의정수값 연산이 생각대로 안되요

-10^2
## [1] -100

-10 의 제곱은 100이지만,
위의 코드가 100이 반환되기를 기대한 순간 ?Syntax 를 다시 참고할 시간인 것이다.
나는 항상 100이 되길 기대하기 때문에 빈번히 연산자 우선순위를 다시 기억하기 위해 ?Syntax 도움말을 열어본다..

  • -보다 ^이 먼저 수행되는 문제를 괄호를 통해 해결
(-10)^2
## [1] 100
  • -10 의 값을 사전에 객체로 할당하고, 그 객체에 제곱을 취함
C <- -10
C^2
## [1] 100


seq(2, 20, by=2): 연산자를 통하여 더 간단한 코드로 만들고 싶습니다

seq(2, 20, by=2) 의 결과를 잘 살펴보면

seq(2, 20, by = 2)
##  [1]  2  4  6  8 10 12 14 16 18 20

1:10 의 모든 결과값에

1:10
##  [1]  1  2  3  4  5  6  7  8  9 10

2를 곱한 것과 같다.

(1:10)*2
##  [1]  2  4  6  8 10 12 14 16 18 20

그런데 (1:10)*2 의 코드가 사실 가장 간단히 구현된 코드가 아니었다.
연산자 우선순위를 잘 알지 못한다면 습관적으로 1:10이 먼저 수행되어야 한다는 생각에 괄호를 본능적으로 둘러싸게 될 텐데,
그렇지 않더라도 : 연산자는 * 보다 우위에 있으므로 1:10 을 먼저 계산 이후에 곱 연산 * 을 수행한다.
따라서 괄호를 생략하고 아래와 같이 코드를 작성해도 된다.

1:10*2
##  [1]  2  4  6  8 10 12 14 16 18 20

이밖에도 연산자 우선순위에 대한 추가 예제는 ?Syntax 의 예제코드에 훌륭한 것이 많다.

## Logical AND ("&&") has higher precedence than OR ("||"):
TRUE || TRUE && FALSE   # is the same as
TRUE || (TRUE && FALSE) # and different from
(TRUE || TRUE) && FALSE

## Special operators have higher precedence than "!" (logical NOT).
## You can use this for %in% :
! 1:10 %in% c(2, 3, 5, 7) # same as !(1:10 %in% c(2, 3, 5, 7))
## but we strongly advise to use the "!( ... )" form in this case!


## '=' has lower precedence than '<-' ... so you should not mix them
##     (and '<-' is considered better style anyway):
## Consequently, this gives a ("non-catchable") error
 x <- y = 5  #->  Error in (x <- y) = 5 : ....

  1. 사실 할당연산자 중 -> 도 존재한다 방향이 반대이니 이 연산자를 기준으로 왼쪽편에 있는 코드의 반환값을 오른쪽으로 할당한다. <<- 와 같은 할당연산자도 있는데 어떤상황이든 전역환경(global environment)으로 지정하여 할당하는 특수한 할당연산자이다↩︎