我正在嘗試從 R 包中打包一個函式。從源代碼來看,它似乎對某些引數進行了非標準評估。如何撰寫函式以將值傳遞給實施了非標準評估的引數?
這是一個玩具示例
data <- data.frame(name = 1:10)
#Suppose the one below is the function from that package
toy.fun <- function(dat, var) {
eval(substitute(var), dat)
}
> toy.fun(data, name)
[1] 1 2 3 4 5 6 7 8 9 10
這是我嘗試包裝它的內容
toy.fun2 <- function(dat, var2) {
var_name <- deparse(substitute(var2))
#example, but for similar purpose.
data_subset <- dat[var_name]
toy.fun(data_subset, var2)
}
> toy.fun2(data, name)
Error in eval(substitute(var), dat) : object 'var2' not found
編輯
我應該讓問題更清楚,其中我想將不同的變數名傳遞給var2. 因此,當資料中有不同的變數名稱時,它可以使用該名稱進行兩個資料選擇,并傳遞給我嘗試包裝的函式。exceedance函式 from的源代碼heatwaveR已經 ts_y <- eval(substitute(y), data)可以捕獲輸入變數y。這相當于我的toy.fun.
toy.fun2為了清楚起見,我已經修改了。
uj5u.com熱心網友回復:
使用 獲取呼叫match.call,替換函式名稱并對其進行評估。也可以根據需要修改其他引數。查看源代碼lm以查看此方法的另一個示例。
toy.fun2 <- function(dat, var) {
cl <- match.call()
cl[[1L]] <- quote(toy.fun)
eval.parent(cl)
}
toy.fun2(data, name)
## [1] 1 2 3 4 5 6 7 8 9 10
uj5u.com熱心網友回復:
我們可以使用點或省略號將引數傳遞給函式,參見?dots和?dotsMethods,可變長度引數。
data <- data.frame(name = 1:10)
toy <- function(dat, var) {
eval(substitute(var), dat)
}
toy(data, name)
#> [1] 1 2 3 4 5 6 7 8 9 10
toy2 <- function(dat, ...) {
var_name <- deparse(substitute(...))
data_subset <- dat[var_name]
toy(data_subset, ...)
}
toy2(data, name)
#> [1] 1 2 3 4 5 6 7 8 9 10
來自R 語言定義第 2.1.9 節:如果函式具有 ... 作為形式引數,則與形式引數不匹配的任何實際引數都與 ... 匹配。
錢伯斯 (2008) 書籍軟體資料分析的摘錄:
求值器首先在當前求值的環境中查找包含在該環境本身中的物件,然后逐步回傳封閉環境。
要查看它的作用,我們可以使用substitute(c(...))in ( toy2) 函式并找到
c(data, name)
這里name和data位于封閉環境中。
順便說一句 - 如果包裝器旨在供更廣泛的受眾使用,最好仔細記錄省略號傳遞到的位置。
更新的問題
看一眼函式的heatwaveR包源代碼,exceedance我認為不...應該發生沖突。
但是,如果需要,在這里提及一些查找更多資訊的方法可能是個好主意,因為該包確實使用tidyverse. 你可能想看看的rlang包,并與組合實驗enquo和!!,或在串列中的情況下,enquos和!!!。在 tidyverse 中處理 NSE 的新增功能是{{ }}擁抱。該tidyverse檔案或第20章哈德利韋翰的的預研會提供更多的答案。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/368511.html
