ř范围:强制变量替换在功能而不当地环境(R scope: force variable substi

2019-07-23 09:03发布

我定义函数在一个循环中,并试图强制循环变量的评价,而不必随身携带的私人环境。

例如:一组功能的handlers$h1handlers$h2 ,..., handlers$h6 ,仅仅通过1,2,...,6到像这样另一功能:

handlers <- list()
for (i in 1:6) {
    handlers[[paste0('h', i)]] <- function () {
        message(i) # <-- example
    }
}

因此, handlers$h1()应消息1, handlers$h2()应消息2,...

相反,所有的函数返回6电流i

为了解决这个问题,我可以使用闭包作为在这个问题上规定

msg <- function(i) {
    force(i)
    function () { message(i) }
}

for (i in 1:6) {
    handlers[[paste0('h', i)]] <- msg(i)
}

现在,每个功能正常工作, 每个函数必须携带自己的环境:

handlers$h1
# function () { message(i) }
# <environment: 0x9342b80>

我怎样才能让这个handlers$h1打印function () { message(1) } ,即评估i ,直接替换成的定义,消除了对环境的需要?

我能想到的唯一的办法是:

  • 使用eval (东西我不喜欢这样做);
  • 用手与1-6直接取代的写出的每个定义(在这种情况下细那里只有6的功能,但在一般的不可伸缩)

Answer 1:

下面是一些使用方法body<-

你可以使用bquote

handlers <- list()

for (i in 1:6) {
  handlers[[paste0('h', i)]] <- function () {}
  body( handlers[[paste0('h', i)]]) <- bquote(message(.(i)))
}

handlers$h1
## function () 
##   message(1L)

substitute

for (i in 1:6) {
  handlers[[paste0('h', i)]] <- function () {}
  body( handlers[[paste0('h', i)]]) <- substitute(message(i), list(i=i))
}


Answer 2:

不幸的是基础R缺少手工制作的功能的功能,但pryr用品make_function

library(pryr)

handlers <- list()
for (i in 1:6) {
  body <- substitute(message(i), list(i = i))
  f <- make_function(alist(), body)

  handlers[[paste0('h', i)]] <- f
}

注意,这里使用的substitute手动修改引用调用。

另一个冷却(!IMO)在pryr功能是unenclose ,其通过在封闭环境中定义的变量代unencloses的函数:

msg <- function(i) {
    force(i)
    function () message(i)
}
msg(1)
# function () message(i)
# <environment: 0x102dc6ca0>
unenclose(msg(1))
# function () 
# message(1)

但他们真的是没有缺点使用原始封闭。



Answer 3:

这里有两种方法。 他们除了在每个##行相同:

正式< -

handlers <- list()
f <- function() message(i)
for (i in 1:6) { 
   formals(f) <- list(i = i) ##
   handlers[[paste0('h', i)]] <- f 
}

跟踪

handlers <- list()
f <- function() message(i)
for (i in 1:6) { 
   trace(f, bquote(i <- .(i)), print = FALSE) ##
   handlers[[paste0('h', i)]] <- f 
}


文章来源: R scope: force variable substitution in function without local environment
标签: r scope