累积函数和闭包 [英] accumulating functions and closures in R

查看:124
本文介绍了累积函数和闭包的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在构造一个近似函数递归(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!

这篇关于累积函数和闭包的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