在R中同时检查所有函数参数的长度

在R中同时检查所有函数参数的长度,r,function,R,Function,作为合理性检查,我希望当下面函数seda中的任何参数是长度大于1的向量时,函数停止 问题:是否有方法使用match.call或formals等,而不是单独列出所有函数参数(此处x,y,z),以便可以立即检查所有函数参数 我尝试了以下方法,但没有成功: seda <- function(x, y, z){ is.v <- function(...) lengths(list(...)) > 1 if(is.v(match.call())) stop("Error") #

作为合理性检查,我希望当下面函数
seda
中的任何参数是长度大于1的向量时,函数停止

问题:是否有方法使用
match.call
formals
等,而不是单独列出所有函数参数(此处
x
y
z
),以便可以立即检查所有函数参数

我尝试了以下方法,但没有成功:

seda <- function(x, y, z){

  is.v <- function(...) lengths(list(...)) > 1
  if(is.v(match.call())) stop("Error") # instead of `is.v(x, y, z)`

  x + y + z
}

seda(2, 2, 3)
seda(c(2, 3), 2, 3)
seda
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)

感谢@erocoar指出,
match.call
可以用来代替
sys.call
,而
as.list
是不必要的。

你可以调整一下你所拥有的来让它工作:

seda[1]3
轿车(1,1,1:2)
#>错误:长度(列表(…)==1不都是真的
…或使用命名参数

seda_命名[1]3
命名为seda_(1,1,1:2)
#>错误:长度(列表(x,y,z))==1不都是真的

要使用
stop
而不是
stopifnot
来控制错误消息,请将条件包装在
all

中。如果同时测试了所有条件,则错误消息不会说明问题出在哪个参数上。下面在一个循环中测试它们,并指出错误消息中哪个参数有问题

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

seda我非常感谢我的专家同事们的意见。根据你的宝贵意见,我想我想要的是:

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)
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)
seda 1)停止(“错误”)
x+y+z
}
轿车(c(2,3),2,3)
轿车(2,2,3)

为什么不使用
pars=match.call()
?是的,对,只需要将其转换为列表。出于某种原因,我想到了
sys.call()
,然后意识到我需要将其转换为一个列表,但没有想到只使用
match.call()
。谢谢我会更新我的答案。(查看帮助,我看到
match.call
实际上使用了
sys.call
)是的,考虑到这一点,我认为您可以同时使用
sys.call()
match.call()
而不使用
as.list()
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
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
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)
   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)
    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)