假设我们希望我们的函数能够处理两种情况:
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
了解这两种情况之间的区别?
答案 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
中的步骤分离为单独的函数,因为这可能会导致更易读(更容易重用)的代码。