rlang: Error: Can't convert a function to a string
rlang: Error: Can't convert a function to a string
我创建了一个将函数名转换为字符串的函数。版本 1 func_to_string1
工作正常,但版本 2 func_to_string2
不工作。
func_to_string1 <- function(fun){
print(rlang::as_string(rlang::enexpr(fun)))
}
func_to_string2 <- function(fun){
is.function(fun)
print(rlang::as_string(rlang::enexpr(fun)))
}
func_to_string1
作品:
> func_to_string1(sum)
[1] "sum"
func_to_string2
无效。
> func_to_string2(sum)
Error: Can't convert a primitive function to a string
Call `rlang::last_error()` to see a backtrace
我的猜测是,通过在将其转换为字符串之前调用 fun
,它会在函数内部进行计算,因此会抛出错误消息。但是为什么我没有做任何作业会发生这种情况?
我的问题是为什么会发生这种情况,是否有更好的方法将函数名称转换为字符串?
感谢任何帮助,谢谢!
也许改用这个?
func_to_string2 <- function(fun){
is.function(fun)
deparse(substitute(fun))
#print(rlang::as_string(rlang::enexpr(fun)))
}
> func_to_string2(sum)
[1] "sum"
这不是一个完整的答案,但我认为它不适合发表评论。
R 有一种机制叫做 pass-by-promise,
其中函数的形式参数是惰性对象(承诺),只有在使用时才会被评估。
即使你没有执行任何任务,
对 is.function
的调用使用参数,
所以承诺是 "replaced" 通过评估它的结果。
然而,在我看来,这似乎是 rlang
* 中的一个不一致之处,
特别是考虑到科里的回答,
这意味着即使在使用给定参数后,R 仍然可以找到 promise 对象;
不过,这样做的机制可能不是 R 的 public API 的一部分。
*编辑:查看评论。
无论如何,您可以像 base::missing
一样对待 enexpr
/enquo
/ensym
,
从某种意义上说,您应该只将它们与您在函数主体中根本没有使用过的参数一起使用。
这个问题提出了惰性求值的一个有趣观点。
R 参数是延迟计算的,这意味着直到需要时才会计算参数。
这在具有以下示例的 Advanced R 书中得到了最好的理解,
f <- function(x) {
10
}
f(stop("This is an error!"))
结果是 10,这是令人惊讶的,因为 x 从未被调用,因此也从未被计算过。我们可以使用 force()
强制对 x 求值
f <- function(x) {
force(x)
10
}
f(stop("This is an error!"))
这符合预期。事实上,我们甚至不需要 force()
(尽管明确表示是好的)。
f <- function(x) {
x
10
}
f(stop("This is an error!"))
这就是你在这里打电话的情况。函数 sum
最初是一个符号,在调用 is.function()
时不带参数进行求值。事实上,即使这样也会失败。
func_to_string2 <- function(fun){
fun
print(rlang::as_string(rlang::ensym(fun)))
}
总的来说,我认为最好在函数的最开始使用enexpr()
。
来源:
我创建了一个将函数名转换为字符串的函数。版本 1 func_to_string1
工作正常,但版本 2 func_to_string2
不工作。
func_to_string1 <- function(fun){
print(rlang::as_string(rlang::enexpr(fun)))
}
func_to_string2 <- function(fun){
is.function(fun)
print(rlang::as_string(rlang::enexpr(fun)))
}
func_to_string1
作品:
> func_to_string1(sum)
[1] "sum"
func_to_string2
无效。
> func_to_string2(sum)
Error: Can't convert a primitive function to a string
Call `rlang::last_error()` to see a backtrace
我的猜测是,通过在将其转换为字符串之前调用 fun
,它会在函数内部进行计算,因此会抛出错误消息。但是为什么我没有做任何作业会发生这种情况?
我的问题是为什么会发生这种情况,是否有更好的方法将函数名称转换为字符串?
感谢任何帮助,谢谢!
也许改用这个?
func_to_string2 <- function(fun){
is.function(fun)
deparse(substitute(fun))
#print(rlang::as_string(rlang::enexpr(fun)))
}
> func_to_string2(sum)
[1] "sum"
这不是一个完整的答案,但我认为它不适合发表评论。
R 有一种机制叫做 pass-by-promise,
其中函数的形式参数是惰性对象(承诺),只有在使用时才会被评估。
即使你没有执行任何任务,
对 is.function
的调用使用参数,
所以承诺是 "replaced" 通过评估它的结果。
然而,在我看来,这似乎是 rlang
* 中的一个不一致之处,
特别是考虑到科里的回答,
这意味着即使在使用给定参数后,R 仍然可以找到 promise 对象;
不过,这样做的机制可能不是 R 的 public API 的一部分。
*编辑:查看评论。
无论如何,您可以像 base::missing
一样对待 enexpr
/enquo
/ensym
,
从某种意义上说,您应该只将它们与您在函数主体中根本没有使用过的参数一起使用。
这个问题提出了惰性求值的一个有趣观点。
R 参数是延迟计算的,这意味着直到需要时才会计算参数。
这在具有以下示例的 Advanced R 书中得到了最好的理解,
f <- function(x) {
10
}
f(stop("This is an error!"))
结果是 10,这是令人惊讶的,因为 x 从未被调用,因此也从未被计算过。我们可以使用 force()
f <- function(x) {
force(x)
10
}
f(stop("This is an error!"))
这符合预期。事实上,我们甚至不需要 force()
(尽管明确表示是好的)。
f <- function(x) {
x
10
}
f(stop("This is an error!"))
这就是你在这里打电话的情况。函数 sum
最初是一个符号,在调用 is.function()
时不带参数进行求值。事实上,即使这样也会失败。
func_to_string2 <- function(fun){
fun
print(rlang::as_string(rlang::ensym(fun)))
}
总的来说,我认为最好在函数的最开始使用enexpr()
。
来源: