我正在写一个R函数,它变得非常大.它允许多种选择,我正在组织它:
myfun <- function(y, type=c("aa", "bb", "cc", "dd" ... "zz")){
if (type == "aa") {
do something
- a lot of code here -
....
}
if (type == "bb") {
do something
- a lot of code here -
....
}
....
}
Run Code Online (Sandbox Code Playgroud)
我有两个问题:
如果我写子功能,它看起来像这样:
myfun <- function(y, type=c("aa", "bb", "cc", "dd" ... "zz")){
if (type == "aa") result <- sub_fun_aa(y)
if (type == "bb") result <- sub_fun_bb(y)
if (type == "cc") result <- sub_fun_cc(y)
if (type == "dd") result <- sub_fun_dd(y)
....
}
Run Code Online (Sandbox Code Playgroud)
子功能当然在其他地方定义(在myfun的顶部,或以其他方式).
我希望我对我的问题很清楚.提前致谢.
- 附加信息 -
我正在编写一个函数,将一些不同的滤镜应用于图像(不同的滤镜=不同的"类型"参数).一些过滤器共享一些代码(例如,"aa"和"bb"是两个高斯过滤器,它们仅对一个行代码不同),而其他过滤器完全不同.
所以我被迫使用了很多if语句,即
if(type == "aa" | type == "bb"){
- do something common to aa and bb -
if(type == "aa"){
- do something aa-related -
}
if(type == "bb"){
- do something bb-related -
}
}
if(type == "cc" | type == "dd"){
- do something common to cc and dd -
if(type == "cc"){
- do something cc-related -
}
if(type == "dd"){
- do something dd-related -
}
}
if(type == "zz"){
- do something zz-related -
}
Run Code Online (Sandbox Code Playgroud)
等等.此外,代码中有一些if语句"做某事".我正在寻找组织代码的最佳方式.
一种选择是使用switch而不是多个if语句:
myfun <- function(y, type=c("aa", "bb", "cc", "dd" ... "zz")){
switch(type,
"aa" = sub_fun_aa(y),
"bb" = sub_fun_bb(y),
"bb" = sub_fun_cc(y),
"dd" = sub_fun_dd(y)
)
}
Run Code Online (Sandbox Code Playgroud)
在您编辑的问题中,您提供了更具体的信息.以下是您可能需要考虑的一般设计模式.这种模式的关键因素是看不到任何一个if.我替换它match.function,其中关键的想法是type你的函数本身就是一个函数(是的,因为R支持函数式编程,这是允许的):
sharpening <- function(x){
paste(x, "General sharpening", sep=" - ")
}
unsharpMask <- function(x){
y <- sharpening(x)
#... Some specific stuff here...
paste(y, "Unsharp mask", sep=" - ")
}
hiPass <- function(x) {
y <- sharpening(x)
#... Some specific stuff here...
paste(y, "Hipass filter", sep=" - ")
}
generalMethod <- function(x, type=c(hiPass, unsharpMask, ...)){
match.fun(type)(x)
}
Run Code Online (Sandbox Code Playgroud)
并称之为:
> generalMethod("stuff", "unsharpMask")
[1] "stuff - General sharpening - Unsharp mask"
> hiPass("mystuff")
[1] "mystuff - General sharpening - Hipass filter"
Run Code Online (Sandbox Code Playgroud)
几乎没有理由不将您的代码重构为更小的函数.在这种情况下,除了重组之外,还有一个额外的好处:如果知道她在哪里,你的功能的受过教育的用户可以立即调用子功能.
如果这些函数有很多参数,那么解决方案(以便于维护)可以将它们分组到类"myFunctionParameters"的列表中,但取决于您的情况.
如果代码在不同的sub_fun_xxs之间共享,只需将其插入到每个sub_fun_xxs中使用的另一个函数中,或者(如果可行的话)先计算内容并将其直接传递给每个sub_fun_xx.