함수의 인자로 함수 쓰기
함수형 프로그래밍
함수형 프로그래밍 언어에서는 함수를 함수의 인자로 쓸 수 있다.
모두 함수가 무엇인지는 알 것이다.
f = function(x,y) {
return(x^y)
}
f(3,2)
## [1] 9
함수를 함수의 인자로
함수를 인자로 받아서 새로운 함수를 만드는 예를 들어보자.
g = function(f,z) {
return(function(x,y) f(x,y)^z)
}
h=g(f,2)
h(3,2)
## [1] 81
(3^2)^2
## [1] 81
h(3,2) == (3^2)^2
## [1] TRUE
함수 g는 함수 f를 인자로 받아서 새로운 함수를 반환한다. 새로운 함수의 인자는 x, y이고, 반환값은 f(x,y)^z가 된다. 위의 코드를 실행시키면 h에는 g(f,2), 다시 말해, 입력으로 x, y를 받으면, f(x,y)^2를 반환하는 함수가 담기게 된다. f(x,y)는 x^y이므로, f(x,y)^z은 (x^y)^2가 반환된다.
인자 함수(원래 함수)의 인자
함수를 인자로 주고 받을 때 문제의 하나는 함수의 인자를 처리하는 것이다.
예를 들어 apply()함수를 보자. apply(mat, 1, sum)은 행렬 mat의 행별로 합산(sum())을 한다. 그런데 합산 함수 sum()의 여러 옵션을 변경하려면 어떻게 해야 할까? 예를 들어 na.rm=TRUE로 변경하고자 한다면?
mat = matrix(c( 1,-3, 2,
-5, 3, 2,
1,-1,NA,
-3, 1, 2), 4,3, byrow=TRUE)
apply(X=mat, MARGIN=1, FUN=sum)
## [1] 0 0 NA 0
apply(mat, 1, sum)
## [1] 0 0 NA 0
함수를 인자로 받는 R의 함수들은 대부분 원래 함수의 나머지 인자 역시 인자로 넘겨 줄 수 있다. 예를 보자. 만약 위의 코드에서 각 행별로 sum(x, na.rm=T)를 하고 싶다면, 다음과 같이 쓸 수 있다.
apply(mat, 1, sum, na.rm=TRUE)
## [1] 0 0 0 0
만약 함수 apply의 인자와 함수 sum의 매개변수이름이 겹치지 않는다면, 함수 sum()의 모든 인자를 성공적으로 apply()에 넘겨 줄 수 있음을 주목하자. (아마도 함수 apply(X=, MARGIN=, FUN=)의 매개변수 이름이 X, MARGIN, FUN과 같이 대문자인 이유도 원래 함수와 매개변수 이름과 겹치지 않게 하려는 의미였을 것 같다.[1])
[1]: 함수 f=function(x) x^2; f(x=3)을 생각할 때 3은 인자(함수에 입력되는 값), 그리고 x는 매개변수라고 할 수 있다. 매개변수란 다시 말해 함수에 입력되는 값이 저장되는 변수라고 이해하면 된다.
인자 함수(원래 함수)의 인자를 새로운 함수의 인자로 받기
함수를 인자로 받는 함수에서 원래 함수의 인자를 처리하기 위해 ...를 쓸 수 있다(...는 영어로 dot-dot-dot이라고 하던데, 우리나라말로 직역하면 점점점 쯤 되려나?). 특히 원래 함수의 인자(매개변수) 이름이 무엇이고, 인자의 갯수가 몇 개인지 가늠할 수 없을 때 요긴하다. 예를 들어 모든 인자의 원소를 합하는 합계 함수를 직접 만들어 보자.
sum2 = function(...) { sum(sapply(list(...), sum)) }
sum2(c(1,3,2), c(4,2,2,1), c(-1,1,1,0,1))
## [1] 17
sum2(c(1,3,2), c(4,2,2,NA), c(-1,1,1,0,1))
## [1] NA
list(...)은 모든 인자를 리스트로 반환한다. 함수 sum2()는 그 리스트의 모든 원소에 대해 합을 하고, 그 합에 다시 합을 한다. 여기서 na.rm=과 같은 sum()의 매개변수와 인자를 받고 싶다면, 다음과 같이 할 수 있다.
sum3 = function(..., na.rm=FALSE) {
sum(sapply(X=list(...), FUN=sum, na.rm=na.rm), na.rm=na.rm)
}
sum3(c(1,3,2), c(4,2,2,1), c(-1,1,1,0,1))
## [1] 17
sum3(c(1,3,2), c(4,2,2,NA), c(-1,1,1,0,1))
## [1] NA
sum3(c(1,3,2), c(4,2,2,NA), c(-1,1,1,0,1), na.rm=TRUE)
## [1] 16
na.rm=na.rm에서 na.rm=는 sum()의 매개변수이름을 나타낸다. 뒤이어 나오는 na.rm는 sum3()의 인자로 받은 값을 나타낸다.
한 줄 요약
R에서 인자 함수의 불특정 다수의 인자를 처리하기 위해 ...(dot-dot-dot, 점점점)을 활용할 수 있다.
Leave a comment