这是一个非常简单和一般性的问题,但我还没有看到它已经讨论过了.我希望我没有错过任何东西.
我开始设计具有多层功能的大型程序,虽然其他编程语言中有明确的策略,但我无法在R中找到关于如何处理也将具有"参数"的函数的"参数"的规范解决方案".我在"参数"和"参数"之间做了一个概念上的区别,即使它们实际上与函数相同:输入.前者将设置在更高级别,而不是经常更改,而后者是函数将处理的真实数据.
让我们考虑这个简单的例子

感兴趣的子函数SF()通过"WORKER"用不同的参数多次查询,但具有相同的参数,设置在"上方".当然,同样的问题适用于具有多个层的更复杂的情况.
我认为有两种方法可以处理:1.传递一切,但是:a.你最终会在函数调用中包含无数的参数,或者包含所有这些参数的结构.湾 因为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)
}
Run Code Online (Sandbox Code Playgroud)
编辑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)
}
}
Run Code Online (Sandbox Code Playgroud)
我发现每次评估子函数的"type"参数都是非理想的.似乎@hadley给闭包带来的参考和@Greg的解释是我需要的解决方案的良好轨道.
我认为您可能正在寻找词法范围。R 使用词法作用域,这意味着如果您在 F 内部定义函数 WORKER 和 SF,那么它们将能够访问 的当前值,而param无需将其向下传递。
如果您无法利用词法作用域(SF 必须在 F 之外定义),那么另一个选择是创建一个新环境来存储您的参数,然后如果所有需要的函数都可以访问该环境(通过显式传递,或者通过继承(使该环境成为函数的封闭环境)),然后 F 可以分配param到该环境中,并且其他函数可以访问该值。
| 归档时间: |
|
| 查看次数: |
650 次 |
| 最近记录: |