我有一个函数,当我第一次学习NSE时,它曾经接受无引号的输入,现在我讨厌它在这个用例中。我想强制这个函数只接受一个字符串,但是向用户返回一个清晰的错误消息。
我的问题是测试传递的是什么类型的输入。我可以使用rlang::quo_is_symbol(rlang::enquo(str_x)),但当将多个函数链接在一起时,这将失败。这是我在reprex上的分成。
fun1 <- function(str_x) {
depr_str_x(str_x)
paste("this is x", str_x)
}
depr_str_x <- function(str_x) {
if (rlang::quo_is_symbol(rlang::enquo(str_x))) {
stop("this is a clear error message to the user")
}
invisible(NULL)
}所以当我运行这个的时候,我得到了我想要的。
depr_str_x("test") # nothing (which I want)
depr_str_x(test) # my custom error (which I want)但当我运行这段代码时,两次都会得到错误。如何让它识别正在传递的"test"是一个字符串?我也尝试过rlang::is_scalar_character(),但对于符号的情况失败了。我希望有一种快速而简单的方法来做到这一点,而不是强迫评估和查看它是否失败或其他什么。
fun1("test") # my custom error (which I don't want)
fun1(test) # my custom error (which I want)此外,当函数在其他函数内部使用时,这应该是有效的。这就是我的方法不断遇到问题的地方。
fun2 <- function(str_x) fun1(str_x)
fun2("test") # my custom error (which I don't want)
fun2(test) # my custom error (which I want)发布于 2021-04-20 02:36:58
我通过粗略地捕获错误object 'x' not found,让它正常工作(但我不确定这不会有but)。我把这个问题放在一边,欢迎更好的解决方案。
depr_str_x <- function(str_x) {
is_valid <- tryCatch(rlang::is_scalar_character(str_x),
error = function(e) {
if (grepl("not found", e, fixed = TRUE)) {
return(FALSE)
} else {
stop(e)
}
})
if (!is_valid)
stop("this is a clear error message to the user")
}发布于 2021-04-20 03:27:58
NSE参数和可能是NSE也可能不是NSE的参数需要将quasiquotation正确地从一个函数传递到下一个函数。最直接的方法是使用{{
fun1 <- function(str_x) {
depr_str_x({{str_x}}) # <-- Note the {{ operator
paste("this is x", str_x)
}
fun1("test") # [1] "this is x test"
fun1(test) # Error in depr_str_x({ : this is a clear error message to the user fun2也是如此
fun2 <- function(str_x) fun1({{str_x}}) # <---- Ditto on {{
fun2("test") # [1] "this is x test"
fun2(test) # Error in depr_str_x({ : this is a clear error message to the user EDIT:要记住的一点是,通过允许可能是也可能不是NSE的参数,您正在创建歧义。考虑一下,
test <- "This is a string"
fun2(test) # What should happen here?对于您的情况,我的一般建议是完全放弃对NSE的支持,并记录更改。然后NSE输入将自动失败,但会出现一个错误,显示"Variable test not found",这应该足以让大多数用户找出问题所在。
https://stackoverflow.com/questions/67165853
复制相似问题