定义 R 函数列表
Define list of R functions
我正在尝试在循环中定义一个函数列表,如下所示:
rr <- list(); ss <- list(list(1,2),list(3,4))
for (i in 1:length(ss)) {
A <- ss[[i]][1]
B <- ss[[i]][2]
print(paste("A, B:", A, ",", B))
rr[[i]] <- function () { force(B); B }
}
print
语句给出:
[1] "A, B: 1 , 2"
[1] "A, B: 3 , 4"
...这就是我想要的!但是,当我尝试使用这些函数时,我得到了错误的答案(我认为 A
和 B
被延迟评估并等到函数被实际调用以获取它们的值):
> environment(rr[[1]])$A
[[1]]
[1] 3
> rr[[1]]()
[[1]]
[1] 4
> environment(rr[[2]])$A
[[1]]
[1] 3
> rr[[2]]()
[[1]]
[1] 4
如何重写上面的for
循环,使每个函数rr[[i]]
都有自己的内部参数集,不会被修改通过稍后的 rr[[n > i]]
函数定义?
编辑: 我下面的解决方案可能会对某些人有所帮助,所以我会把它留在这里供后代使用,但是 user2554330's 对于我的用例来说是一个更好的解决方案。
啊哈!在 this answer:
的帮助下,我弄明白了
rr <- list(); ss <- list(list(1,2),list(3,4))
for (i in 1:length(ss)) {
rr[[i]] <- function(x){}
body(rr[[i]]) <- parse(text={
paste("(", ss[[i]][[1]], "<= x) && (x <=", ss[[i]][[2]], ")")
})
}
> rr[[1]](1.5) # within range [1,2]
[1] TRUE
> rr[[1]](2.5)
[1] FALSE
> rr[[2]](3.5) # within range [3,4]
[1] TRUE
> rr[[2]](4.5)
[1] FALSE
记住fortunes::fortune(106)
。当然有更好的方法来做到这一点。
一种方法是创建一个 "function factory" 来捕获值。例如,
make_fn <- function(A, B) {
force(A)
force(B)
function(x) A <= x & x <= B
}
那么你的循环将是
for (i in 1:length(ss)) {
A <- ss[[i]][1]
B <- ss[[i]][2]
print(paste("A, B:", A, ",", B))
rr[[i]] <- make_fn(A, B)
}
编辑以添加对评论的回应:此处与 force()
的区别如下:force()
适用于承诺,即函数的参数。在你的例子中, B
从来不是任何函数的参数,所以它从来不是一个承诺,并且 force(B)
除了 return 它的价值之外什么都不做。在我的回答中,A
和 B
是 make_fn
的参数,所以当它被评估时它们是承诺,而 force()
导致它们的表达式被评估并且它们的值是已修复。
我正在尝试在循环中定义一个函数列表,如下所示:
rr <- list(); ss <- list(list(1,2),list(3,4))
for (i in 1:length(ss)) {
A <- ss[[i]][1]
B <- ss[[i]][2]
print(paste("A, B:", A, ",", B))
rr[[i]] <- function () { force(B); B }
}
print
语句给出:
[1] "A, B: 1 , 2"
[1] "A, B: 3 , 4"
...这就是我想要的!但是,当我尝试使用这些函数时,我得到了错误的答案(我认为 A
和 B
被延迟评估并等到函数被实际调用以获取它们的值):
> environment(rr[[1]])$A
[[1]]
[1] 3
> rr[[1]]()
[[1]]
[1] 4
> environment(rr[[2]])$A
[[1]]
[1] 3
> rr[[2]]()
[[1]]
[1] 4
如何重写上面的for
循环,使每个函数rr[[i]]
都有自己的内部参数集,不会被修改通过稍后的 rr[[n > i]]
函数定义?
编辑: 我下面的解决方案可能会对某些人有所帮助,所以我会把它留在这里供后代使用,但是 user2554330's
啊哈!在 this answer:
的帮助下,我弄明白了rr <- list(); ss <- list(list(1,2),list(3,4))
for (i in 1:length(ss)) {
rr[[i]] <- function(x){}
body(rr[[i]]) <- parse(text={
paste("(", ss[[i]][[1]], "<= x) && (x <=", ss[[i]][[2]], ")")
})
}
> rr[[1]](1.5) # within range [1,2]
[1] TRUE
> rr[[1]](2.5)
[1] FALSE
> rr[[2]](3.5) # within range [3,4]
[1] TRUE
> rr[[2]](4.5)
[1] FALSE
记住fortunes::fortune(106)
。当然有更好的方法来做到这一点。
一种方法是创建一个 "function factory" 来捕获值。例如,
make_fn <- function(A, B) {
force(A)
force(B)
function(x) A <= x & x <= B
}
那么你的循环将是
for (i in 1:length(ss)) {
A <- ss[[i]][1]
B <- ss[[i]][2]
print(paste("A, B:", A, ",", B))
rr[[i]] <- make_fn(A, B)
}
编辑以添加对评论的回应:此处与 force()
的区别如下:force()
适用于承诺,即函数的参数。在你的例子中, B
从来不是任何函数的参数,所以它从来不是一个承诺,并且 force(B)
除了 return 它的价值之外什么都不做。在我的回答中,A
和 B
是 make_fn
的参数,所以当它被评估时它们是承诺,而 force()
导致它们的表达式被评估并且它们的值是已修复。