29

是否可以让软件忽略在运行模块时定义了未使用的参数这一事实?

例如,我有一个模块,它返回和multiply(a,b)的乘积。如果我像这样调用模块,我会收到一个错误:ab

multiply(a=20,b=30,c=10)

对此返回错误似乎有点不必要,因为所需的输入ab已指定。是否有可能避免这种不良行为?

一个简单的解决方案就是停止指定c,但这并不能解释为什么 R 会这样。还有其他方法可以解决这个问题吗?

4

7 回答 7

42

更改 multiply 的定义以获取额外的未知参数:

multiply <- function(a, b, ...) {
  # Original code
}
于 2012-04-22T17:46:51.497 回答
12

R.utils 包有一个名为 doCall 的函数,它类似于 do.call,但如果传递了未使用的参数,它不会返回错误。

multiply <- function(a, b) a * b

# these will fail
multiply(a = 20, b = 30, c = 10)
# Error in multiply(a = 20, b = 30, c = 10) : unused argument (c = 10)
do.call(multiply, list(a = 20, b = 30, c = 10))
# Error in (function (a, b)  : unused argument (c = 10)

# R.utils::doCall will work
R.utils::doCall(multiply, args = list(a = 20, b = 30, c = 10))
# [1] 600
# it also does not require the arguments to be passed as a list
R.utils::doCall(multiply, a = 20, b = 30, c = 10)
# [1] 600
于 2018-04-20T20:02:05.157 回答
9

一种方法(我无法想象这是良好的编程习惯)是添加...传统上用于将一个函数中指定的参数传递给另一个函数的方法。

> multiply <- function(a,b) a*b
> multiply(a = 2,b = 4,c = 8)
Error in multiply(a = 2, b = 4, c = 8) : unused argument(s) (c = 8)
> multiply2 <- function(a,b,...) a*b
> multiply2(a = 2,b = 4,c = 8)
[1] 8

您可以在此处阅读更多关于...旨在使用的信息

于 2012-04-22T17:47:46.133 回答
7

您可以在函数定义中使用点:...

myfun <- function(a, b, ...){
  cat(a,b)
}

myfun(a=4,b=7,hello=3)

# 4 7
于 2012-04-22T17:48:48.847 回答
3

我和你有同样的问题。我有一长串论据,其中大部分是无关紧要的。我不想硬编码它们。这就是我想出的

library(magrittr)
do_func_ignore_things <- function(data, what){
    acceptable_args <- data[names(data) %in% (formals(what) %>% names)]
    do.call(what, acceptable_args %>% as.list)
}

do_func_ignore_things(c(n = 3, hello = 12, mean = -10), "rnorm")
# -9.230675 -10.503509 -10.927077
于 2017-04-06T01:32:07.123 回答
0

R 有一个函数 prod() 可以很好地进行乘法运算。提问者给出的示例在 prod() 函数中运行良好,不会返回错误。`

prod(a=20,b=30,c=10)

 # 6000

在任何情况下,突出显示的错误都是纠正它的机会,所以不是坏行为。

于 2021-05-17T10:40:11.960 回答
0

由于已经有许多答案直接解决了这个问题,而且 R 经常被技术熟练的非程序员使用,让我快速概述错误存在的原因,并建议不要使用抑制解决方法。

参数的数量是定义函数的一个重要方面。如果参数的数量不匹配,这很好地表明调用者的意图与函数将要执行的操作之间存在不匹配。出于这个原因,这将是许多编程语言中的编译错误,包括 Java、Python、Haskell 和许多其他语言。事实上,如果类型不匹配,许多这些语言中更严格的类型检查也会导致错误。

随着程序规模的增长和代码的老化,很难发现这种不匹配是有意的还是真正的错误。这就是为什么“干净代码”的想法——简单易读的代码,没有错误或警告——通常是专业程序员的标准工作。

因此,我建议重新编写代码以删除不必要的参数。以后为自己和他人理解和调试会更简单。

当然,我知道 R 用户经常使用生命周期有限的小脚本,而大型软件工程项目的通常权衡并不总是适用。也许对于您的快速脚本,它只会使用一周,只是抑制错误是有意义的。然而,人们普遍观察到(我从我自己的经验中看到),在撰写本文时,代码的持久性很少是显而易见的。如果您正在追求开放科学,并发布您的代码和数据,那么该代码在未来对其他人有用,这样他们就可以重现您的结果,这将特别有帮助。

于 2021-06-02T05:32:15.310 回答