如何测试变量是否包含 lambda 函数?
How to test if a variable holds a lambda-function?
我正在构建一个主要参数可以是各种事物的函数,例如公式、函数或 lambda 函数,它必须相应地处理事情。
library(rlang)
my_func=function(x){
if(is_function(x))
return("X is a function")
else if(is_lambda(x))
return("X is a lambda")
else if(is_formula(x))
return("X is a formula")
else
return("X is something else")
}
my_func(x=is.numeric) #function
my_func(x=A~B) #formula
my_func(x=~is.numeric(.x)) #formula too :'(
my_func(x="foo") #something else
如您所见,rlang::is_lambda
无法识别 lambda 函数。在帮助文件示例中,他们首先使用 as_function
(is_lambda(as_function(x))
),但是当 x
不是 lambda 函数公式时会引发转换错误。如果可能,我宁愿不使用 trycatch
,因为我发现它有时会导致不可读的代码和隐藏的错误。
如何简单地测试这个案例?
您可以解析公式并测试其第一个字符是否为波浪号。这意味着任何没有左手边的公式都可以被强制转换为 lambda,但我猜这无论如何都是理想的行为。
library(rlang)
my_func=function(x){
if(is_function(x))
return("X is a function")
else if(is_formula(x)){
if(substr(deparse(x), 1, 1) == "~"){
if(is_lambda(as_function(x)))
return("X is a lambda")
}
return("X is a formula")
}
else
return("X is something else")
}
my_func(x=is.numeric)
#> [1] "X is a function"
my_func(x=A~B)
#> [1] "X is a formula"
my_func(x=~is.numeric(.x))
#> [1] "X is a lambda"
my_func(x="foo")
#> [1] "X is something else"
由 reprex package (v0.3.0)
于 2020-03-16 创建
虽然 Allan 的回答很好,但我决定坚持 rlang
所做的。
如果您查看 View(rlang::as_function)
,您会发现它仅中止 if (length(x) > 2)
。
因此,我的代码可以写成:
library(rlang)
my_func=function(x){
if(is_function(x))
return("X is a function")
else if(is_formula(x)){
if(length(x) > 2)
return("X is a formula")
else if(is_lambda(as_function(x)))
return("X is a lambda")
}
return("X is something else")
}
这每次都会 return 预期的输出。
我正在构建一个主要参数可以是各种事物的函数,例如公式、函数或 lambda 函数,它必须相应地处理事情。
library(rlang)
my_func=function(x){
if(is_function(x))
return("X is a function")
else if(is_lambda(x))
return("X is a lambda")
else if(is_formula(x))
return("X is a formula")
else
return("X is something else")
}
my_func(x=is.numeric) #function
my_func(x=A~B) #formula
my_func(x=~is.numeric(.x)) #formula too :'(
my_func(x="foo") #something else
如您所见,rlang::is_lambda
无法识别 lambda 函数。在帮助文件示例中,他们首先使用 as_function
(is_lambda(as_function(x))
),但是当 x
不是 lambda 函数公式时会引发转换错误。如果可能,我宁愿不使用 trycatch
,因为我发现它有时会导致不可读的代码和隐藏的错误。
如何简单地测试这个案例?
您可以解析公式并测试其第一个字符是否为波浪号。这意味着任何没有左手边的公式都可以被强制转换为 lambda,但我猜这无论如何都是理想的行为。
library(rlang)
my_func=function(x){
if(is_function(x))
return("X is a function")
else if(is_formula(x)){
if(substr(deparse(x), 1, 1) == "~"){
if(is_lambda(as_function(x)))
return("X is a lambda")
}
return("X is a formula")
}
else
return("X is something else")
}
my_func(x=is.numeric)
#> [1] "X is a function"
my_func(x=A~B)
#> [1] "X is a formula"
my_func(x=~is.numeric(.x))
#> [1] "X is a lambda"
my_func(x="foo")
#> [1] "X is something else"
由 reprex package (v0.3.0)
于 2020-03-16 创建虽然 Allan 的回答很好,但我决定坚持 rlang
所做的。
如果您查看 View(rlang::as_function)
,您会发现它仅中止 if (length(x) > 2)
。
因此,我的代码可以写成:
library(rlang)
my_func=function(x){
if(is_function(x))
return("X is a function")
else if(is_formula(x)){
if(length(x) > 2)
return("X is a formula")
else if(is_lambda(as_function(x)))
return("X is a lambda")
}
return("X is something else")
}
这每次都会 return 预期的输出。