簡體   English   中英

Function里面一個function,訪問之前的環境

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM