Home > Blockchain >  Using R, how to dput a list with an environment?
Using R, how to dput a list with an environment?

Time:10-01

I am working on a function to basically grab arguments from inside a function. It works as expected, but when I try and transport the result, I have an envir in the list. It outputs fine via dput, but I CANNOT transport it.

> test(iris)
list(envir = <environment>, call = test(iris), fn.info = list(
    fn = "test", dot.keys = NULL, dot.vals = NULL, params = list(
        df = "iris"), map = list(df = "iris"), formals = list(
        df = "--EMPTY--")))

As you can see, the INTERNALS grab the fn function name, and function parameters. One element captured is the envir which is simple to reproduce as follows:

dput( (envir = environment()) );

The list at least TRAPPED the environment, but when I try and paste it back into a session, I get an error:

> x = list(envir = <environment>, call = test(iris), fn.info = list(
Error: unexpected '<' in "x = list(envir = <"
>     fn = "test", dot.keys = NULL, dot.vals = NULL, params = list(
Error: unexpected ',' in "    fn = "test","
>         df = "iris"), map = list(df = "iris"), formals = list(
Error: unexpected ')' in "        df = "iris")"
>         df = "--EMPTY--")))
Error: unexpected ')' in "        df = "--EMPTY--")"


Ideally, I would like to pair of functions that would cast it to/from envir as a string, so I can transport it.

Question: How to transport an environment via dput?

env.toString(envir) {}

env.fromString(envir) {}

The above represents my current roadmap, but I am open to suggestions. I have tried as.character , as.raw, as.hexmode... I believe deparse internally will work, but that will not enable me to recover the environment as an object without the propose env.fromString

CodePudding user response:

Perhaps you could use ls() to get the names of all objects in the environment, and then put their names and values in a list, then reconstruct an environment from that list with list2env()... Something like:

x <- new.env()
x$foo <- 1:3

xnames <- ls(envir = x)
xlist <- lapply(xnames, function(y) {
  z <- x[[y]]
  if (!inherits(z, 'environment'))
    return(z)
})
names(xlist) <- xnames

dput(list(my_env = xlist))
#> list(my_env = list(foo = 1:3))

a_list <- list(my_env = list(foo = 1:3))

x2 <- list2env(a_list$my_env)
print(x2$foo)
#> [1] 1 2 3

CodePudding user response:

If you just need to remove the items from a list that are an environment you can just iterate over the list remove the elements that inherit from 'environment'

x <- list(a = new.env(), b = "foo")
dput(x[-sapply(x, inherits, 'environment')])
#> list(b = "foo")
  • Related