假設我有一個閉包add_y(y),它回傳一個添加y到其輸入的函式。
add_y <- function(y) {
function(x) {
x y
}
}
add_4 <- add_y(4)
所以 的值add_4是一個將輸入加 4 的函式。這有效。我想dput用來顯示add_4as的定義
function(x) {
x 4
}
但這不是 dput 回傳的內容。
add_y <- function(y) {
function(x) {
x y
}
}
add_4 <- add_y(4)
dput(add_4)
#> function (x)
#> {
#> x y
#> }
有沒有辦法獲得可以在封閉環境之外運行的源代碼?
uj5u.com熱心網友回復:
如果您控制 add_y,那么解決方法是將 y 的值直接注入內部函式的主體,或者將其注入正式引數串列。這消除了環境的使用,因此問題不再存在。這涉及命名匿名內部函式和僅額外的一行執行注入加上一行回傳結果。
# 1. inject into body
add_y2 <- function(y) {
inner <- function(x) {
x y
}
body(inner) <- do.call("substitute", list(body(inner)))
inner
}
# test
add_4 <- add_y2(4)
dput(add_4)
## function (x)
## {
## x 4
## }
# 2. inject into formal arguments
add_y3 <- function(y) {
inner <- function(x) {
x y
}
formals(inner)$y <- y
inner
}
# test
add_4 <- add_y3(4)
dput(add_4)
## function (x, y = 4)
## {
## x y
## }
uj5u.com熱心網友回復:
這可以作業,但它涉及更改add_y.
library(rlang)
library(magrittr)
library(stringr)
add_y <- function(y) {
fn <- expr(function(x) {
x !!y
})
fn <- deparse(fn) %>% str_c(collapse = "")
fn <- eval(parse(text = fn))
}
add_4 <- add_y(4)
dput(add_4)
#> function (x)
#> {
#> x 4
#> }
由reprex 包(v2.0.1)于 2021 年 12 月 24 日創建
uj5u.com熱心網友回復:
您可以構造一個dput替換來生成創建類似函式的代碼add_4,但它不會按照您想要的方式決議:
dput_with_env <- function(f) {
fn <- deparse(f, control = c("keepNA", "keepInteger",
"niceNames", "showAttributes"))
env <- as.list(environment(f))
cat("local({ f =\n")
cat(fn, sep = "\n")
cat("\nenvironment(f) <- list2env(\n")
dput(env)
cat(")\nf})")
}
add_y <- function(y) {
function(x) {
x y
}
}
add_4 <- add_y(4)
dput_with_env(add_4)
#> local({ f =
#> function (x)
#> {
#> x y
#> }
#>
#> environment(f) <- list2env(
#> list(y = 4)
#> )
#> f})
由reprex 包(v2.0.1)于 2021 年 12 月 24 日創建
這假設 的環境add_4非常簡單,因此當您評估代碼時,其環境的父級可以是適當的環境。我們可以試試:
newfn <- local({ f =
function (x)
{
x y
}
environment(f) <- list2env(
list(y = 4)
)
f})
newfn
#> function (x)
#> {
#> x y
#> }
#> <environment: 0x7f9a1b5e2318>
newfn(1)
#> [1] 5
由reprex 包(v2.0.1)于 2021 年 12 月 24 日創建
uj5u.com熱心網友回復:
不dput(),不。該dput()函式不會創建環境的文本表示。
如果你想保存該功能,你可以這樣做
save(add_4, file="add4.Rdata")
然后在另一個 R 會話中
load("add4.Rdata")
這將捕獲所有封閉的值,您的函式將像以前一樣運行
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/393449.html
