Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/65.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
R 如何编写同时接受字符输入的NES函数?_R_Eval_Lazy Evaluation - Fatal编程技术网

R 如何编写同时接受字符输入的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

我正在研究一个以字符串作为函数参数的R包。现在我想使用非标准求值来允许非字符串输入。另外,为了保持向后兼容性,我想保留函数采用字符串的可能性

Hadley给出了一个与子集函数相关的函数,并建议每个NES函数都应该伴随一个标准的求值函数

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、 e
with=FALSE
用于字符大小写a la
data.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))
}