检查函数的表达式参数

检查函数的表达式参数

问题描述:

编写函数时,检查参数的类型非常重要。例如,取该正在执行子集以下(不一定是有用的)功能:检查函数的表达式参数

data_subset = function(data, date_col) { 

     if (!TRUE %in% (is.character(date_col) | is.expression(date_col))){ 
     stop("Input variable date is of wrong format") 
     } 

     if (is.character(date_col)) { 
     x <- match(date_col, names(data)) 
     } else x <- match(deparse(substitute(date_col)), names(data)) 

     sub <- data[,x] 
} 

我想允许用户提供应(提取为字符或表达式列例如所谓的“日期列“与刚才的日期)。在开始时,我想检查date_col的输入实际上是一个字符值还是一个表达式。然而,“is.expression”不工作:

Error in match(x, table, nomatch = 0L) : object '...' not found 

由于deparse(替代))的作品,如果一个提供我想表达“is.expression”必须正常工作。 这里有什么不对,谁能给我一个提示?

我认为你不是在寻找is.expression,而是为is.name

棘手的部分是得到date_col类型,并检查它是否是类型的角色,只有当它是name。如果您在名称中调用is.character,那么它将得到评估,通常会导致错误,因为该对象未定义。

要做到这一点,short circuit evaluation可用于:在

if(!(is.name(substitute(date_col)) || is.character(date_col))) 

is.character只调用如果is.name回报FALSE

你的功能可以归结为:

data_subset = function(data, date_col) { 

    if(!(is.name(substitute(date_col)) || is.character(date_col))) { 
    stop("Input variable date is of wrong format") 
    } 

    date_col2 <- as.character(substitute(date_col)) 
    return(data[, date_col2]) 
} 

当然,你可以使用if(is.name(…))只能转换为字符时date_col是出了名。

这工作:

testDF <- data.frame(col1 = rnorm(10), col2 = rnorm(10, mean = 10), col3 = rnorm(10, mean = 50), rnorm(10, mean = 100)) 

data_subset(testDF, "col1") # ok 
data_subset(testDF, col1) # ok 
data_subset(testDF, 1) # Error in data_subset(testDF, 1) : Input variable date is of wrong format 

不过,我不认为你应该这样做。请看下面的例子:

var <- "col1" 
data_subset(testDF, var) # Error in `[.data.frame`(data, , date_col2) : undefined columns selected 

col1 <- "col2" 
data_subset(testDF, col1) # Gives content of column 1, not column 2. 

虽然这个“工作原理设计的”,这是混淆了,因为除非仔细阅读你的函数的文档,人们会期望得到在第一种情况col1col2在第二种情况下。

滥用一个famous quote

一些人,当遇到一个问题,认为“我知道,我将使用非标准的评价。”现在他们有两个问题。

哈德利韦翰在Non-standard evaluation

非标准评价,您可以编写非常强大的功能。但是,他们很难理解和编程。除了始终提供逃生舱外,在将其用于新领域之前,请仔细考虑NSE的成本和收益。

除非您希望允许跳过列名称周围的引号,否则不要这么做。

+0

非常感谢您的详细解答!迄今为止还没有听说过短路评估。 ;) 我将放弃输入表达式作为参数的可能性。保存两个按键不值得可能发生的复杂情况,你是对的。 – RomanB