В каких случаях следует использовать new.env для создания новой среды? - PullRequest
31 голосов
/ 16 июля 2010

В "Какой самый полезный трюк R?" ( здесь ), я читал, что использование сред дает «возможности передачи по ссылке». Существуют ли ограничения и / или ошибки с этим подходом?

Кроме того, каковы преимущества и недостатки использования созданных сред? Это то, что меня смущало в течение достаточно долгого времени, поэтому любая ясность или ссылка были бы очень полезны для меня.

Заранее спасибо.

Ответы [ 2 ]

33 голосов
/ 16 июля 2010

Хотя я согласен с общим советом Харлана (то есть не использую что-либо, пока вы не понимаете это), я бы добавил:

Среды - это фундаментальная концепция в R, и, на мой взгляд, они чрезвычайно полезны (другими словами: их стоит понять!). Среды очень важны для понимания вопросов, связанных с областью применения. Некоторые основные вещи, которые вы должны понимать в этом контексте:

  1. search(): покажет вам рабочее пространство; среды перечислены в порядке приоритета. Основным окружением является .GlobalEnv, и на него всегда можно ссылаться как таковое.
  2. ls(): покажет вам, что содержится в окружающей среде
  3. attach / detach: создает новую среду для объекта
  4. get, assign, <<- и <-: вы должны знать разницу между этими функциями
  5. with: один метод работы со средой без ее подключения.

Еще один указатель: взгляните на пакет proto (используется в ggplot), который использует среды для обеспечения управляемого наследования.

Наконец, я хотел бы отметить, что среды очень похожи на списки: они могут хранить внутри себя любые объекты (см. этот вопрос ). Но в зависимости от вашего варианта использования (например, хотите ли вы иметь дело с наследованием и приоритетом), с списком может быть проще работать. И вы всегда можете attach список как окружение.

Редактировать: Если вы хотите увидеть пример proto в работе в ggplot, посмотрите, что структура объекта ggplot, который по сути является списком, составленным частично из окружений:

> p <- qplot(1:10, 1:10)
> str(p)
List of 8
 $ data       :'data.frame':    0 obs. of  0 variables
 $ layers     :List of 1
  ..$ :proto object 
 .. .. $ legend     : logi NA 
 .. .. $ inherit.aes: logi TRUE 
...
> class(p$layers[[1]])
[1] "proto"       "environment"
> is.environment(p$layers[[1]])
[1] TRUE

Обратите внимание, как он построен с использованием прото и в результате содержит много сред. Вы также можете построить отношения в этих объектах, используя graph.proto.

5 голосов
/ 16 июля 2010

Ну, если вы их не понимаете, и люди, которым вы когда-нибудь должны будете читать ваш код (включая ваше будущее я), не понимают окружения, то вы не должны их использовать! Они были разработаны для использования для инкапсуляции пространств имен в пакетах и ​​тому подобное. Тот факт, что вы можете использовать их для передачи по ссылке и хеш-таблицам, не обязательно означает, что вы должны . Это трюк. Как правило, использование deep magic на самом деле не рекомендуется, даже если это делает ваш код немного быстрее.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...