【问题标题】:Check expression argument of function检查函数的表达式参数
【发布时间】:2015-07-13 09:43:17
【问题描述】:

在编写函数时,检查参数的类型很重要。例如,采用以下(不一定有用)正在执行子集的函数:

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(substitute)) 可以提供表达式,因此我认为“is.expression”也必须有效。 这里有什么问题,谁能给我提示?

【问题讨论】:

    标签: r function arguments expression


    【解决方案1】:

    我认为您不是在寻找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])
    }
    

    当然,当date_col 是名称时,您可以使用if(is.name(…)) 仅转换为字符。

    这行得通:

    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 用于新领域之前,请仔细考虑其成本和收益。

    除非您期望允许跳过列名称周围的引号有很大的好处,否则不要这样做。

    【讨论】:

    • 非常感谢您的详细解答!到目前为止还没有听说过短路评估。 ;) 我将放弃输入表达式作为参数的可能性。保存两次击键不值得可能的并发症,你是对的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-31
    • 1970-01-01
    • 1970-01-01
    • 2016-05-18
    • 2020-02-21
    相关资源
    最近更新 更多