是否可以让软件忽略在运行模块时定义了未使用的参数这一事实?
例如,我有一个模块,它返回和multiply(a,b)
的乘积。如果我像这样调用模块,我会收到一个错误:a
b
multiply(a=20,b=30,c=10)
对此返回错误似乎有点不必要,因为所需的输入a
和b
已指定。是否有可能避免这种不良行为?
一个简单的解决方案就是停止指定c
,但这并不能解释为什么 R 会这样。还有其他方法可以解决这个问题吗?
是否可以让软件忽略在运行模块时定义了未使用的参数这一事实?
例如,我有一个模块,它返回和multiply(a,b)
的乘积。如果我像这样调用模块,我会收到一个错误:a
b
multiply(a=20,b=30,c=10)
对此返回错误似乎有点不必要,因为所需的输入a
和b
已指定。是否有可能避免这种不良行为?
一个简单的解决方案就是停止指定c
,但这并不能解释为什么 R 会这样。还有其他方法可以解决这个问题吗?
更改 multiply 的定义以获取额外的未知参数:
multiply <- function(a, b, ...) {
# Original code
}
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
一种方法(我无法想象这是良好的编程习惯)是添加...
传统上用于将一个函数中指定的参数传递给另一个函数的方法。
> 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
您可以在此处阅读更多关于...
旨在使用的信息
您可以在函数定义中使用点:...
。
myfun <- function(a, b, ...){
cat(a,b)
}
myfun(a=4,b=7,hello=3)
# 4 7
我和你有同样的问题。我有一长串论据,其中大部分是无关紧要的。我不想硬编码它们。这就是我想出的
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
R 有一个函数 prod() 可以很好地进行乘法运算。提问者给出的示例在 prod() 函数中运行良好,不会返回错误。`
prod(a=20,b=30,c=10)
# 6000
在任何情况下,突出显示的错误都是纠正它的机会,所以不是坏行为。
由于已经有许多答案直接解决了这个问题,而且 R 经常被技术熟练的非程序员使用,让我快速概述错误存在的原因,并建议不要使用抑制解决方法。
参数的数量是定义函数的一个重要方面。如果参数的数量不匹配,这很好地表明调用者的意图与函数将要执行的操作之间存在不匹配。出于这个原因,这将是许多编程语言中的编译错误,包括 Java、Python、Haskell 和许多其他语言。事实上,如果类型不匹配,许多这些语言中更严格的类型检查也会导致错误。
随着程序规模的增长和代码的老化,很难发现这种不匹配是有意的还是真正的错误。这就是为什么“干净代码”的想法——简单易读的代码,没有错误或警告——通常是专业程序员的标准工作。
因此,我建议重新编写代码以删除不必要的参数。以后为自己和他人理解和调试会更简单。
当然,我知道 R 用户经常使用生命周期有限的小脚本,而大型软件工程项目的通常权衡并不总是适用。也许对于您的快速脚本,它只会使用一周,只是抑制错误是有意义的。然而,人们普遍观察到(我从我自己的经验中看到),在撰写本文时,代码的持久性很少是显而易见的。如果您正在追求开放科学,并发布您的代码和数据,那么该代码在未来对其他人有用,这样他们就可以重现您的结果,这将特别有帮助。