Reputation: 87
How to get from meow to purr?
Let's say I have a list with 2 elements "a" and "b". I want to copy these elements into my Global environment. If I wanted to just add these elements to the search path, I'd use assign. However, I want to create a copy. And I'd like to use purrr::map to do this. How does it work?
mylist <- list(a=1:2, b=3:4)
#nope
map(mylist, assign, x=names(.), value=.)
#no
map(mylist, assign(x=names(.), value=.))
#no
map2(mylist, names(mylist), assign(x=.y, value=.x) )
#no
map2(mylist, names(mylist), assign, x=.y, value=.x )
Upvotes: 1
Views: 1040
Reputation: 887511
Easier is list2env
from base R
applied directly on the named list
to create the objects from the names
in the global environment
list2env(mylist, .GlobalEnv)
Regarding the use of map
, it returns only the value and not the names
A slightly related to this topic would be destructuring assignment. In R
, this can be done with %<-%
operator from zeallot
library(zeallot)
c(a, b) %<-% mylist
Upvotes: 3
Reputation: 160607
Several responses to this :-)
Don't. My first visceral and emphatic response: don't do that. Very rarely do I find the use of get
/assign
justified, most commonly they are indications of inefficient (if not poor) data management. Having similar-structured things in a list
means that you can efficiently operate on them (using map
or lapply
or similar).
Base R does this very efficiently with list2env
.
ls()
# character(0)
list2env(list(a=1:2, b=3:4), envir = .GlobalEnv)
# <environment: R_GlobalEnv>
ls()
# [1] "a" "b"
If you must use purrr
, then what you need is both the name and the value, so use purrr::imap
:
ls()
# character(0)
imap(list(a=1:2, b=3:4), ~ assign(..2, ..1, envir = .GlobalEnv))
# $a
# [1] 1 2
# $b
# [1] 3 4
ls()
# [1] "a" "b"
The reason your assign
calls failed was that it was assigning it to the then-current environment, which is neither global nor something you get to use after your call to map
/map2
.
Upvotes: 6