16.6 R의 Infix 연산자
이 절에서는 infix 연산자에 대해 알아 보겠습니다. 이러한 연산자가 R에서 실제로 어떻게 작동하는지, 그리고 infix 연산자를 직접 만드는 방법 등에 대하여 알아 보겠습니다. 또한 R 프로그래밍에서 사용할 수 있는 사전에 정의된 다양한 infix 연산자에는 어떤 것이 있는지 알아 보겠습니다.
R에서 사용하는 대부분의 연산자는 이항 연산자(두 개의 피연산자를 가짐)입니다. 따라서 이들은 피연산자와 피연산자 사이에 사용되는 infix 연산자라고 할 수 있습니다. 실제로 이러한 연산자는 백그라운드에서 함수를 호출합니다.
예를 들어 a + b
라는 수식은 실제로는 +(a, b)
와 같이 인수 a
와 b
를 받아들여 ` + `
()
함수를 호출하는 것과 같습니다.
참고 : 백틱 (``) 기호를 주목하기 바랍니다. 함수 이름에서 +를 특수 기호로 인식하기 때문에 백틱으로 묶어 줘야 합니다.
다음은 백그라운드에서 호출되는 실제 함수와 함께 몇 가지 예제 수식입니다.
16.6.1 infix 연산자의 작동 예
5 + 3
## [1] 8
`+`(5,3) # 5 + 3의 +연산자를 함수로 표현한 것입니다
## [1] 8
5 - 3
## [1] 2
`-`(5,3)
## [1] 2
5 * 3 - 1
## [1] 14
`-`(`*`(5,3),1)
## [1] 14
앞의 예를 보면 이제 R에서 사용자 정의 infix 연산자를 만들 수도 있는 것입니다. 이러한 infix 연산사를 위한 함수의 이름은 %
로 시작하고 끝나게 정의합니다.
다음은 숫자가 정확히 다른 숫자로 나누어 지는지를 확인하는 사용자 정의 infix 연산자를 정의하는 함수입니다.
16.6.2 사용자 정의 infix 연산자의 예
`%divisible%` <- function(x,y) {
if (x%%y ==0) return (TRUE)
else return (FALSE)
}
This function can be used as infix operator a %divisible% b
or as a function call `%divisible%
(a, b)`. Both are the same.
이 함수는 infix 연산자a %divisible% b
또는 함수 호출`%divisible%(a, b)
로 사용할 수 있습니다.
<- c(4, 8, 6, 3)
x <- c(2, 3, 2, 2)
y %divisible% y x
## Warning in if (x%%y == 0) return(TRUE) else return(FALSE): length > 1 이라는 조
## 건이 있고, 첫번째 요소만이 사용될 것입니다
## [1] TRUE
`%divisible%`(x, y)
## Warning in if (x%%y == 0) return(TRUE) else return(FALSE): length > 1 이라는 조
## 건이 있고, 첫번째 요소만이 사용될 것입니다
## [1] TRUE
참고로 2개의 벡터 x
, y
를 인수로 받아 들여, 이 두 벡터의 요소 각각에 대한 %divisible%
연산자를 적용하는 함수를 생성해 보았습니다.
## 요소의 갯수가 적은 벡터를 자동 반복으로 채워주는 함수입니다.
<- function(x, j, k) { # x : 짧은 벡터이며,
vec.cycle # j : 벡터 전체의 자동반복 횟수
# k : 마지막으로 채워 넣어야 할 요소의 수입니다.
<- x
vec if (j>=2) { # 벡터 전체를 자동 반복으로 복사합니다.
for (t1 in 1:(j-1)) vec <- c(vec, vec)
}
for (t2 in 1:k) # 남은 요소를 자동으로 채워 넣기 합니다.
<- c(vec, vec[t2])
vec
return(vec)
}
## infix 연산자를 정의합니다.
`%divisible%` <- function(x, y, na.rm = FALSE) {
# if (na.rm == TRUE) {
# x <- x[!is.na(x)]
# y <- y[!is.na(y)]
# }
<- length(x) # x 벡터의 길이를 반환합니다.
len.x <- length(y) # y 벡터의 길이를 반환합니다.
len.y
if (len.x >= len.y) { # 벡터 x가 긴 경우입니다.
<- len.x %/% len.y # 벡터 전체를 반복할 횟수를 계산합니다.
j <- len.x %% len.y # 부족한 벡터 요소 갯수를 계산합니다.
k <- vec.cycle(y, j, k) # y를 자동반복으로 채워줍니다.
y
}else {
<- len.y %/% len.x
j <- len.y %% len.x
k <- vec.cycle(x, j, k)
x
}
# result <- NULL
# for (i in 1:length(x)) { # 각 요소별로 %% 연산 결과를 저장합니다.
# if (x[i] %% y[i] == 0) result[i] <- TRUE
# else result[i] <- FALSE
# }
# return(result) # 최종 연산결과를 반환합니다.
return(x %% y == 0) # x의 요소 각각을 y의 요소 각각으로 나누어지는지 결과를 반환한다.
}
# 데이터 벡터입니다.
<- c(2, 3, 2)
x <- c(4, 8, 6, 2, 4, 3, 8, 7)
y
# 두 벡터 데이터를 확인합니다.
%divisible% y x
## [1] FALSE FALSE FALSE TRUE FALSE FALSE FALSE FALSE
자신만의 infix 연산자를 정의할 때 기억해야 할 점은 연산자의 이름은 %
로 시작하고 %
로 끝나야 한다는 것입니다. 함수를 정의할 때 함수 이름을 백틱(``
)으로 묶어서 %
를 이스케이프 시켜 주어야 합니다.
16.6.3 R에 미리 정의되어 있는 infix 연산자
기호 | 설 명 |
---|---|
%% | 나머지 연산자 |
%/% | 몫 연산자 |
%*% | 행렬 곱하기 |
%o% | 아웃터 곱하기 |
%x% | Kronecker 곱하기 |
%in% | 대응 연산자 |