递归地将列表变量发送到全局环境

时间:2014-10-02 19:55:19

标签: r recursion

考虑以下嵌套列表nest

nest <- list(
    A = list(w = 1:5, x = letters[1:5]),
    B = list(y = 6:10, z = LETTERS[1:5])
)

我想将nest中的所有个别变量发送到全局环境。也就是说,列表AB以及向量wxyz都应该转到全局环境。以下是我的一些尝试以及他们的结果。请注意,所有这些只会将某些变量发送到全局环境。

list2env(nest, .GlobalEnv)
ls()
# [1] "A"    "B"    "nest"
list2env(unlist(nest, recursive = FALSE), .GlobalEnv)
ls()
# [1] "A.w"  "A.x"  "B.y"  "B.z"  "nest"
lapply(nest, list2env, envir = .GlobalEnv)
ls()
# [1] "nest" "w"    "x"    "y"    "z"   
with(nest, list2env(mget(ls()), .GlobalEnv))
ls()
# [1] "A"    "B"    "nest"

我还尝试了其他递归可能性并遇到错误,因为当list2env点击列表底部时,它会发现x不是列表。

rapply(nest, list2env, envir = .GlobalEnv)
# Error in (function (x, envir = NULL, parent = parent.frame(), 
#   hash = (length(x) >  : first argument must be a named list
with(nest, {
    obj <- mget(ls())
    do.call(list2env, c(obj, envir = .GlobalEnv))
})
# Error in (function (x, envir = NULL, parent = parent.frame(), 
#     hash = (length(x) >  : unused arguments (A = list(w = 1:5, 
#     x = c("a", "b", "c", "d", "e")), B = list(y = 6:10, 
#     z = c("A", "B", "C", "D", "E")))

如何递归调用list2env以便所有变量都转到全局环境?从新的R会话中,ls()将导致

# [1] "A" "B" "nest" "w" "x" "y" "z"

我也尝试过local并遇到同样的问题。

2 个答案:

答案 0 :(得分:8)

使用递归函数。不优雅,但似乎有效:

nest <- list(A = list(w = 1:5, x = letters[1:5]),
             B = list(y = 6:10, z = LETTERS[1:5]))

test <- function(x) {
    if(is.list(x)) { 
        list2env(x, envir = .GlobalEnv)
        lapply(x, test)
    }
}

test(nest)
ls()
# [1] "A"    "B"    "nest" "test" "w"    "x"    "y"    "z"   

答案 1 :(得分:0)

rrapply软件包中使用rrapply的另一种方法(基本版本{rapply的扩展版本):

library(rrapply)

nest <- list(
  A = list(w = 1:5, x = letters[1:5]),
  B = list(y = 6:10, z = LETTERS[1:5])
)

ls()
#> [1] "nest"

out <- rrapply(
  nest, 
  classes = c("list", "ANY"),
  f = function(x, .xname) assign(.xname, x, envir = .GlobalEnv), 
  how = "recurse"
)

ls()
#> [1] "A"    "B"    "nest" "w"    "x"    "y"    "z"

在此处,在全局环境中,每个节点(x)的内容都被分配为其名称(.xname)。将how = "recurse"函数应用到嵌套列表中的每个节点后,f继续递归。