如何找出R函数调用中使用了哪些参数值?

时间:2017-05-29 06:20:38

标签: r function

我想知道是否有一个Base R函数来提取在特定函数调用中使用的参数值?

例如,对于下面的每个对象xyz,是否有提取参数名称的通用方法(例如n,{正在使用{1}},sdrate)和用户或系统为每个参数分配的值(例如,scale 1e4)?

注意:在某些" R"这样的提取功能很容易完成。例如,在n中,可以使用density()轻松提取参数values

density()$call

1 个答案:

答案 0 :(得分:2)

这真的不是一件容易的事。如果您正在构建该功能,则可以使用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_fnlang_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