检查R中某个参数之前的参数个数

时间:2013-10-12 15:50:54

标签: r

假设我们希望我们的函数能够处理两种情况:

somefun = function(x, y, method, ...) {
res = dowith(x, y)
res
}

somefun = function(z, method, ...) {
x = z$v1
y = z$v2
res = dowith(x, y)
res
}

我们如何让somefun了解这两种情况之间的区别?

2 个答案:

答案 0 :(得分:3)

如果您可以保证x永远不会成为列表,您可以使用is.list(x)来确定调用哪个版本的函数。否则,您可以使用missing

somefun<-function(x,y,method,...){
  if(missing(y)){
    cat("Using List version\n")
    y<-x$y
    x<-x$x
  }
  else{
    cat("Using normal version\n")   
  }
  c(x,y)
}

> somefun(list(x=1,y=2),method="a method")
Using List version
[1] 1 2
> somefun(1,2,method="a method")
Using normal version
[1] 1 2
> 

但是,请注意,如果您这样做,并且您想要使用该函数的列表版本,那么method及其之后的所有内容都必须按名称传递,否则R将绑定它们到y

> somefun(list(x=1,y=2),"a method")
Using normal version
$x
[1] 1

$y
[1] 2

[[3]]
[1] "a method"

> somefun(list(x=1,y=2),method="a method",5)
Using normal version
$x
[1] 1

$y
[1] 2

[[3]]
[1] 5

> somefun(list(x=1,y=2),method="a method",q=5)
Using List version
[1] 1 2

答案 1 :(得分:1)

我不知道自动执行此操作的方法,但在处理这些类型的情况时,使用switch有时会很有帮助。这是一个基本的例子:

somefun <- function(x, y = NULL, type = c("DF", "vecs"), method = NULL, ...) {
  switch(type,
         DF = sum(x[["v1"]], x[["v2"]]),
         vecs = sum(x, y),
         stop("'type' must be either 'DF' or 'vecs'"))
}

somefun(x = 10, y = 3, type="vecs")
# [1] 13
somefun(x = data.frame(v1 = 2, v2 = 4), type="DF")
# [1] 6
somefun(x = data.frame(v1 = 2, v2 = 4), type = "meh")
# Error in somefun(x = data.frame(v1 = 2, v2 = 4), type = "meh") : 
#   'type' must be either 'DF' or 'vecs'

在上文中,我们期望用户必须输入type参数,其中可接受的值是“DF”或“vecs”,并且已为每个选项定义了一组不同的操作。

当然,我还会编写一组不同的场景,并在函数开头使用一些条件检查,以确保事情按预期工作。例如,如果您期望大多数时间,人们将输入data.frame,您可以执行if (is.null(y) & is.null(type)) temp <- "DF"之类的操作(或在其中插入try类型语句)。在一天结束时,它还取决于您是否可以预测一组合理的默认值。

如果您的函数很复杂,您可能希望将switch中的步骤分离为单独的函数,因为这可能会导致更易读(更容易重用)的代码。