這實在不是一件容易的事。如果你正在構建的功能,可以捕捉match.call
通話,可沒有太多的麻煩解析:
f <- function(x, y = 1, ...){
cl <- match.call()
as.list(cl[-1])
}
str(f(1))
#> List of 1
#> $ x: num 1
str(f(1, 'foo'))
#> List of 2
#> $ x: num 1
#> $ y: chr "foo"
str(f(1, 'foo', list(3), fun = sum))
#> List of 4
#> $ x : num 1
#> $ y : chr "foo"
#> $ : language list(3)
#> $ fun: symbol sum
注match.call
只捕獲的號召,不默認參數添加(第一個例子中沒有y
)。那些可以用formals(f)
訪問,因爲f
不是原始的,所以完全可能的參數通過
user_args <- f(1)
fun_args <- formals(f)
fun_args[names(user_args)] <- user_args
str(fun_args)
#> List of 3
#> $ x : num 1
#> $ y : num 1
#> $ ...: symbol
這種方法不適用於完成點很好地工作來創建的,但如果他們完成了那麼match.call
本身就足夠了。要提取傳遞給現有函數的參數,您可以編寫一個包含match.call
的包裝,但重建每個函數並不現實,並且您捕獲的調用看起來很有趣,除非您覆蓋現有函數。只要功能是不是原始的,你可以使用quote
,使formals
辦法,但:
cl <- quote(rnorm(5, 2))
user_args <- as.list(cl[-1]) # subset call to only args
fun_args <- formals(as.character(cl[1])) # subset call to only function
names(user_args) <- names(fun_args)[seq(length(user_args))]
fun_args[names(user_args)] <- user_args
str(fun_args)
#> List of 3
#> $ n : num 5
#> $ mean: num 2
#> $ sd : num 1
另一種方法是使用rlang,其職能處理好原語(fn_fmls(sum)
),可以提取部分(lang_fn
,lang_args
),準確地命名未命名的參數(lang_standardize
)等等。加上purrr新list_modify
(開發版本),這一切都變得相當容易:
library(rlang)
fun_call <- quo(rnorm(5))
fun_call
#> <quosure: frame>
#> ~rnorm(5)
default_args <- fn_fmls(lang_fn(fun_call))
str(default_args)
#> Dotted pair list of 3
#> $ n : symbol
#> $ mean: num 0
#> $ sd : num 1
user_args <- lang_args(lang_standardise(fun_call))
str(user_args)
#> List of 1
#> $ n: num 5
calling_args <- purrr::list_modify(default_args, user_args)
str(calling_args)
#> Dotted pair list of 3
#> $ n : num 5
#> $ mean: num 0
#> $ sd : num 1
據我所知,你必須保存該調用並解析它,這是一種痛苦。 – alistaire
@alistaire說,你可以使用'Sys.call()'來訪問一個函數內部的調用......但是你的目標是什麼? – Val