Доступ к объектам R, созданным в функции - PullRequest
0 голосов
/ 30 апреля 2020

Я пытаюсь поместить что-то в CRAN, что позволяет пользователю манипулировать реактивными блестящими объектами, создавая аналогичный объект stati c на пути поиска. Я знаю, что не могу писать в глобальную среду (что она в данный момент делает), но я не уверен, как позволить объектам сохраняться после выполнения функции.

store_it <- function() {
  env <- new.env()
  assign("x", runif(10), env)
  assign("iris_df", head(iris), env)
  # View(env)
  env
}

# how I want to use it, doesn't work
store_it() # <environment: 0x0000012bd8959cb0>
x          # Error: object 'x' not found
iris_df    # Error: object 'iris_df' not found

# works
e <- attach(store_it())

x
iris_df

Она делает то, что я хочу, но я не не похоже, что он добавляет среды к пути поиска:

e <- attach(store_it())
# The following objects are masked from store_it() (pos = 3):
#   iris_df, x

e <- attach(store_it())
# The following objects are masked from store_it() (pos = 4):
#   iris_df, x

e <- attach(store_it())
# The following objects are masked from store_it() (pos = 5):
#   iris_df, x

Какой правильный способ сделать это? Я бы хотел, чтобы пользователь просто написал store_it(). Если attach() - верный путь, как мне поместить его в функцию, чтобы он не создавал новые среды? Помните, что решение должно соответствовать политике CRAN. Заранее спасибо.

Примечание: кто-то, вероятно, укажет, что я задавал подобный вопрос в прошлом. Я сделал новое сообщение, потому что этот вопрос более конкретен c. Пакетная обработка среды и отправка в CRAN

Ответы [ 2 ]

1 голос
/ 30 апреля 2020

1) CRAN позволит вам сохранять и считывать элементы в tempdir, как показано ниже, или можно пропустить tmpdir и просто использовать текущий каталог, как это делает R * Rprof.

store_it <- function() {
    iris_df <- head(iris)
    rand <- runif(3)
    save(list = ls(), file = file.path(tempdir(), "store.rda"))
}

retrieve_it <- function(envir = parent.frame()) {
    load(file.path(tempdir(), "store.rda"), envir = envir)
}

2) Также возможно хранить объекты в самом пакете при условии, что пакет определяет среду для их хранения. Таким образом, это будет работать.

store <- new.env()

store_it2 <- function() {
    store$iris_df <- head(iris)
    store$rand <- runif(3)
    invisible(store)
}

retrieve_it2 <- function(envir = parent.frame()) {
    list2env(as.list(store), envir)
}

Альтернативой retrieve_it2 является просто экспорт store в ваш пакет, и тогда пользователь может получить доступ к его содержимому, например, store$x или with(store, x) для доступа к х или они могут присоединить его, используя attach(store). Конечно, если экспортируется store, то могут быть предоставлены оба варианта - пользователь может получить прямой доступ к store или запустить retrieve_it2().

.
0 голосов
/ 30 апреля 2020

Один метод:

store_it <- local({
  .env <- NULL
  function() {
    if (is.null(.env)) .env <<- new.env(parent = emptyenv())
    .env$x <- runif(10)
    .env$iris_df <- head(iris)
    .env
  }
})
store_it()
# <environment: 0x0000000049340d80>
store_it()
# <environment: 0x0000000049340d80>
attach(store_it())
x
#  [1] 0.6478808 0.6862712 0.6969733 0.9513357 0.1560208 0.9332960 0.3966457
#  [8] 0.5067889 0.4244998 0.3747476
iris_df
#   Sepal.Length Sepal.Width Petal.Length Petal.Width Species
# 1          5.1         3.5          1.4         0.2  setosa
# 2          4.9         3.0          1.4         0.2  setosa
# 3          4.7         3.2          1.3         0.2  setosa
# 4          4.6         3.1          1.5         0.2  setosa
# 5          5.0         3.6          1.4         0.2  setosa
# 6          5.4         3.9          1.7         0.4  setosa

detach()
x
# Error: object 'x' not found
# No traceback available 

Он по-прежнему будет несколько раз «присоединять» среду к вашему пути поиска, потому что, повторяя вызов attach, вы и говорите, чтобы это было сделано.

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