Вопрос по r – Глобальные и локальные переменные в R

110

Я новичок в R, и меня совершенно смущает использование локальных и глобальных переменных в R.

Я прочитал некоторые посты в интернете, которые говорят, если я использую= или же<- Я назначу переменную в текущей среде, и с<<- Я могу получить доступ к глобальной переменной внутри функции.

Однако, как я помню, в C ++ локальные переменные возникают всякий раз, когда вы объявляете переменную в скобках{}так что мне интересно, то же самое для R? Или это только дляfunctions в R, что у нас есть понятие локальных переменных.

Я провел небольшой эксперимент, который, кажется, говорит о том, что недостаточно только скобок, я что-то не так понимаю?

{
   x=matrix(1:10,2,5)
}
print(x[2,2])
[1] 4
Некоторый код для запуска в дополнение к этим ответам:globalenv(); globalenv() %>% parent.env; globalenv() %>% parent.env %>% parent.env, & # x2026; isomorphismes
@isomorphismes,Error: could not find function "%>%" , Это другая форма назначения? Aaron McDaid
Соответствующая тема по R-help:What does the "<<-" operator mean?. Henrik
@AaronMcDaid Привет, извините, что не ответил раньше! Это изrequire(magrittr), Это способ применения функций справа (x | f1 | f2 | f3) вместо слева (f3( f2( f1( x ) ) )). isomorphismes

Ваш Ответ

3   ответа
1

Немного больше в том же духе

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"

131

Переменные, объявленные внутри функции, являются локальными для этой функции. Например:

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
}

y остается доступным послеif-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
@ Dason действительно :) Я забыл вызов функции ...
116

<- делает назначение в текущей среде.

Когда вы находитесь внутри функции, 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 поэтому значение "в foo" имеет смысл. Ниже мы видим, что<<- на самом деле делает. Следующее напечатанное значение будет "in baz - before & lt; & lt; -" quot; несмотря на то, что заявление на печать приходит после<<-, Это потому что<<- не смотрит в текущую среду (если только вы не находитесь в глобальной среде, в этом случае<<- действует как<-). Так что внутриbaz значение бара остается как "в базисе - до" & lt; & lt; - ". Как только мы позвонимbaz копия бара внутриfoo изменяется на "в базе" но, как мы видим, глобальныйbar без изменений. Это потому, что копияbar это определено внутриfoo находится в родительской среде, когда мы создалиbaz так что это первая копияbar тот<<- видит и, следовательно, копию, которую он назначает. Так<<- это не просто прямая привязка к глобальной среде.

<<- это сложно, и я бы не рекомендовал использовать его, если вы можете избежать этого. Если вы действительно хотите назначить глобальную среду, вы можете использовать функцию назначить и явно сказать ей, что вы хотите назначить глобально.

Теперь я меняю<<- на оператор присваивания, и мы можем увидеть, какой эффект это имеет:

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 значение равно "в foo" даже после звонкаbaz, Это потому что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"

Похожие вопросы