[r] R의 전역 및 지역 변수

나는 R의 초보자이며 R의 지역 및 전역 변수 사용법과 혼동됩니다.

인터넷 에서 현재 환경에서 변수를 사용 =하거나 <-할당 할지 여부를 나타내는 게시물을 읽었 <<-으며 함수 내부에서 전역 변수에 액세스 할 수 있습니다.

그러나 C ++에서 기억할 때 괄호 안에 변수를 선언 할 때마다 로컬 변수가 발생 {}하므로 이것이 R에 대해 동일한 지 궁금합니다. 아니면 지역 변수의 개념을 갖는 것이 R의 함수 일뿐입니다 .

나는 약간의 실험을했는데, 대괄호만으로는 충분하지 않다고 제안하는 것 같습니다.

{
   x=matrix(1:10,2,5)
}
print(x[2,2])
[1] 4



답변

함수 내부에 선언 된 변수는 해당 함수에 로컬입니다. 예를 들어 :

foo <- function() {
    bar <- 1
}
foo()
bar

다음과 같은 오류가 발생 Error: object 'bar' not found합니다.

bar전역 변수 를 만들려면 다음을 수행해야합니다.

foo <- function() {
    bar <<- 1
}
foo()
bar

이 경우 bar기능 외부에서 액세스 할 수 있습니다.

그러나 C, C ++ 또는 다른 많은 언어와 달리 대괄호는 변수의 범위를 결정하지 않습니다. 예를 들어 다음 코드 스 니펫에서

if (x > 10) {
    y <- 0
}
else {
    y <- 1
}

yif-else진술 후에도 접근 가능 합니다.

잘 말하지만, 중첩 환경을 만들 수도 있습니다. 사용 방법을 이해하기 위해이 두 링크를 살펴볼 수 있습니다.

  1. http://stat.ethz.ch/R-manual/R-devel/library/base/html/environment.html
  2. http://stat.ethz.ch/R-manual/R-devel/library/base/html/get.html

여기 작은 예가 있습니다.

test.env <- new.env()

assign('var', 100, envir=test.env)
# or simply
test.env$var <- 100

get('var') # var cannot be found since it is not defined in this environment
get('var', envir=test.env) # now it can be found


답변

<- 현재 환경에서 할당합니다.

함수 안에있을 때 R은 새로운 환경을 만듭니다. 기본적으로 변수는 작성된 환경의 모든 것을 포함하므로 해당 변수를 사용할 수는 있지만 새로 작성한 것은 글로벌 환경에 기록되지 않습니다.

대부분의 경우 <<-전역 환경에 이미있는 변수에 할당하거나 함수 내부에 있더라도 전역 환경에 변수를 만듭니다. 그러나 그렇게 간단하지는 않습니다. 그것이하는 일은 부모 환경에서 관심있는 이름의 변수를 확인하는 것입니다. 부모 환경에서 찾지 못하면 부모 환경의 부모로 이동하여 (함수가 생성 된 시점) 그 곳을 봅니다. 글로벌 환경으로 계속 올라가며 글로벌 환경에서 찾지 못하면 글로벌 환경에서 변수를 할당합니다.

이것은 무슨 일이 일어나고 있는지 보여줄 수 있습니다.

bar <- "global"
foo <- function(){
    bar <- "in foo"
    baz <- function(){
        bar <- "in baz - before <<-"
        bar <<- "in baz - after <<-"
        print(bar)
    }
    print(bar)
    baz()
    print(bar)
}
> bar
[1] "global"
> foo()
[1] "in foo"
[1] "in baz - before <<-"
[1] "in baz - after <<-"
> bar
[1] "global"

우리가 인쇄 막대를 처음 인쇄 할 때 foo아직 전화 하지 않았으므로 여전히 전역 적이어야합니다. 두 번째로 인쇄 foo하기 전에 호출하기 전에 baz“in foo”값이 의미가 있습니다. 다음은 <<-실제로 무엇을 하고 있는지 보여 줍니다. print 문이 다음에 오는 경우에도 다음으로 인쇄되는 값은 “baz-before <<-” <<-입니다. 때문이다 <<-(당신이 경우에하는 글로벌 환경에서가 아니라면 현재의 환경에서 보이지 않는 <<-같은 역할 <-). 따라서 bazbar 값의 내부는 “baz에서-<<-“이전으로 유지됩니다. 우리가 호출 baz하면 내부의 막대 사본이 foo“in baz”로 변경되지만 전역 bar에서 변경되지 않은 것을 볼 수 있습니다 .bar내부에 정의되는 foo우리가 만들 때 부모 환경에 baz이의 첫 번째 복사본 그래서 bar<<-보고, 따라서 그것을에 할당 복사합니다. 그래서 <<-그냥 직접 지구 환경에 할당되지 않습니다.

<<-까다 롭고 피할 수 있다면 사용하지 않는 것이 좋습니다. 글로벌 환경에 실제로 할당하려면 assign 기능을 사용하여 글로벌로 할당하겠다고 명시 적으로 지정할 수 있습니다.

이제 <<-assign 문으로 변경하고 어떤 영향을 미치는지 볼 수 있습니다.

bar <- "global"
foo <- function(){
    bar <- "in foo"
    baz <- function(){
        assign("bar", "in baz", envir = .GlobalEnv)
    }
    print(bar)
    baz()
    print(bar)
}
bar
#[1] "global"
foo()
#[1] "in foo"
#[1] "in foo"
bar
#[1] "in baz"

따라서 foo호출 한 후에도 값 내부에 bar를 인쇄 할 때마다 “in foo”가 baz됩니다. foo 내부의 assign복사본을 고려하지 않았기 때문입니다. 왜냐하면 bar정확히 어디를보아야하는지 말했기 때문입니다. 그러나 이번에는 전역 환경에서 bar의 값이 명시 적으로 지정되어 변경되었습니다.

이제 로컬 변수를 만드는 것에 대해서도 물었고 함수를 만들지 않고도 상당히 쉽게 할 수 있습니다 … 함수를 사용해야합니다 local.

bar <- "global"
# local will create a new environment for us to play in
local({
    bar <- "local"
    print(bar)
})
#[1] "local"
bar
#[1] "global"


답변

같은 줄을 따라 조금 더

attrs <- {}

attrs.a <- 1

f <- function(d) {
    attrs.a <- d
}

f(20)
print(attrs.a)

“1”을 인쇄합니다

attrs <- {}

attrs.a <- 1

f <- function(d) {
   attrs.a <<- d
}

f(20)
print(attrs.a)

“20”을 인쇄합니다


답변