我想使用两个agruments函数'func'创建一个函数向量,例如这个:
func = function(number, coefficient) {
return(coefficient*number)
}
这是我如何创建函数向量:
vector_of_functions = NULL
for (i in 1:4) {
vector_of_functions = c(vector_of_functions,
function(number) func(number=number, coefficient=i))
}
我的问题是组成我的矢量的所有函数都是相同的,即使它们是通过循环使用不同的i创建的。它接缝使用i的最后一个值(这是一个全局变量)进行评估。
有人有想法吗?
由于
答案 0 :(得分:4)
您可以通过在自己的本地环境中重新定义i
(由R中的函数i
方便地创建),将local
的值“附加”到每个函数。数据“附加”的结果函数称为“闭包”。
> vector_of_functions = NULL
> for (i in 1:4) {
+ vector_of_functions = c(vector_of_functions,
+ local({i <- i;function(number) func(number=number, coefficient=i)}))
+ }
> vector_of_functions[[1]](1)
[1] 1
> vector_of_functions[[2]](1)
[1] 2
> vector_of_functions[[3]](1)
[1] 3
> vector_of_functions[[4]](1)
[1] 4
答案 1 :(得分:3)
这可以使用eval-parse构造来解决,尽管我强烈建议你不来使用这个构造。它往往导致更多问题。但我无法获得一个体面的做法。
vector_of_functions = NULL
for (i in 1:4) {
vector_of_functions = c(vector_of_functions,
eval(parse(text=paste("function(number) func(number=number, coefficient=",i,")"))))
}
原因正如Aaron所解释的那样:函数定义中的所有内容都按原样进行,直到函数求值。
小注释:这尤其是列表的功能,而不是矢量。有一个“功能”类型的矢量是不可能的。它也绝对无用,因为你必须先使用索引[[]]选择函数才能使用它。然后我只是添加参数而不是为其中一个参数定义一个函数。
所以你想要实现的目标还不清楚,但如果你想用不同的系数应用func,我想知道你为什么不这样做:
> x <- c(10,20,30)
> sapply(1:4,function(y)func(number=x,coefficient=y))
[,1] [,2] [,3] [,4]
[1,] 10 20 30 40
[2,] 20 40 60 80
[3,] 30 60 90 120
Marek对主题的一种变体(避免解析):
vector_of_functions = NULL
for (i in 1:4) {
vector_of_functions = c(vector_of_functions,
eval(substitute(function(number) func(number=number, coefficient=i),list(i=i))))
}
你得到的1L等,只是表明它们是精确的整数(占用更少的内存空间)。
答案 2 :(得分:2)
问题是由于延迟评估,'i'变量在每一步都没有被评估,所以当你调用函数时它会使用最后一个值。创建强制函数是为了在这种情况下强制进行评估(在帮助页面上有一个与你的问题非常相似的?force的例子)。