더북(TheBook)

변수는 내부 블록에서만 접근할 수 있으므로 함수 내부에 정의한 이름은 함수 바깥에서 접근할 수 없다.

> rm(list = ls())
> f <- function() {
+ n <- 1
+ }
> f()
> n
Error : object 'n' not found

함수 내에서 이름은 함수 안의 변수들로부터 먼저 찾는다. 같은 이유로 함수 인자의 변수명 역시 전역 변수보다 우선한다.

> n <- 100
> f <- function(n) {
+ print(n)
+ }
> f(1)
[1] 1

중첩 함수에도 같은 규칙이 적용된다. 다음 코드에서 함수 g( ) 안에는 변수 a가 선언되어 있지 않다. 따라서 R 언어는 g( ) 함수를 감싼 함수 f( )로부터 변수 a를 찾는다.

> f <- function(x) {
+   a <- 2
+   g <- function(y) {
+     print(y + a)
+   }
+   g(x)
+ }
> f(1)
[1] 3

그러나 만약 함수 f( )마저도 변수 a를 포함하고 있지 않다면 전역 변수 a를 사용하게 된다.

> a <- 100
> f <- function(x) {
+   g <- function(y) {
+   print(y + a)
+   }
+   g(x)
+ }
> f(1)
[1] 101

내부 블록에서 외부 블록에 선언된 값을 수정하고자 할 때는 주의가 필요하다. 내부 블록이 외부 블록보다 우선하므로 <-를 사용한 값의 할당 시, 값이 할당되는 대상이 내부 블록으로 간주되기 때문이다. 예를 들어, 함수 f( ) 안에 변수 a가 있고 중첩된 함수 g( )에서 함수 f( ) 안의 변수 a에 값을 할당하려고 하는 다음 코드를 살펴보자.

> f <- function() {
+   a <- 1
+   g <- function() {
+     a <- 2
+     print(a)
+   }
+   g()
+   print(a)
+ }
> f()
[1] 2
[1] 1

이 코드에서는 함수 g( )에서 함수 f( )에 선언된 변수 a에 2를 할당하려 했지만 <-는 함수 g( ) 내부에 새로운 변수 a를 만들고 해당 변수에 2를 할당한다. 따라서 f( )에서 print(a)가 수행될 때 출력은 2가 아니라 1이 된다. 만약 함수 g에서 함수 f( ) 안의 변수 또는 전역 변수에 값을 할당하려면 <<-를 사용해야 한다.

> b <- 0
> f <- function() {
+   a <- 1
+   g <- function() {
+     a <<- 2
+     b <<- 2
+     print(a)
+     print(b)
+   }
+   g()
+   print(a)
+   print(b)
+ }
> f()
[1] 2
[1] 2
[1] 2
[1] 2

실행 결과 g( ) 안에서 <<-를 사용한 값의 할당은 함수 f( )에 선언된 a와 전역 변수인 b를 대상으로 이루어졌음을 볼 수 있다.

신간 소식 구독하기
뉴스레터에 가입하시고 이메일로 신간 소식을 받아 보세요.