R 如何编写同时接受字符输入的NES函数?
我正在研究一个以字符串作为函数参数的R包。现在我想使用非标准求值来允许非字符串输入。另外,为了保持向后兼容性,我想保留函数采用字符串的可能性 Hadley给出了一个与子集函数相关的函数,并建议每个NES函数都应该伴随一个标准的求值函数R 如何编写同时接受字符输入的NES函数?,r,eval,lazy-evaluation,R,Eval,Lazy Evaluation,我正在研究一个以字符串作为函数参数的R包。现在我想使用非标准求值来允许非字符串输入。另外,为了保持向后兼容性,我想保留函数采用字符串的可能性 Hadley给出了一个与子集函数相关的函数,并建议每个NES函数都应该伴随一个标准的求值函数 library(lazyeval) # standard evaluation subset2_ <- function(df, condition) { r <- lazy_eval(condition, df) r <- r
library(lazyeval)
# standard evaluation
subset2_ <- function(df, condition) {
r <- lazy_eval(condition, df)
r <- r & !is.na(r)
df[r, , drop = FALSE]
}
subset2_(mtcars, lazy(mpg > 31))
# NES can be written easily afterwards
subset2 <- function(df, condition) {
subset2_(df, lazy(condition))
}
NSE函数抛出一个错误:
subset2(mtcars, "mpg > 31")
但是我希望用户对引用的和未引用的参数具有相同的函数(NSE函数)
有什么想法吗?NSE函数接受NSE输入。这就是这种模式的要点,不是吗
subset2(mtcars, mpg > 31)
当然,您可以允许NSE函数也接受字符输入,但我强烈建议不要这样做。不要把SE和NSE混用,这没有什么好处,而且会造成混乱(而且可能会有bug,因为你在混用域)
也就是说,以下当然有效:
subset2 <- function(df, condition) {
if (is.character(substitute(condition)))
subset2_(df, condition)
else
subset2_(df, lazy(condition))
}
subset2我将添加另一个参数来区分这两种情况。i、 ewith=FALSE
用于字符大小写a ladata.table
方式。谢谢。那么,您建议如何转换到NSE并保持向后兼容性?@Marti啊,向后兼容性是一个很好的论点。标准的解决方案是发布一个主要的修订版,其中旧的行为被弃用。在随后的下一次重大修订中,旧的行为被删除,破坏了向后兼容性。我认为这是应该走的路。如果在非引号表达式上使用is.character,则会抛出一个错误<代码>子集合2中的错误(mtcars,mpg>31):未找到对象“mpg”
subset2 <- function(df, condition) {
if (is.character(substitute(condition)))
subset2_(df, condition)
else
subset2_(df, lazy(condition))
}
subset2 <- function(df, condition) {
if (is.character(substitute(condition))) {
msg = sprintf(paste0('Calling %s with a quoted expression is',
' deprecated. Pass an unquoted expression',
' instead, or use %s.'),
sQuote('subset2'), sQuote('subset2_'))
.Deprecated(msg = msg)
subset2_(df, condition)
}
else
subset2_(df, lazy(condition))
}