Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Recursively send list variables to the global environment

Tags:

r

recursion

Consider the following nested list, nest.

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

I'd like to send all the individual variables in nest to the global environment. That is, the lists A and B, and the vectors w, x, y, and z should all go to the global environment. Here are a few of my tries along with their results. Notice that all of these only send some of the variables to the global environment.

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"

I also tried other recursive possibilities and got errors because when list2env hits the bottom of the list, it finds that x is not a list.

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")))

How can I recursively call list2env so that all variables go to the global environment? From a fresh R session, ls() would result in

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

I've also experimented with local and am having the same problem.

like image 884
Rich Scriven Avatar asked Oct 02 '14 19:10

Rich Scriven


1 Answers

Use a recursive function. Not elegant but it appears to work:

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"   
like image 73
jdharrison Avatar answered Oct 15 '22 15:10

jdharrison