R Academy · Урок

Что такое окружение в R?

Изучите окружения как именованные списки с указателями на родительские окружения.

Урок 1 из 413 шагов

«Что такое окружение в R?» — бесплатный урок R Academy на CoddyKit. Это урок 1 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения R Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс R Academy содержит 4 уроков всего.

Что такое окружение

В R окружение — это набор именованных привязок (подобный именованному списку) и указатель на родительское окружение. Каждая переменная находится в некотором окружении. Когда R ищет имя, он сначала проверяет текущее окружение, а затем поднимается по цепочке родительских окружений.

# The global environment holds your session variables
x <- 42
cat('x is in globalenv:', exists('x', envir = globalenv()), '\n')
cat('globalenv name:', environmentName(globalenv()), '\n')

globalenv(), baseenv() и emptyenv()

В R есть несколько встроенных окружений: globalenv() — Ваше интерактивное рабочее пространство, baseenv() содержит базовые функции R, а emptyenv() находится на вершине цепочки и не имеет родителя. Цепочка любого окружения в конечном итоге завершается в emptyenv().

cat('global    :', environmentName(globalenv()),  '\n')
cat('base      :', environmentName(baseenv()),    '\n')
cat('empty     :', environmentName(emptyenv()),   '\n')
cat('parent of global:', environmentName(parent.env(globalenv())), '\n')

Цепочка окружений

У каждого окружения ровно один родитель (кроме emptyenv()). Если R не находит имя в текущем окружении, он переходит к родителю, затем к родителю родителя и так далее. Именно так R разрешает имена переменных.

# Walk the parent chain from globalenv
env <- globalenv()
for (i in 1:5) {
  cat(sprintf('Level %d: %s\n', i, environmentName(env)))
  if (identical(env, emptyenv())) break
  env <- parent.env(env)
}

environment() для функции

У каждой функции есть связанное с ней окружение — то, в котором она была создана. environment(f) возвращает это окружение. Это охватывающее окружение функции, определяющее, где она ищет свободные переменные.

f <- function() 'hello'
cat('f was defined in:', environmentName(environment(f)), '\n')

# Inside a function, environment() returns its own env
show_env <- function() {
  cat('my env:', environmentName(environment()), '\n')
}
show_env()

as.list() для окружения

as.list(env) преобразует привязки окружения в именованный список, что удобно для программного просмотра его содержимого. В сочетании с globalenv() эта функция показывает все переменные текущего сеанса.

a <- 10
b <- 'hello'
c_val <- TRUE
# Show current global bindings as list
bindings <- as.list(globalenv())
cat('Names in globalenv:', paste(ls(globalenv()), collapse = ', '), '\n')

ls() — список содержимого окружения

ls() выводит имена, привязанные в окружении. По умолчанию отображается глобальное окружение. Передайте envir = e, чтобы проверить определённое окружение. Добавьте all.names = TRUE, чтобы включить имена, начинающиеся с ..

my_env <- new.env(parent = emptyenv())
my_env$x <- 1
my_env$y <- 'two'
my_env$.hidden <- TRUE
cat('Default ls:', ls(envir = my_env), '\n')
cat('All names :', ls(envir = my_env, all.names = TRUE), '\n')

new.env() — Создание окружений

new.env(parent = e) создаёт новое пустое окружение с указанным родительским окружением. Используйте emptyenv() в качестве родительского окружения, если нужно полностью изолированное окружение без унаследованных привязок.

e <- new.env(parent = emptyenv())
e$name  <- 'Alice'
e$score <- 95
cat('Names:', ls(e), '\n')
cat('Name binding:', e$name, '\n')

Окружения и списки

Окружения похожи на именованные списки, но ведут себя иначе: они всегда изменяются на месте (без копирования при изменении), у них есть родительское окружение, а поиск имён выполняется с помощью хеш-таблицы (быстро). При изменении списки копируются, а окружения — нет.

