프로그래밍 /R

R에서 함수 정의하기, 콜하기

yooj_lee 2019. 6. 12. 18:18
300x250

- R에서 사용자 정의 함수 사용하기

: 내가 A라는 기능을 수행하는 함수가 필요하지만 R에서는 제공하지 않을 때 직접 함수를 정의해서 사용할 수 있다.

 

1. 함수 정의하기

R에서 함수를 정의하는 방법은 c나 python과는 다르다(실은 c는 가물가물함 ㅎㅎ;).

기존에 내가 사용해왔던 python에서는

def func_name(arg1, arg2, ...):

    ...

    return ...(arg1, ...)

의 형식이었다면,

R에서는 def를 사용하지 않는다. 약간 function이라는 객체가 있고 그거 속성 지정을 해준 다음 함수 이름을 담은 변수에 넣어주는 느낌?

user.function <- function(arg1, arg2, ...){

      ...

      return(...(arg1, ...))

}

이렇게 정의한다. 아주 귀찮게도 return에 괄호를 붙여줘야 함. 난 R이 싫다..

 

2. 함수 인자(argument)

함수에 인자가 필요하지 않은 경우도 분명히 꽤 있겠지만 내가 대부분 정의해왔던 함수는 인자가 필요했다.

 

ex) 전달받은 숫자들의 합을 계산해주는 함수 sumNum()

sumNum <- function(arg1 = vec1){

     res <- 0

     for(i in vec1){

         res = res + i }

     return(res)

     }

 

하나 이상의 인자를 사용해 함수를 호출할 경우 인자의 이름 또는 입력 순서로 어떤 인자에 어떤 값이 들어가는지 명시할 수 있다.

ex) read.table(file, header = FALSE, sep = "", quote = "\"'", ...)

read.table()의 인자의 기본 순서는 file, header, sep, quote,...의 순이다.

이때 read.table(file, TRUE, ",") 이런 식으로 호출을 한다면 R은 알아서 header값을 포함하고, 콤마로 구분하여 파일을 읽어올 것이다.

혹은 read.table(file, sep = ",", header = TRUE) 이런 식으로 호출을 한다면 인자의 순서가 기본 설정과는 다르지만 인자에 이름을 붙여주었으므로 알아서 잘 위의 경우와 같은 결과를 리턴할 것이다.

 

1) 기본 인자(default)

함수의 기본 인자는 단순히 말해 함수의 인자에 미리 값을 지정해놓는 것이다. 인자 값에는 모든 종류의 R 객체가 가능하다. 기본 인자를 설정해두면 함수를 호출할 때 해당 인자에 값을 전달하지 않아도 기본적으로 설정된 값을 적용해 함수 결과를 도출해낸다.

위의 read.table()함수를 다시 보면, header = FALSE라고 적혀있다. 이때 header의 디폴트값은 FALSE인 것이다. 따라서 read.table()을 콜할 때 header값을 따로 TRUE로 지정해주지 않는 한 header를 미포함하여 파일을 읽어올 것이다. 이때 read.table()은 header의 기본인자로 logical 타입의 값을 가진 것이다.

 

2) 여분 인자(extra)

R은 함수가 함수 정의에서 명시되지 않은 임의의 개수의 인자를 받아들일 수 있는 특별한 연산자, '...'를 제공한다. (... 가 연산자임)

func1 <- function(arg1, arg2, ...){

     return()

}

 

arg2 다음에 ... 연산자를 명시해줌으로써 함수를 호출할 때 2개 이상의 인자를 전달할 수 있게 된다. 다만, 이때 주의할 점은 여분 인자가 무엇인지 이름 혹은 순서를 통해 명시해주어야 한다는 것이다.

ex) 이름을 통해 명시 -> func1(arg1 = arg1, arg3 = arg3, arg2= arg2) ; 이때 arg3는 원래 인자 이름이 아니므로 알아서 여분 인자로 인식한다.

순서를 통해 명시 -> func1('1', '2', '3'); 이때 함수는 arg1 = '1', arg2 = '2'로 인식하고 3번째에 온 '3'은 자동적으로 여분 인자로 인식한다.

 

3) 리턴 값

함수는 일반적으로 사용자에게 값을 되돌려주는 구조다. 즉, 어떤 값을 리턴해야 한다(수학에서 X -> Y 로 대응되듯이). 함수에 return()을 명시하지 않은 경우 마지막 라인의 값이 자동으로 리턴된다. (별로 좋은 방법은 아님.)

당연한 말이지만, return()을 통해 리턴되어야할 값을 명확히 지정하는 것이 훨씬 좋다. 함수는 return()문을 만나면 무조건 종료된다. 그 다음에 오는 문장은 수행하지 않는다. 

 

3. 함수 호출

1) 함수명(인자)

가장 보편적인 함수 호출 방법. 직관적이다. (내 뇌피셜ㅎㅎㅎ)

2) do.call

잘 사용되진 않지만,  함수를 호출하는 또 다른 방법으로 do.call()이 있다. 이 함수는 character 또는 객체로 함수의 이름을 지정하고 리스트를 사용하여 해당 함수의 인자를 제공하게 한다.

 

do.call("sumNum", args = list(arg1 = vec1))

→ 이런 식으로 커맨드를 작성

 

사용자가 액션을 지정할 수 있게 하는 함수를 작성할 때 특히 유용하다. 

 

run.this <- function(x, func = mean){

    do.call(func, args = list(x))

} #func 인자에 mean이 기본 인자로 설정.

run.this(1:10) #기본적으로 mean을 찾는 함수

> 5.5

run.this(1:10, sum) #합을 계산하도록 func자리에 sum함수를 전달.

> 55

 

python의 map함수랑 비슷한 것 같다(내 뇌피셜ㅎㅎㅎ2)

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

300x250