问题描述
我正在构造一个近似函数递归(adaboost)。我想创建一个结果的学习功能(不直接应用近似直接到我的测试数据,但保持导致它的函数)
I am constructing an approximating function recursively (adaboost). I would like to create the resulting learning function along the way (not to apply the approximation directly to my test data but keep the function that leads to it)
不幸的是,它似乎R更新了变量名在使用后指向long的值。
unfortunately, it seems that R updates the value to which a variable name refers to long after it is used.
#defined in plyr as well
id <- function(x) {x}
#my first classifier
modelprevious <- function(inputx, k) { k(0)}
#one step of my superb model
modelf <- function(x) 2*x #for instance
#I update my classifier
modelCurrent <- function(inputx, k)
{ modelprevious(inputx, function(res) {k(res + modelf(inputx))})}
#it works
modelCurrent(2,id) #4
#Problem
modelf <- function(x) 3*x
modelCurrent(2,id) #6 WTF !!
具有相同参数的同一个函数返回不同的东西,这是很讨厌的!
The same function with the same argument return something different, which is quite annoying !
因此,如何捕获由modelf表示的值,以便生成的函数只取决于它在绑定时的参数,而不是某些全局状态?
So how is it possible to capture the value represented by modelf so that the resulting function only depends on its argument at the time of the binding, and not of some global state ?
鉴于这个问题,我不知道如何在R中构建一个递归函数
Given that problem I dont see how one can do a recursive function building in R if one can not touch local variable, apart going through ugly hacks of quote/parse
推荐答案
您需要一个工厂:
modelCurrent = function(mf){
return(function(inputx,k){
modelprevious(
inputx,
function(res){
k(res+mf(inputx))
} # function(res)
) # modelprevious
} # inner function
) # return
} # top function
现在您使用工厂创建模型c $ c> modelf 您希望它使用的函数:
Now you use the factory to create models with the modelf
function that you want it to use:
> modelf <- function(x) 2*x
> m1 = modelCurrent(modelf)
> m1(2,id)
[1] 4
> modelf <- function(x) 3*x
> m1(2,id) # no change.
[1] 4
您可以随时使用它们: / p>
You can always make them on an ad-hoc basis:
> modelCurrent(modelf)(2,id)
[1] 6
看到工厂使用当前定义 modelf
创建了一个函数,所以它乘以3。
and there you can see the factory created a function using the current definition of modelf
, so it multiplied by three.
ginormous WTF!?!这将打你。仔细观察:
There's one last ginormous WTF!?! that will hit you. Watch carefully:
> modelf <- function(x) 2*x
> m1 = modelCurrent(modelf)
> m1(2,id)
[1] 4
>
> m1 = modelCurrent(modelf) # create a function using the 2* modelf
> modelf <- function(x) 3*x # change modelf...
> m1(2,id) # WTF?!
[1] 6
这是因为当工厂被调用时, mf
不会被求值 - 这是因为内部函数不被调用,并且 mf
在调用内部函数之前不被使用。
This is because when the factory is called, mf
isn't evaluated - that's because the inner function isn't called, and mf
isn't used until the inner function is called.
诀窍是强制外部函数中 mf
的评估,通常使用 force
:
The trick is to force evaluation of the mf
in the outer function, typically using force
:
modelCurrent = function(mf){
force(mf)
return(function(inputx,k){
modelprevious(
inputx,
function(res){
k(res+mf(inputx))
} # function(res)
) # modelprevious
} # inner function
) # return
} # top function
这导致我过早的秃发,因为如果你忘记这一点,并认为有一些奇怪的bug,然后尝试贴 print(mf)
到位,看看发生了什么,你将评估 mf
,从而得到你想要的行为。通过检查数据,你改变了! A Heisenbug!
This has lead me to premature baldness, because if you forget this and think there's some odd bug going on, and then try sticking print(mf)
in place to see what's going on, you'll be evaluating mf
and thus getting the behaviour you wanted. By inspecting the data, you changed it! A Heisenbug!
这篇关于累积函数和闭包的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!