Глобальные и локальные переменные в R
Я новичок в R, и я совершенно запутался с использованием локальных и глобальных переменных в р.
Я читал некоторые сообщения в интернете, которые говорят, если я использую = или <- Я назначу переменную в текущей среде, и с <<- Я могу получить доступ к глобальной переменной внутри функции.
однако, как я помню, в C++ локальные переменные возникают всякий раз, когда вы объявляете переменную внутри скобок {}, так что мне интересно, если это то же самое для R? Или это только для функции в R, что у нас есть понятие локальных переменных.
Я сделал небольшой эксперимент, который, кажется, предполагает, что только скобки не достаточно, я получаю что-то не так?
{
x=matrix(1:10,2,5)
}
print(x[2,2])
[1] 4
3 ответов:
переменные, объявленные внутри функции являются локальными к этой функции. Например:
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заявление.как вы хорошо говорите, вы также можете создавать вложенные среды. Вы можете посмотреть на эти две ссылки для понимания того, как их использовать:
- http://stat.ethz.ch/R-manual/R-devel/library/base/html/environment.html
- 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так что значение "в foo" имеет смысл. Ниже мы видим, что<<-на самом деле делает. Следующее напечатанное значение- " in baz-before <<-. Это потому что<<-не смотрит в текущая среда (если вы не находитесь в глобальной среде, в этом случае<<-действует как<-). Так что внутриbazзначение бара остается как "в baz-before baz копия бара внутриfooменяется на "В баз", но, как мы видим, глобальный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значение "в foo" даже после вызоваbaz. Это потому чтоassignникогда даже не рассматривал копиюbarвнутри foo, потому что мы сказали ему, где именно искать. Однако на этот раз значение 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"
Comments