-2

I am trying to determine all the objects in a script. ( specifically to get all the dataframes but I'll settle for all the assigned objects ie vectors lists etc.) Is there a way of doing this. Should I make the script run in its own session and then somehow get the objects from that session rather than rely on the global environment.

Sebastian Zeki
  • 6,690
  • 11
  • 60
  • 125

2 Answers2

1

Use the second argument to source() when you execute the script. For example, here's a script:

x <- y + 1
z <- 2

which I can put in script.R. Then I will execute it in its own environment using the following code:

x <- 1   # This value will *not* change
y <- 2   # This value will be visible to the script
env <- new.env()
source("script.R", local = env)

Now I can print the values, and see that the comments are correct

x        # the original one
# [1] 1
ls(env)  # what was created?
# [1] "x" "z"
env$x    # this is the one from the script
# [1] 3
user2554330
  • 37,248
  • 4
  • 43
  • 90
1

I had a similar question and found an answer. I am copying the answer from my other post here.

I wrote the following function, get.objects(), that returns all the objects created in a script:

get.objects <- function(path2file = NULL, exception = NULL, source = FALSE, message = TRUE) {
  library("utils")
  library("tools")

  # Step 0-1: Possibility to leave path2file = NULL if using RStudio.
  # We are using rstudioapi to get the path to the current file
  if(is.null(path2file)) path2file <- rstudioapi::getSourceEditorContext()$path

  # Check that file exists
  if (!file.exists(path2file)) {
    stop("couldn't find file ", path2file)
  }

  # Step 0-2: If .Rmd file, need to extract the code in R chunks first
  # Use code in https://felixfan.github.io/extract-r-code/
  if(file_ext(path2file)=="Rmd") {
    require("knitr")
    tmp <- purl(path2file)
    path2file <- paste(getwd(),tmp,sep="/")
    source = TRUE # Must be changed to TRUE here
  }

  # Step 0-3: Start by running the script if you are calling an external script.
  if(source) source(path2file)

  # Step 1: screen the script
  summ_script <- getParseData(parse(path2file, keep.source = TRUE))

  # Step 2: extract the objects
  list_objects <- summ_script$text[which(summ_script$token == "SYMBOL")]
  # List unique
  list_objects <- unique(list_objects)

  # Step 3: find where the objects are.
  src <- paste(as.vector(sapply(list_objects, find)))
  src <- tapply(list_objects, factor(src), c)

  # List of the objects in the Global Environment
  # They can be in both the Global Environment and some packages.
  src_names <- names(src)

  list_objects = NULL
  for (i in grep("GlobalEnv", src_names)) {
    list_objects <- c(list_objects, src[[i]])
  }

  # Step 3bis: if any exception, remove from the list
  if(!is.null(exception)) {
    list_objects <- list_objects[!list_objects %in% exception]
  }

  # Step 4: done!
  # If message, print message:
  if(message) {
    cat(paste0("  ",length(list_objects)," objects  were created in the script \n  ", path2file,"\n"))
  }

  return(list_objects)
}

To run it, you need a saved script. Here is an example of a script:

# This must be saved as a script, e.g, "test.R".
# Create a bunch of objects
temp <- LETTERS[1:3]
data <- data.frame(x = 1:10, y = 10:1)
p1 <- ggplot(data, aes(x, y)) + geom_point()

# List the objects. If you want to list all the objects except some, you can use the argument exception. Here, I listed as exception "p1.
get.objects()
get.objects(exception = "p1", message = FALSE)

Note that the function also works for external script and R markdown. If you run an external script, you will have to run the script before. To do so, change the argument source to TRUE.

Rosalie Bruel
  • 1,423
  • 1
  • 10
  • 22