Как я могу ссылаться на локальную среду внутри функции, в R? - PullRequest
30 голосов
/ 07 января 2012

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

У меня есть функция, myFunc, которая создает внутри нее localFunc. (NB: это не пакет, а глобальная среда.) Я хотел бы знать, где в пути поиска существует localFunc, так как я хотел бы проанализировать его с помощью mvbutils::foodweb.

Вот пример:

myFunc <- function(){
    require(data.table)
    require(mvbutils)
    localFunc <- function(x){
        return(as.data.table(x))
    }

    vecPrune <- c("localFunc",ls("package:data.table"))
    ix <- match("data.table",search())
    tmpWeb <- foodweb(where = c(1,ix), prune = vecPrune, plotting = FALSE)
    return(tmpWeb)
}

Однако вызов myFunc(), похоже, не означает, что localFunc вызывает data.table(). Это неверно - что дает?

(NB: аргумент where указывает путь поиска.)


Обновление 1: Как отмечают Томми и Спейсдман, хитрость заключается в том, чтобы указать environment(). Звонок на foodweb() относится к where = c(1, ix). Индекс 1 является ошибкой. Это связано с мыслью, что .GlobalEnv, который часто (всегда?) Является первым элементом в векторе search(), является подходящим местом для поиска. Это ошибочно. Вместо этого следует обратиться к environment(), и правильный вызов ниже. (Примечание: ix указывает расположение data.table() в выводе search().)

tmpWeb <- foodweb(where = c(environment(),ix), prune = vecPrune, plotting = FALSE)

Это появляется в ответе на на этот вопрос в функции с именем checkScriptDependencies, которая оборачивает код из файла сценария R в локальную функцию, которая затем анализируется с помощью foodweb. Это ограниченный пример использования environment(), и Томми дал хорошее объяснение того, как использовать его и подобные функции в этом контексте.

1 Ответ

42 голосов
/ 08 января 2012

Чтобы получить текущую среду, просто позвоните environment().

Как правило, sys.frame возвращает любую из сред, находящихся в настоящее время в стеке вызовов, а sys.nframe возвращает текущую глубину стека вызовов.,sys.frames возвращает список всех сред в стеке вызовов.

environment(f) возвращает среду закрытия для функции f (где она будет искать функции и глобальные переменные).

parent.env(e) возвращает родительскую среду, в которой он будет искать, если символ не найден в e.

f <- function() {
  function() list(curEnv=environment(), parent=parent.env(environment()), 
          grandParent=parent.env(parent.env(environment())), callStack=sys.frames(), 
          callStackDepth=sys.nframe())
}
g <- function(f, n=2) if (n>2) g(f, n-1) else f()

floc <- f() # generate a local function
g(floc, 3) # call it

Это вызовет локальную функцию floc с глубиной стекаof 3. Возвращает список с текущей средой, ее родителем (локальная среда в f) и его родителем (где было определено f, поэтому globalenv).Он также возвращает список стековых фреймов (сред).Это среды для рекурсивных вызовов в g (кроме последней, которая является текущей средой floc).

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