用 eval 和替换来回答
我认为在这种情况下要做到这一点你只需要eval(substitute(expr))
. expr
是一个承诺,我们可以通过使用来获取承诺的值expr
直接或承诺的内容,通过使用substitute
. See http://cran.r-project.org/doc/manuals/R-lang.html#Promise-objects了解详情。承诺的内容是call
,所以我们只是eval
以获得新的结果。
prettify <- function( dat, expr ) {
labels <- attr(dat,"var.labels")
for(i in seq(ncol(dat))) colnames(dat)[i] <- labels[i]
attr(dat,"var.labels") <- NULL
eval(substitute(expr))
}
> prettify( testDF, str(dat))
'data.frame': 10 obs. of 3 variables:
$ Identifier : int 1 2 3 4 5 6 7 8 9 10
$ Important Data : num 0.336 0.9479 0.1379 0.94 0.0484 ...
$ Lies, Damn Lies, Statistics: num 1.398 0.654 0.268 -0.397 -0.41 ...
在建议的编辑中,@user2103369 建议replicate
是不同的,因为它使用sapply
为了获得多次评估,所以它需要一个函数而不是调用。
默认参数时的不同行为
有趣的是,根据参数是默认参数还是用户添加的,promise 的行为会有所不同。见下文。我认为 SoDA 可以解决这个问题,但我手边没有。该函数打印承诺的值,并用以下方法对其进行评估eval
,然后直接对其进行评估。
foo <- function(a, b=a+1) {
print(substitute(b))
print(eval(substitute(b)))
b
}
当用户提供值时,直接评估它会导致错误。
> foo(a=2, b=a+1)
a + 1
[1] 3
Error in foo(a = 2, b = a + 1) : object 'a' not found
但默认值有效。
> foo(a=2)
a + 1
[1] 3
[1] 3
在建议的编辑中,@user2103369 表示默认参数在函数内部求值,而显式参数在调用框架中求值。所以在这种情况下,用户提供的值失败,因为a
在调用框架中不可见。
使用函数的替代方法
然而,对我来说(尽管OP不同意;我将这部分留给这个答案的未来读者),这感觉像是使用函数作为第二个参数更自然的情况,就像这样;其一,这意味着用户不必知道它的名称dat
函数内。
prettify <- function( dat, FUN ) {
f <- match.fun(FUN)
labels <- attr(dat,"var.labels")
for(i in seq(ncol(dat))) colnames(dat)[i] <- labels[i]
attr(dat,"var.labels") <- NULL
f(dat)
}
然后可以使用匿名函数调用它,我认为这正是您正在寻找的,除了用户必须输入function(x)
以及。
> prettify( testDF, function(x) str(x) )
'data.frame': 10 obs. of 3 variables:
$ Identifier : int 1 2 3 4 5 6 7 8 9 10
$ Important Data : num 0.296 0.707 0.883 0.821 0.724 ...
$ Lies, Damn Lies, Statistics: num -1.1506 0.4846 -1.824 -0.397 0.0898 ...
或者在简单的情况下,如您的示例中所示,仅使用函数名称。
> prettify( testDF, str)
'data.frame': 10 obs. of 3 variables:
$ Identifier : int 1 2 3 4 5 6 7 8 9 10
$ Important Data : num 0.296 0.707 0.883 0.821 0.724 ...
$ Lies, Damn Lies, Statistics: num -1.1506 0.4846 -1.824 -0.397 0.0898 ...