首页 > 解决方案 > r-studio:有“严格模式”吗?

问题描述

说,而不是写

sort(tapply(CPS$C == "S", CPS$M, sum, na.rm=TRUE))

我写的

sort(tapply(CPS$C == "S", CPS$M, sum, rm.na=TRUE))

似乎 r-studio 会愉快地运行该函数,忽略关键参数 na.rm

预计它会忽略 na.rm(我确实提供了具有错误参数名称的函数)。我发现令人惊讶的是它完全可以运行。

有什么方法可以说服 R/R-studio 抛出某种错误,告诉我我打错了,而不是运行函数?

标签: r

解决方案


没有“严格”模式,尤其是对于使用省略号将参数传递给其他函数的函数。这里sum不关心参数名称。例如

sum(1:4, whatever=4)
sum(1:4, 4)

运行得很好,两者都返回相同的值。您可以编写自己的包装函数来更积极地检查参数值,而不是使用此类函数。这是一个“安全”的版本sum

safe_sum <- function(...) {
  cx <- match.call()
  cn <- names(cx)[-1]
  if (!is.null(cn)) {
    bad_names <- cn[cn!="" & cn!="na.rm"]
    if(length(bad_names)) {
      stop(paste("unexpected named parameter:", paste(bad_names, collapse=", ")))
    }
  }
  cx[[1]] <- quote(sum)
  eval(cx)
}

safe_sum(1:5, rm.na=TRUE)
# Error in safe_sum(1:5, rm.na = TRUE) : unexpected named parameter: rm.na

您可以使用它tapply

set.seed(10)
CPS <- data.frame(
  C = sample(c("S","T"), 50, replace=TRUE),
  M = sample(LETTERS[1:4], 50, replace=TRUE)
)
sort(tapply(CPS$C == "S", CPS$M, safe_sum , na.rm=TRUE))
# D A B C 
# 3 5 8 9 
sort(tapply(CPS$C == "S", CPS$M, safe_sum , rm.na=TRUE))
# Error in FUN(X[[i]], ...) : unexpected named parameter: rm.na 

如果您想使用其他功能执行此操作,您可以创建一个工厂来检查所有参数名称。这是一个这样的功能

check_match_names <- function(fun) {
  args <- formalArgs(args(sum))
  args <- args[args!="..."]
  function(...) {
    cx <- match.call()
    cn <- names(cx)[-1]
    if (!is.null(cn)) {
      bad_names <- cn[cn!="" & !(cn %in% args)]
      if(length(bad_names)) {
        stop(paste("unexpected named parameter:", paste(bad_names, collapse=", ")))
      }
    }
    cx[[1]] <- fun
    eval.parent(cx)
  }
}

然后你会创建你的功能

safe_sum <- check_match_names(sum)

推荐阅读