Function Factory in R

怎甘沉沦 提交于 2019-12-22 05:26:15

问题


I try to come up with a function factory by returning a dictionary of specialized functions, more or less like functional programming style. I try to do this in the following code.

require(hash)

names = c("aa","bb","cc");
funs = hash()
for (i in seq(length(names))) {
  n = names[i]
  funs[[n]] = function(x) { 
    print(paste(n,":",x, sep="")) 
 }
}

Obviously, I have 3 functions in the array; however, they all behave the same as the last function in the iteration.

> funs[["aa"]](1)
[1] "cc:1"
> funs[["bb"]](2)
[1] "cc:2"
> funs[["cc"]](3)
[1] "cc:3"

My guess is that R didn't create new function instance but reuses the same function object inside the for-loop.

I try the following in hope that R will create different function object,

  funs[[n]] = eval(parse(text="function(x) { print(paste(n,':',x, sep='')) }"))

but it works the same as the first one.

Do you have an idea how to create a generator that creates different function objects?


回答1:


According to Hadley's Advanced R Programmin, Lexical scoping, the variable n in the body of functions funs[['aa']], funs[['bb']], and funs[['cc']] are the variable n in <environment: R_GlobalEnv>.

For example:

> funs[["aa"]](1)
[1] "cc:1"
> n <- "1234"
> funs[["aa"]]("1")
[1] "1234:1"

To do what you want, I'll write a function which returns a function:

funs.gen <- function(n) {
  force(n)
  function(x) {
    print(paste(n, ":", x, sep=""))
  }  
}

names = c("aa","bb","cc");
funs = hash()
for (i in seq(length(names))) {
  n = names[i]
  funs[[n]] = funs.gen(n)
}

funs[["aa"]](1)
funs[["bb"]](2)
funs[["cc"]](3)

Note that force is used to ask R not lazy evaluate expression n. If you remove it, then R will evaluate n out of the for loop which will produce the same result as your question.



来源:https://stackoverflow.com/questions/19749923/function-factory-in-r

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!