![](/img/trans.png)
[英]R Step function looks for data in global environment, not inside defined function
[英]How to let function defined in global environment access variables defined in its calling function's environment?
connect_dw <- function() {
DBI::dbConnect(RSQLite::SQLite(), ":memory:")
}
fetch_sql_res <- function(key, ...) {
query_list <- list(...)
query_sql_res <- function(.query_list = query_list, .db_connect_f = connect_dw) {
con <- .db_connect_f()
res <- purrr::map(.query_list, glue::glue_sql, .con = con ) %>%
purrr::map(purrr::partial(DBI::dbGetQuery, conn = con))
DBI::dbDisconnect(con)
res
}
## if key exists in redis cache, fetch it from redis.
## If not, call the function to query database
query_sql_res()
}
#' testing
#' @serializer unboxedJSON
#' @get /test_db
test_db <- function() {
userid <- 10
fetch_sql_res(df = "SELECT {userid}")
}
错误信息:
Error in eval(parse(text = text, keep.source = FALSE), envir) :
object 'userid' not found
我想创建一个可以在一个函数内使用的函数(该函数用于使用管道工创建Web api)。
该函数用于获取sql结果。 它需要一些变量来构造sql查询。
上面的代码不起作用。 看来问题出在环境上。
所有R函数都具有词法范围,这意味着它们从定义函数的地方继承变量,而不是从调用地方继承。 您无法更改此默认行为,因为它会破坏很多事情。 因此,在评估需要不同环境的函数调用时,只需要小心指定正确的环境即可。
在这种情况下,问题似乎出在glue::glue_sql
找不到变量上。 该函数有一个.envir=
参数,告诉它在哪里寻找变量。 您只需要明确地将调用环境传递给该函数。 例如
fetch_sql_res <- function(key, ...) {
query_list <- list(...)
calling_env <- parent.frame()
query_sql_res <- function(.query_list = query_list, .db_connect_f = connect_dw) {
con <- .db_connect_f()
res <- purrr::map(.query_list, glue::glue_sql, .con = con, .envir=calling_env ) %>%
purrr::map(purrr::partial(DBI::dbGetQuery, conn = con))
DBI::dbDisconnect(con)
res
}
query_sql_res()
}
这不是“通用”解决方案,但相同的基本思想将在其他地方应用。 您需要在需要时显式引用调用环境。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.