检查函数的表达式参数
编写函数时,检查参数的类型非常重要。例如,取该正在执行子集以下(不一定是有用的)功能:检查函数的表达式参数
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.
虽然这个“工作原理设计的”,这是混淆了,因为除非仔细阅读你的函数的文档,人们会期望得到在第一种情况col1
和col2
在第二种情况下。
滥用一个famous quote:
一些人,当遇到一个问题,认为“我知道,我将使用非标准的评价。”现在他们有两个问题。
哈德利韦翰在Non-standard evaluation:
非标准评价,您可以编写非常强大的功能。但是,他们很难理解和编程。除了始终提供逃生舱外,在将其用于新领域之前,请仔细考虑NSE的成本和收益。
除非您希望允许跳过列名称周围的引号,否则不要这么做。
非常感谢您的详细解答!迄今为止还没有听说过短路评估。 ;) 我将放弃输入表达式作为参数的可能性。保存两个按键不值得可能发生的复杂情况,你是对的。 – RomanB