【问题标题】:Which R functions are not suitable for programmatic use?哪些 R 函数不适合编程使用?
【发布时间】:2014-06-12 21:33:51
【问题描述】:

browser 这样的一些函数只有在交互使用时才有意义。

人们普遍认为subset 函数should only be used interactively

同样,sapply 不适合编程使用,因为它不会简化零长度输入的结果。

我正在尝试列出仅不适合编程使用的函数的详尽列表。

计划是做一个包检查工具,看看这些函数是否被调用并给出警告。

还有其他功能,如 file.choosereadline 需要交互性,但这些可以包含在包中,因为最终使用将是交互性的。对于这个用例,我不太关心这些,但可以随意将它们添加到列表中。

我错过了哪些功能?

【问题讨论】:

  • imho attach 永远不应该被使用,尤其是不能以编程方式使用。当然还有Viewedit 和朋友。我不确定我是否同意sapply
  • @Roland 同意attach。我对sapply 的看法是,由于零长度输入,它会导致太多模糊的错误。例如,sapply(x, length) 返回一个整数向量,除非x 的长度为0,在这种情况下您会得到一个列表。如果您知道输出的大小是恒定的,则使用vapply,否则使用lapply
  • 顺便说一句,我提出这个问题的动机是我一直不小心在我的代码中留下对browser 的调用,如果你将它签入存储库,这看起来很愚蠢。
  • 也许你也应该警告cat。通常应该使用message
  • 这可能有点激烈。在编程中使用诸如subset 之类的函数的问题在于它们对参数使用非标准评估。如果那些使用非标准评估评估的参数是传递变量,这只是一个潜在的问题。如果接受非标准评估的参数传递给常量表达式,那么这些函数仍然可以安全地在函数中使用。例如,subset(data, id == 1) 在函数中不会有问题。

标签: r interactive


【解决方案1】:

(随意编辑。)

以下函数应该小心处理(这并不一定意味着它们不适合编程):

  • 根据输入,其输出没有一致的输出类的函数:sapplymapply(默认)

  • 内部行为因输入长度而异的函数:sampleseq

  • 在环境中评估其某些参数的函数:$subsetwithwithintransform

  • 违背正常环境使用的函数:attachdetachassign<<-

  • 允许部分匹配的函数:$

  • 仅在交互使用中有意义的函数:browserrecoverdebugdebugonceeditfixmenuselect.list

  • 与用户输入一起使用时可能构成威胁(病毒)的函数:sourceeval(parse(text=...))system

此外,在某种程度上,每个函数都会生成警告而不是错误。我建议使用options(warn = 2) 将所有警告转化为编程应用程序中的错误。然后可以通过suppressWarningstry 允许特定情况。

【讨论】:

  • 有趣的是,由于 R 3.1.0 部分匹配 data.frame 列名会发出警告,请参阅 NEWS
  • ...但不是列表(例如 cars$das.list(cars)$d),叹息。
【解决方案2】:

这是对发布者问题后评论的回答。此函数输入一个函数并返回找到的错误函数及其行号。它可能会产生误报,但它们只是警告,因此看起来并不算太糟糕。修改bad以适应。

badLines <- function(func) {
    bad <- c("sapply", "subset", "attach")
    regex <- paste0("\\b", bad, "\\b")
    result <- sort(unlist(sapply(regex, FUN = grep, body(func), simplify = FALSE)))
    setNames(result, gsub("\\b", "", names(result), fixed = TRUE))
}
badLines(badLines)

## sapply1  subset  attach sapply2 
##       2       2       2       4 

【讨论】:

  • 有些人可能会发现lint 包对这种代码检查很有用。它足够灵活,您可以定义自己的规则。不过,它的学习曲线非常陡峭,文档/支持也很差。
  • @flodel 关于lint 包的好消息。我刚试过lint(dir("mypackage/R", full.names = TRUE)),它抛出了很多我以前没有发现的东西。
猜你喜欢
  • 2011-01-13
  • 2010-09-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多