作为一个完整性检查,我希望当下面的函数seda
中的任何参数是长度大于1的向量时,函数会停止。
问题:而不是单独列出所有函数参数(此处为x
,y
,z
),是否可以使用{{1} }或match.call
等,以便可以立即检查所有函数参数?
我尝试了以下但没有成功:
formals
答案 0 :(得分:2)
match.call()
将捕获函数的参数,然后可以测试其长度。我们使用sapply
返回一个带有每个函数参数长度的向量,并使用any
函数来测试任何参数的长度是否大于1。
seda <- function(x, y, z){
if(any(sapply(match.call()[-1], length) > 1)) stop("All arguments must be length 1")
x + y + z
}
seda(2, 2, 3)
[1] 7
seda(c(2, 3), 2, 3)
Error in seda(c(2, 3), 2, 3) : All arguments must be length 1
感谢@erocoar指出可以使用match.call
代替sys.call
,而as.list
是不必要的。
答案 1 :(得分:1)
你可以调整一下你可以使用的东西:
seda <- function(...){
stopifnot(lengths(list(...)) == 1)
sum(...)
}
seda(1, 1, 1)
#> [1] 3
seda(1, 1, 1:2)
#> Error: lengths(list(...)) == 1 are not all TRUE
...或使用命名参数
seda_named <- function(x, y, z){
stopifnot(lengths(list(x, y, z)) == 1)
x + y + z
}
seda_named(1, 1, 1)
#> [1] 3
seda_named(1, 1, 1:2)
#> Error: lengths(list(x, y, z)) == 1 are not all TRUE
要使用stop
代替stopifnot
以控制错误消息,请将条件包装在all
中。
答案 2 :(得分:0)
如果一次性测试它们,则错误消息不会说明哪个参数是问题。下面在循环中对它们进行测试,并确实指出错误消息中哪个是有问题的参数。
seda <- function(x, y, z) {
argnames <- names(match.call()[-1])
for(nm in argnames) if (length(get(nm)) != 1) stop(nm, " does not have length 1")
x + y + z
}
# test - note that the error message names z
seda(10, 20, 1:2)
## Error in seda(10, 20, 1:2) : z does not have length 1
当然,如果你真的有3个参数,那么将它写出来会简单得多。这也提供了参数特定的错误消息:
seda <- function(x, y = 1, z) {
stopifnot(length(x) == 1, length(y) == 1, length(z) == 1)
x + y + z
}
seda(10, 20, 1:2)
## Error: length(z) == 1 is not TRUE
答案 3 :(得分:0)
我非常感谢我的专家同事的投入。使用您宝贵的意见,我想我想要的是以下内容:
seda <- function(x, y, z){
if(lengths(list(get(names(match.call()[-1])))) > 1) stop("Error")
x + y + z
}
seda(c(2, 3), 2, 3)
seda(2, 2, 3)
我们也可以使用formals
:
seda <- function(x, y, z){
if(lengths(list(get(names(formals(seda))))) > 1) stop("Error")
x + y + z
}
seda(c(2, 3), 2, 3)
seda(2, 2, 3)
或formalArgs
喜欢这样:
seda <- function(x, y, z){
if(lengths(list(get(formalArgs(seda)))) > 1) stop("Error")
x + y + z
}
seda(c(2, 3), 2, 3)
seda(2, 2, 3)