Глобальные и локальные переменные в R
Я новичок в R, и я довольно запутан с использованием локальных и глобальных переменных в R.
Я прочитал несколько сообщений в Интернете, которые говорят, что если я использую =
или <-
Я назначу переменную в текущей среде, а с помощью <<-
я могу получить доступ к глобальной переменной, когда внутри функции.
Однако, как я помню, в C ++ локальные переменные возникают всякий раз, когда вы объявляете переменную внутри скобок {}
, поэтому мне интересно, так ли это для R? Или это просто для функций из R, что мы имеем понятие локальных переменных.
- Среднее значение для каждого элемента списка матриц
- Как удалить несколько значений из вектора?
- Как вы читаете в нескольких файлах .txt в R?
- конвертировать письма в номера
- R подавляет запуск сообщений от зависимости
Я сделал небольшой эксперимент, который, кажется, предполагает, что только скобок недостаточно, я получаю что-то не так?
{ x=matrix(1:10,2,5) } print(x[2,2]) [1] 4
- Не удалось установить пакеты в последней версии RStudio и R версии.3.1.1
- Разверните строки по дате с использованием даты начала и окончания
- Добавить переменную в кадр данных, содержащий максимальное значение каждой строки
- Добавить столбец «ранг» в кадр данных
- Элементарно означает над списком матриц
- Формат чисел до значительных цифр в R
- Градиент из n цветов, начиная от цвета 1 и цвета 2
- как найти верхние значения N по группам или внутри категории (по группам) в R.frame
Переменные, объявленные внутри функции, являются локальными для этой функции. Например:
foo <- function() { bar <- 1 } foo() bar
дает следующую ошибку: Error: object 'bar' not found
.
Если вы хотите сделать bar
глобальной переменной, вы должны сделать:
foo <- function() { bar <<- 1 } foo() bar
В этом случае bar
доступен извне функции.
Однако, в отличие от C, C ++ или многих других языков, скобки не определяют область переменных. Например, в следующем fragmentе кода:
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
поэтому значение «in foo» имеет смысл. Ниже мы видим, что на самом деле делает <<-
. Следующее значение, напечатанное «baz - before << -», даже если инструкция печати появляется после <<-
. Это потому, что <<-
не выглядит в текущей среде (если вы не находитесь в глобальной среде, в этом случае <<-
действует как <-
). Таким образом, внутри baz
значение bar остается как «в baz - до << -». Как только мы вызываем baz
копия бара внутри foo
меняется на «baz», но, как мы видим, глобальный 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
внутри 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"