본문 바로가기
R/Data Operation

R 함수 Function - 함수정의/함수인자/재귀중첩함수

by 통계열등생 2020. 11. 3.
반응형

특정 코드블록을 반복적으로 써야할 때 함수를 작성하면 코드의 반복을 줄일 수 있고, 코드의 가독성도 높일 수 있다.

함수를 실행하기 위해서는 반드시 호출을 해야한다. 호출하는 방법은 함수이름 뒤에 소괄호( )를 붙이는 것이다. 이를 함수호출(function call)이라고 한다.

 

 

 

 ◎ 함수정의

 

함수명 = function( 인자1, 인자2, ... ) {
    실행문
    return( 반환값 )
}

 

  • 인자가 없는 함수
> pi_1 = function() {
+   cat(3.141592653589793)
+ }
> pi_1()
3.141593
> x = pi_1()
3.141593
> x
NULL

인자가 없이 pi값을 출력하는 함수이다. return은 생략할 수 있지만 pi값을 x 객체로 받으려해도 x 객체에는 NULL 값이 저장되어버린다. 

 

> pi_2 = function() {
+   return(3.141592653589793)
+ }
> pi_2()
[1] 3.141593
> x = pi_2()
> x
[1] 3.141593

return을 사용해주면 pi값을 x 객체로 받을 수 있게 된다.

 

 

  • 인자가 있는 함수
> state = function(fname, data) {
+   switch(fname, 
+          SUM = sum(data), 
+          AVG = mean(data), 
+          VAR = var(data), 
+          SD = sd(data))
+ }
> state('SUM', 1:10)
[1] 55

swith() 함수를 사용해서 함수이름과 데이터를 인자로 받는 함수를 만들었다.

 

swith() 함수 더 알아보기

small22.tistory.com/16

 

R 조건문

조건문은 조건이 참인지 거짓인지에 따라 달라지는 계산이나 상황을 수행한다. 조건문에도 종류가 여러가지 있다.  ◎ if if( 조건식 ) 실행문 > score = 85 > if(score >= 80) cat('합격') 합격 > if(score >=..

small22.tistory.com

 

> state
function(fname, data) {
  switch(fname, 
         SUM = sum(data), 
         AVG = mean(data), 
         VAR = var(data), 
         SD = sd(data))
}
> body(state)
{
    switch(fname, SUM = sum(data), AVG = mean(data), VAR = var(data), 
        SD = sd(data))
}

어떤 함수의 몸체를 알고 싶다면 body(함수이름) or 함수이름을 입력한다.

 

 

  • 리턴이 있는 함수
> calc = function(x, y) {
+   add = x + y; cat(x, '+', y, '=', add, '\n')
+   sub = x - y; cat(x, '-', y, '=', sub, '\n')
+   mul = x * y; cat(x, '*', y, '=', mul, '\n')
+   div = x / y; cat(x, '/', y, '=', div, '\n')
+   
+   calc_df = data.frame(add, sub, mul, div, row.names='값')
+   return(calc_df)
+ }
> df = calc(100, 20)
100 + 20 = 120 
100 - 20 = 80 
100 * 20 = 2000 
100 / 20 = 5 
> df
   add sub  mul div
값 120  80 2000   5

return은 지정한 값을 외부로 반환하는 역할을 한다. 하지만 return(add, sub, mul, div) 같은 두 개 이상의 다중인자는 반환할 수 없고 error가 발생한다.

 

 

 

 ◎ 함수인자

 

  • 위치 인자
> f1 = function(x, y, z) {
+   print(x)
+   print(y)
+   print(z)
+ }
> f1(1, 2, 3)
[1] 1
[1] 2
[1] 3

인자가 2개 이상이면 값은 인자의 위치에 따라 순서대로 할당된다.

 

 

  • 이름 인자
> f1(z=1, x=2, y=3)
[1] 2
[1] 3
[1] 1
> f1(z=1, 2, 3)
[1] 2
[1] 3
[1] 1
> f1(1, z=2, x=3)
[1] 3
[1] 1
[1] 2

호출할 때 인자의 이름을 지정하면 순서에 상관없이 값을 할당할 수 있다.

인자의 위치와 이름에 의한 값할당을 혼용해서 사용할 수도 있다. 인자의 이름을 지정한 값이 먼저 할당되고 다음으로 이름이 지정되지 않은 값들이 순서대로 할당된다.

 

 

  • 기본값 인자
> f2 = function(x, y, z=3) {
+   print(x)
+   print(y)
+   print(z)
+ }
> f2(1, 2)
[1] 1
[1] 2
[1] 3

함수를 정의할 떄 인자의 기본값(Default Value)을 지정할 수 있다. 인자이름에 등호를 사용하여 기본값을 지정한다.

세번째 인자 z에 3을 기본값으로 주었고, 함수를 호출할 때 두 개의 값만 입력한다면 z 인자는 기본값이 할당된다. 

 

 

  • 가변길이 인자
> f3 = function(...) {
+   cat(...)
+ }
> f3(1:10)
1 2 3 4 5 6 7 8 9 10
> f3('kim', 150, TRUE)
kim 150 TRUE

"..." 인자는 인자의 개수가 정해지지 않거나, 함수 안에서 다른 함수를 호출할 때 필요한 인자를 명시할 용도로 사용한다.

아래 예시는 이전에 정의한 f1 함수를 f4 함수 안에서 호출하여 정의하는 것이다.

 

> f4 = function(r, ...) {
+   cat('r =', r, '\n')
+   f1(...)
+ }
> f4(1, 2, 3, 4)
r = 1 
[1] 2
[1] 3
[1] 4

 

 

 

 ◎ 함수안에 함수

 

  • 재귀함수
> fact = function(n) {
+   if(n == 0) return(1)
+   return(n * fact(n-1))
+ }
> fact(5)
[1] 120
> 5 * 4 * 3 * 2 * 1
[1] 120

재귀함수(Recursive Function)는 함수안에서 자기자신을 호출하는 함수이다.

재귀함수에서 가장 많이 쓰이는 예시로 팩토리얼(Factorial)을 계산하는 함수를 작성하였다.

 

 

  • 중첩함수
> func = function(x, y) {
+   print(x)
+   
+   func_re = function(y) {
+     print(y^2)
+   }
+   func_re(y)
+ }
> func(10, 2)
[1] 10
[1] 4

새로운 함수를 정의할 때 함수안에서 또 다른 함수를 정의하여 사용할 수 있다.

외부함수 func에 인자를 두 개 전달하면 두번째 인자가 내부함수 func_re에 전달되어 코드를 실행한다.

 

> func2 = function(x) {
+   return(function(y) print(x + y))
+ }
> a = func2(1)
> a(2)
[1] 3
> class(a)
[1] "function"
>
> b = func2(2)
> b(2)
[1] 4

중첩함수의 또다른 예시로 return 안에 함수를 정의하고, func2 함수의 리턴값을 a 객체로 받게되면 a는 y 인자를 받을 수 있는 함수가 된다. class() 함수로 자료구조를 확인해보면 ''function" 이 출력되는 것을 알 수 있다.

 

 

 

 

 

<R 함수 Function - 함수정의/함수인자/재귀중첩함수>

반응형

댓글