2
votes

Is there any way to return all objects defined in a function in R?

Here's a little example of what I'm trying to do. I want to return everything I've assigned a value to inside this function (dave, mark, xx, z (if exists)). The print statement is superfluous.

I normally wouldn't even try to do this, it's just I'm converting a sourced file into a function, and previously all objects were sourced into the global environment, which is what I still need, and I'd rather not create an enormous list of all the objects at the end of the function. Ideally, after running the function, all the objects are in the global environment and can be accessed from the list. (Automatically delisting and leaving them as standalone objects would be great.) Perhaps this should be a class?

It errors out if any of these are NULL, if for example, y is supplied as NULL in the function definition arguments (i.e. test_func <- function(x = c(1, 2), y = NULL) ...).

test_func <- function(x = c(1, 2), y = 3) {
  xx <- x * x
  if(!is.null(y)) z <- x * y
  mark <- "hello"
  dave <- data.frame(x = x, xx = xx)
  whatshere <- ls()
  print(whatshere)
  whatsout <- list()
  for (i in 1:length(whatshere)) {
    whatsout[[i]] <- get(whatshere[[i]])
  }
  names(whatsout) <- whatshere
  return(whatsout)
}
test_func()
#> [1] "dave" "mark" "x"    "xx"   "y"    "z"
#> $dave
#>   x xx
#> 1 1  1
#> 2 2  4
#> 
#> $mark
#> [1] "hello"
#> 
#> $x
#> [1] 1 2
#> 
#> $xx
#> [1] 1 4
#> 
#> $y
#> [1] 3
#> 
#> $z
#> [1] 3 6

Created on 2020-03-03 by the reprex package (v0.3.0)

1
For anyone coming to this question, Konrad's answer works perfectly, and I'm using this to unlist everything into the global environment: x <- test_func(); for (i in 1:length(x)) { assign(names(x[i]), x[[i]]) }; rm(x)RobertMyles

1 Answers

4
votes

Is there any way to return all objects defined in a function in R?

Literally, there is1:

as.list(environment())

However, I’d generally recommend against this: be explicit, name all objects that you want to return individually:

list(
    foo = foo,
    bar = bar,
    …
)

1 This will include arguments, since these are just locally defined values. To exclude formal arguments, do this:

values = as.list(environment())
values[setdiff(names(values), names(formals()))]