这是一个非常简单和普遍的问题,但我还没有看到它已经讨论过。我希望我没有错过任何东西。
我开始设计具有多层函数的大型程序,虽然在其他编程语言中有明确的策略,但我在 R 中找不到关于如何处理也将具有“参数”的函数的“参数”的规范解决方案”。我在“参数”和“参数”之间做出了概念上的区别,即使它们实际上与函数相同:输入。前者将设置在更高的级别,并且不会经常更改,而后者是函数将处理的真实数据。
让我们考虑这个简单的例子:
“WORKER”使用不同的参数多次查询感兴趣的子函数 SF(),但使用相同的参数,设置为“above”。当然,同样的问题也适用于具有多层的更复杂的情况。
我看到了两种处理方法: 1. 传递一切,但是:你最终会在你的函数调用中得到无数的参数,或者一个包含所有这些参数的结构。湾。因为 R 会复制参数来调用函数,所以它可能效率不高。2. 每次更改参数时动态评估函数,并将它们“硬连线”到函数定义中。但我不确定如何做到这一点,尤其是以一种干净的方式。
这一切似乎都不是很讨人喜欢,所以我想知道你们是否对这件事有意见?也许我们可以使用 R 的一些环境特性?:-)
谢谢!
编辑:因为对于某些人来说,代码比图表好,这是一个虚拟示例,我在其中使用了方法“1.”,将所有参数传递过来。如果我有很多层和子函数,将所有参数传递给中间层(这里是 WORKER())似乎不太好。(从代码和性能的角度来看)
F <- function(){
param <- getParam()
result <- WORKER(param)
return(result)
}
getParam <- function(){
return('O')
}
WORKER <- function(param) {
X <- LETTERS[1:20]
interm.result <- sapply(X,SF,param) # The use of sapply here negates maybe the performance issue?
return(which(interm.result=='SO'))
}
SF <- function(x,param) {
paste0(x,param)
}
编辑 2:上面示例的简单性误导了一些关注我的问题的人,所以这里有一个更具体的说明,使用离散梯度下降。同样,我保持简单,所以一切都可以写在同一个大函数中,但这不是我想要为我的真正问题做的事情。
gradientDescent <- function(initialPoint= 0.5, type = 'sin', iter_max = 100){
point <- initialPoint
iter <- 1
E <- 3
deltaError <- 1
eprev <- 0
while (abs(deltaError) > 10^(-2) | iter < iter_max) {
v_points <- point + -100:100 / 1000
E <- sapply(v_points, computeError, type)
point <- v_points[which.min(E)]
ef <- min(E)
deltaError <- ef - eprev
eprev <- ef
iter <- iter+1
}
print(point)
return(point)
}
computeError <- function(point, type) {
if (type == 'sin') {
e <- sin(point)
} else if (type == 'cos') {
e <- cos(point)
}
}
我发现每次评估子函数时都传递子函数的“类型”参数不是最佳选择。似乎@hadley 对闭包的引用和@Greg 的解释是我需要的解决方案的好方法。