如何遍历分配内部(嵌套)函数? (我应该使用什么环境?)

时间:2017-11-03 13:56:42

标签: r assign tidyverse

tl; dr / summary

我有一个函数,它接受一个包含许多元素的列表作为参数。我希望能够通过在函数内分配这些元素来直接处理这些元素。由于我有许多元素,我想使用walk包中的tidyverse函数。

library(tidyverse)
list <- (a = 1, b = 2)
func <- function(x){
  walk2(names(x), x, assign, envir = {some environment})
  {Rest of the function, where I can use a and b instead of x$a and x$b}
}

我应该使用什么环境?并且parent.frame()没有工作,请参阅下文。

为什么parent.frame()无法正常工作

第1步:没有函数 - 这里需要parent.frame()(因为你在函数中使用了assign)。但如果你这样做,一切正常。

x <- list(a = 1, b = 2)
a <- 0
b <- 0

# Doesn't work:

walk2(names(x), x, assign)
a
b

# Does work:

walk2(names(x), x, assign, envir = parent.frame())
a
b

第2步:一个功能 - 当你在一个函数中做同样的事情时,事情会变得更复杂。使用parent.frame()作为环境也会导致变量在全局环境中发生变化。

func <- function(x) {

  walk2(names(x), x, assign)
  print(paste0("a inside func without parent.frame() is ", a))
  print(paste0("b inside func without parent.frame() is ", b))

  walk2(names(x), x, assign, envir = parent.frame())
  print(paste0("a inside func with parent.frame() is ", a))
  print(paste0("b inside func with parent.frame() is ", b))

}

# Using envir = parent.frame() seems to work at first

x <- list(a = 1, b = 2)
a <- 0
b <- 0
func(x)

# But a and b get overwritten in the global environment as well (unwanted)

a
b

这是不可取的。当您在&#34; normal&#34;中分配时,不会发生这种情况。方式如下例所示。

# How it should work

func_desired <- function(x){

  a <- x[[1]]
  b <- x[[2]]

  print(paste0("a inside func_alt is ", a))
  print(paste0("b inside func_alt is ", b))

}

# a and b are correctly assigned within the function

x <- list(a = 1, b = 2)
a <- 0
b <- 0
func_desired(x)

# But outside of the function a and b are not altered

a
b

第3步:嵌套函数 - 这里很明显,使用parent.frame()将分配不在调用walk的环境中的变量,而是在其后面的变量。

func2 <- function(x){

  func(x)

  print(paste0("a inside func2 is ", a))
  print(paste0("b inside func2 is ", b))

}

# a and b are assigned 1 and 2 inside func2, 
# But in the global environment they stay unchanged (both 0)
# func (called from func2) will look in the global environment and find a = b = 0

x <- list(a = 1, b = 2)
a <- 0
b <- 0
func2(x)
a
b

我的问题

我应该使用什么环境才能使其按预期工作,即所有变量都分配给列表中的名称,但仅限于调用walk的函数的环境中。?

0 个答案:

没有答案