R언어 함수와 스코프 (함수정의, 호출, 가변인자, 클로저)

2021. 3. 18. 03:11 기타/R언어

 

1. 함수 정의

다른언어와 마찬가지로 코드가 반복되거나 가독성을 높히려면 함수를 작성할 수 있다.

함수명 <- function(인자1, 인자2, ...) { 함수 본문 return(반환값) # 생략가능 }

이 때 반환값은 return()의 형태로 써줘야한다. return문을 생략하면 마지막 문장의 반환값을 return하게 된다.

2. 가변인자

가변인자는 ...로 표현한다. 함수를 정의할때 인자목록에 ...를 넣어주면 가변인자를 사용하겠다는 것이다. 함수를 호출할 때 정의된 인자갯수보다 많을 때에 가변인자에 해당된다.

> test1 function(...) { args <- list(...) for (i in args) { print(i) } } > test1(1,2,3,4,5) [1] 1 [1] 2 [1] 3 [1] 4 [1] 5

3. 스코프

다른언어와 마찬가지로 블록 스코프를 따른다. 그냥 콘솔에서 변수를 선언하고 할당하면 전역변수가 된다. 하지만 함수 내에 변수선언을 하게되면 지역변수가 된다. 만약 전역변수와 지역변수가 이름이 겹치면 지역변수가 우선한다.

여기서 <<- 를 활용할 수 있다. 지역변수와 전역변수명이 x로 같을 때 함수 내부에서 x <- 10 을 하면 지역변수 x에 할당되지만, x <<- 10 을 하면 전역변수 x에 할당된다!

x <- 3 scope1 <- function() { x <- 5 print(x) } scope2 <- function() { x <<- 5 print(x) }

라고 정의했을 때

> scope1() [1] 5 > x [1] 3

scope1() 실행 후엔 x값이 그대로지만,

> scope2() [1] 5 > x [1] 5

scope2() 실행 후엔 x값이 바뀌었다.

4. 함수 호출

R언어의 대부분은 함수 호출로 이루어진다. 함수 인자는 위치 또는 이름으로 지정할 수 있다.

예를들면

> test2 function(a, b, c, d) { return(a+b+c+d) } > test2(1,2,3,4) [1] 10 > test2(a=1,b=2,c=3,d=4) [1] 10 > test2(d=4,c=3,b=2,a=1) [1] 10

인자명을 지정하지않으면 위치순서로 인자가 넘겨지고 지정하면 인자명=값 형태로 넘길 수 있는 것이다. 또한 인자명은 풀네임을 꼭 안써도되고 구분할 수 있을 정도면 명시해주면 된다.

R언어는 모든 것이 객체다. 객체를 넘길 때 대부분 값에 의한 전달을 사용한다. 즉, 객체를 복사해서 전달한다는 뜻이다. 하지만 read 때 복사하는게 아니라 write 수행시에만 복사를 수행하기 때문에, 메모리사용량이나 성능같은 오버헤드는 크게 걱정하지 않아도 된다.

5. 클로저(closure)

중첩함수도 사용가능하다. JS처럼 클로저도 가능하다. 클로저를 사용하면 반환된 내부 함수가 외부 함수에 정의된 변수들에 접근할 수 있다.

> test3 function(a, b) { c <- a+b return(function(d, e) { f <- d+e return(c+f) }) } > x <- test3(3,4) > x function(d, e) { f <- d+e return(c+f) } > x(1,2) [1] 10

예제에서 a에는 3이, b에는 4가 할당되었고, d에는 1, e에는 2가 들어갔다.



출처: https://sjh836.tistory.com/115?category=719115 [빨간색코딩]