Is it possible to move variables that reside in the global environment into a separate environment to declutter the global namespace? I understand how to create variables in a separate environment (with(env, ...)
) but is there an efficient way to move them after creation in the global environment. I suppose it would be possible to copy them into a separate environment and then remove them from the global environment, but wanted to know if there was a more efficient manner.
Asked
Active
Viewed 420 times
3

Kevin Ushey
- 20,530
- 5
- 56
- 88

kamiks
- 184
- 7
4 Answers
2
Not sure if this is a good idea but you can attach them to the search path. Starting with a fresh vanilla R session try this.
a <- 1
b <- 2
attach(as.list(.GlobalEnv), name = "myenv")
rm(a, b)
ls("myenv")
ls()
a
b

G. Grothendieck
- 254,981
- 17
- 203
- 341
2
Maybe:
library(purrr)
a <- 111
b <- 'hello'
my_envir <- new.env()
names(.GlobalEnv) %>%
walk(~ assign(.x, get(.x), envir = my_envir))
eapply(my_envir, function(x) x)
#> $my_envir
#> <environment: 0x7fed59e56dc8>
#>
#> $a
#> [1] 111
#>
#> $b
#> [1] "hello"
Or
library(purrr)
a <- 111
b <- 'hello'
my_envir <- new.env()
eapply(.GlobalEnv, function(x) x) %>%
discard(is.environment) %>%
{walk2(., names(.), ~{
assign(.y, .x, envir = my_envir)
exec('rm', .y, envir = .GlobalEnv)}
)}
eapply(my_envir, function(x) x)
#> $a
#> [1] 111
#>
#> $b
#> [1] "hello"
Created on 2021-12-31 by the reprex package (v2.0.1)

jpdugo17
- 6,816
- 2
- 11
- 23
-
2thanks, this worked exactly as expected! `lapply()` also works in place of `purrr::walk()` with some slight modifications. – kamiks Dec 31 '21 at 22:56
2
Using rlang
library(rlang)
a <- 111
b <- "hello"
my_envir <- env(!!! as.list(.GlobalEnv))
-checking
> ls(my_envir)
[1] "a" "b"
> my_envir$a
[1] 111

akrun
- 874,273
- 37
- 540
- 662
1
You may use multiple lines in the with
.
e1 <- new.env()
e2 <- new.env()
with(e1, {
k <- l <- m <- 0L
x <- 1
fo <- y ~ x
fun <- function(x) x^2
})
The objects are created in e1
,
ls(e1)
# [1] "fo" "fun" "k" "l" "m" "x"
e2
stays empty,
ls(e2)
# character(0)
and in .GlobalEnv
only the environments exist so far.
ls(.GlobalEnv)
# [1] "e1" "e2"
To work with objects, also use with
or $
.
with(e1, fun(2))
# [1] 4
e1$fun(2)
# [1] 4

jay.sf
- 60,139
- 8
- 53
- 110
-
`with()` doesn't always work as expected. As an example, I created a new environment and set up a multi-line `with(env, {})` block in order to source multiple interrelated scripts into (some of which had their own environments); however, some of the sourced scripts still returned variables into the global environment despite being clearly within the {} block. – kamiks Dec 31 '21 at 21:47
-
@kamiks Instead of narrating, you could give a (not) working example and possibly the solution you found in an answer. – jay.sf Dec 31 '21 at 21:53
-
My intention isn't to be ambiguous, it's that my use case is too long to fit into a comment block: I literally had an R project, where one script sourced a bunch of other scripts and I tried to place all of the `source()` calls within a `with(env,{})` block only to find certain sourced variables appearing in the global environment instead of the specified environment. I have yet to find the reason or solution for why this is occurring. – kamiks Dec 31 '21 at 22:23