함수의 인자로 함수 쓰기
함수형 프로그래밍
함수형 프로그래밍 언어에서는 함수를 함수의 인자로 쓸 수 있다.
모두 함수가 무엇인지는 알 것이다.
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