R: создание среды в globalenv () внутри функции - PullRequest
5 голосов
/ 16 июня 2011

Прямо сейчас у меня есть строки:

envCache <- new.env( hash=TRUE, parent = .GlobalEnv )
print(parent.env(envCache))

R утверждает, что среда находится в глобальной среде, но когда я пытаюсь найти среду позже, ее там нет.

То, что я пытаюсь сделать здесь, - это кэшировать некоторые фреймы данных и среду в глобальной среде, поэтому каждый раз, когда я вызываю функцию, ей не нужно обращаться к серверу, чтобы снова получить те же данные. В идеале я вызову функцию один раз, используя исходную команду в консоли R, она соберет необходимые данные, сохранит их в среде в глобальной среде, а затем, когда я вызову ту же функцию из консоли R, она увидит среда и датафрейм, из которого он будет получать данные, а не запрашивать сервер.

Ответы [ 2 ]

8 голосов
/ 16 июня 2011

Когда R ищет символ, он смотрит в текущую среду, затем в родительскую среду и так далее. Он не назначил envCache в глобальной среде. Один из способов реализовать то, что вы хотели бы сделать, - создать «замыкание», которое запоминает состояние, в соответствии с

makeCache <- function() {
    cache <- new.env(parent=emptyenv())
    list(get = function(key) cache[[key]],
         set = function(key, value) cache[[key]] <- value,
         ## next two added in response to @sunpyg
         load = function(rdaFile) load(rdaFile, cache),
         ls = function() ls(cache))
}

вызывает makeCache() возвращает список из двух функций, get и set.

a <- makeCache() 

Каждая функция имеет среду, в которой она была определена (среда, созданная при вызове makeCache()). Когда вы вызываете a$set("a", 1), правила поиска переменных означают, что R ищет переменную cache, сначала внутри функции aCache$set, а когда она не находит ее там, в среде, в которой set была определены.

> a$get("foo")
NULL
> a$set("foo", 1)
> a$get("foo")
[1] 1

Круто, а? Обратите внимание, что parent=emptyenv()) означает, что get() для несуществующих ключей перестает искать в cache, в противном случае он продолжил бы поиск в родительской среде кэша и т. Д.

В документе «Введение в R» приведен пример банковского счета , действительно забавный. В ответ на комментарий @ sunpyg я добавил функцию load и ls для добавления данных из файла Rda и для отображения содержимого кэша, например, a$load("foo.Rda").

5 голосов
/ 17 июня 2011

Вот то, что я придумал как альтернативное решение.Возможно, он делает то же самое, что и другой ответ в фоновом режиме, но код для меня более интуитивно понятен.

cacheTesting <- function()
{
    if (exists("cache"))
    { 
        print("IT WORKS!!!") 
        cacheData <- get("test", envir = cache)
        print(cacheData)
    }
    else
    {   
        assign("cache", new.env(hash = TRUE), envir = .GlobalEnv) 
        test <- 42
        assign("test", test, envir = cache) 
    }
}

При первом запуске кода создается среда в .GlobalEnv с использованием оператора assign,Второй прогон видит эту среду, потому что он на самом деле добрался до .GlobalEnv, и извлекает из нее данные перед печатью.

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