# Environments are reference objects (no copy-on-modify)
e <- new.env(parent = emptyenv())
e$x <- 1
f <- e        # f points to same env, not a copy
f$x <- 99
cat('e$x after modifying through f:', e$x, '\n')

exists() и get() в окружении

exists('name', envir = e) проверяет, привязано ли имя в окружении (по умолчанию также проверяются его родительские окружения). get('name', envir = e) извлекает значение. Обе функции принимают inherits = FALSE, чтобы выполнять поиск только в указанном окружении.

e <- new.env(parent = emptyenv())
e$pi_approx <- 3.14159
cat('exists pi_approx:', exists('pi_approx', envir = e), '\n')
cat('exists missing:  ', exists('missing_var', envir = e), '\n')
cat('get pi_approx:   ', get('pi_approx', envir = e), '\n')

environmentName() для встроенных окружений

environmentName(env) возвращает понятное человеку имя специального окружения. Для созданных пользователем окружений возвращается '' (пустая строка). Это помогает при отладке определить, где были созданы переменные.

cat(environmentName(globalenv()),    '\n')  # R_GlobalEnv
cat(environmentName(baseenv()),      '\n')  # package:base
cat(environmentName(emptyenv()),     '\n')  # R_EmptyEnv
e <- new.env(parent = emptyenv())
cat('User env name: "', environmentName(e), '"\n', sep = '')

Практика: использование окружений в качестве кэшей

Поскольку окружения изменяются на месте, они хорошо подходят для изменяемых кэшей или хеш-таблиц. Сохраняйте вычисленные результаты в окружении, чтобы не вычислять их повторно — это быстрее, чем изменять список (при изменении которого создаётся копия).

cache <- new.env(parent = emptyenv(), hash = TRUE)
cached_square <- function(n) {
  key <- as.character(n)
  if (exists(key, envir = cache, inherits = FALSE))
    return(get(key, envir = cache))
  result <- n^2
  assign(key, result, envir = cache)
  result
}
cat(cached_square(7), '\n')
cat(cached_square(7), '\n')  # served from cache

Быстрая проверка

Какое окружение является самым верхним в цепочке окружений R — то есть не имеет родительского окружения?

Окружения: основные выводы

Основные выводы об окружениях R:

  • Окружение = именованные привязки + указатель на родительское окружение
  • globalenv() = рабочая область; baseenv() = базовый R; emptyenv() = конец цепочки
  • Поиск имени поднимается по цепочке родительских окружений, пока имя не будет найдено или поиск не достигнет emptyenv()
  • ls(envir=e) перечисляет привязки; exists() проверяет их наличие; get() извлекает значение
  • Окружения являются ссылочными объектами — при изменении копия не создаётся
  • new.env(parent=emptyenv()) создаёт изолированное окружение
e <- new.env(parent = emptyenv())
assign('counter', 0L, envir = e)
for (i in 1:5) assign('counter', e$counter + 1L, envir = e)
cat('Counter:', e$counter, '\n')
cat('Env name:', environmentName(e), '\n')
cat('Bindings:', ls(e), '\n')
Можно начать бесплатно

Изучай R с ИИ-репетитором — бесплатно

Пиши и запускай код прямо в браузере, получай мгновенную помощь от ИИ-репетитора 24/7 и продолжи учиться на сайте или в приложении.

Курсы
43
Уроки
159

Часто задаваемые вопросы

Урок «Что такое окружение в R?» бесплатный?

Да — полный текст урока «Что такое окружение в R?» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс R Academy, подпишись на CoddyKit PRO. Курс R Academy содержит 4 уроков всего.

Чему я научусь в уроке «Что такое окружение в R?»?

Изучите окружения как именованные списки с указателями на родительские окружения. Ты практикуешь R Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать R Academy?

Предыдущий опыт не требуется. R Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 1 из 4.

Сколько времени занимает урок «Что такое окружение в R?»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке R Academy?

Да. Каждый урок R Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Что такое окружение в R?
  2. Правила лексической области видимости
  3. Глобальная и локальная область видимости
  4. Создание и проверка окружений
← Назад к R Academy