Функция для проверки данных в среде - R - PullRequest
0 голосов
/ 22 февраля 2019

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

У меня есть необходимость проверить, существуют ли данные в среде knit (Rmd).Я хотел бы написать функцию, которая может использоваться внутри других функций:

## Function to check x exists in some environment
data_check_fun <- function(x, e = parent.frame()) {

  ## Use substitute so I can pass in unquoted variable
  df_name <- deparse(substitute(x))

  ## Check env looking in
  print("looking in env: ")
  print(e)

  exists(df_name, envir = e)
}

## Create df in Global env
df <- data.frame()

## Try function (works)
> data_check_fun(x = df)
[1] "looking in env: "
<environment: R_GlobalEnv>
[1] TRUE
> data_check_fun(x = not_df)
[1] "looking in env: "
<environment: R_GlobalEnv>
[1] FALSE

## Create new env: knit_env
knit_env <- new.env()

## Put df in knit_env
knit_env$knit_df <- data.frame()

## Check df is in knit_env
> ls(knit_env)
[1] "knit_df"

## Try function (works)
> data_check_fun(x = knit_df, e = knit_env)
[1] "looking in env: "
<environment: 0xda4ac60>
[1] TRUE
> data_check_fun(x = not_df, e = knit_env)
[1] "looking in env: "
<environment: 0xda4ac60>
[1] FALSE

## Create new function e.g. to plot, which calls data_check fun
plot_function <- function(plot_data, env) {
  data_check_fun(x = plot_data, e = env)
}

## Pass data from knit_env into plot function (does not work)
> plot_function(plot_data = knit_df, env = knit_env)
[1] "looking in env: "
<environment: 0xda4ac60>
[1] FALSE

Я думаю, это потому, что data_check_fun внутри plot_function ищет что-то, что теперь называется plot_data, что несуществовать.Есть ли способ, которым я мог бы сделать это.В идеале я не хочу цитировать аргумент, передаваемый в plot_function.

1 Ответ

0 голосов
/ 22 февраля 2019

Было бы намного проще, если бы первый аргумент data_check_fun был просто определен как строка символов.Использование нестандартной оценки, как в вопросе, имеет тенденцию требовать значительных дополнительных усилий, но если вы действительно хотите сделать это без явного цитирования аргументов, то перехватите вызов, создайте новый вызов и оцените его самостоятельно следующим образом:

plot_function2 <- function(plot_data, env) {
  mf <- match.call()
  m <- match(c("plot_data", "env"), names(mf), 0L)
  mf <- mf[c(1L, m)]
  names(mf)[m] <- c("x", "e")[m > 0]
  mf[[1L]] <- quote(data_check_fun)
  eval.parent(mf)
}

# test
plot_function2(plot_data = knit_df, env = knit_env)  

См. Исходный код lm для другого примера.

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