[英]Function inside a function, access previous environment
我正在嘗試訪問在 function 中創建的數據框,並使用其環境來訪問一些數據。 我知道理想的情況是將其稱為 function 中的輸入,但我試圖避免它,因此我不必列出數百個輸入。 任何幫助或資源表示贊賞。
一個例子如下:
library(dplyr)
data_v1 <- tribble(~var1, ~var2,
1, 2)
postprocess_data <- function(){
data_v3 <- data_v2 %>%
mutate(var2 = var2*3)
data_v3
}
process_data <- function(){
data_v2 <- data_v1 %>%
mutate(var1 = var1*3)
data_v3_inside <- postprocess_data()
data_v3_inside
}
process_data()
我們可以從 parent.frame 中得到parent.frame
postprocess_data <- function(){
data_v2 <- get("data_v2", envir = parent.frame())
data_v3 <- data_v2 %>%
mutate(var2 = var2*3)
data_v3
}
process_data <- function(){
data_v2 <- data_v1 %>%
mutate(var1 = var1*3)
data_v3_inside <- postprocess_data()
data_v3_inside
}
-測試
process_data()
# A tibble: 1 × 2
var1 var2
<dbl> <dbl>
1 3 6
您的標題描述了執行此操作的正確方法。
由於process_data
只需要訪問data_v1
,它就這樣很好(盡管如果data_v1
是一個參數,它會更好)。
但是postprocess_data
需要訪問data_v2
,這是process_data
中的局部變量。 所以理想的設計是在process_data
中定義postprocess_data
。 然后它將能夠看到process_data
的所有本地變量,以及所有全局變量。 例如,
library(dplyr)
data_v1 <- tribble(~var1, ~var2,
1, 2)
process_data <- function(){
postprocess_data <- function(){
data_v3 <- data_v2 %>%
mutate(var2 = var2*3)
data_v3
}
data_v2 <- data_v1 %>%
mutate(var1 = var1*3)
data_v3_inside <- postprocess_data()
data_v3_inside
}
process_data()
#> # A tibble: 1 × 2
#> var1 var2
#> <dbl> <dbl>
#> 1 3 6
由reprex package (v2.0.1) 創建於 2022-03-23
編輯添加:我在這里編寫代碼的方式有點冒險。
如果您曾經修改過process_data()
以便它在創建data_v2
之前調用postprocess_data()
,那么嵌套的 function 將不會在封閉環境中找到它,並且會繼續在全局環境中尋找它。 如果碰巧在那里找到一個副本,您可能會遇到一個給您帶來麻煩的細微錯誤。
因此,一個好主意是盡早創建嵌套 function 使用的任何變量,例如在定義postprocess_data
之前設置data_v2 <- NULL
。 如果您在調用嵌套的 function 時沒有替換它, NULL
值應該會觸發錯誤。
1)假設您可以控制並修改process_data
,將其插入正文的第一行。 這將制作postprocess_data
的副本,除了它的環境將是正在運行的process_data
中的框架,以便在那里查找postprocess_data
中的任何自由變量。
environment(postprocess_data) <- environment()
2)如果您無法控制process_data
並且無法更改它但可以控制postprocess_data
將其替換為此。
postprocess_data <- function(envir = parent.frame()) with(envir, {
data_v3 <- data_v2 %>%
mutate(var2 = var2*3)
data_v3
})
2a)或與此一起使它的行為有點像宏。
postprocess_data <- function(envir = parent.frame()) eval(substitute({
data_v3 <- data_v2 %>%
mutate(var2 = var2*3)
data_v3
}), envir = envir)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.