关于使用sapply批量运行R脚本的对象作用域疑问
Great question—this is a super common pitfall when batch sourcing scripts in R, so let’s break this down clearly:
How Your Current Code Works
When you run sapply(list.files('scripts/', full.names=TRUE), source), here’s what’s happening under the hood:
list.files()grabs all the script paths in yourscripts/folder.sapply()iterates over each path and callssource()on it.- By default,
source()executes the script’s code in the environment where it’s called—in your case, that’s the global environment (the workspace you see in RStudio’s Environment pane).
The Critical Risk: No Isolation Between Scripts
To answer your direct questions:
- No, scripts do not only use their own created objects.
- Yes, there’s a huge risk that a later script will accidentally use leftover objects from earlier scripts.
- The process does not isolate script environments by default.
If two scripts create an object with the same name (like temp_df or model_results), the second script will overwrite the first one’s object. Worse, if a script references a name it doesn’t define itself, it will pull whatever exists in the global environment—including leftover objects from previously run scripts. This can lead to silent errors or incorrect results that are hard to debug.
How to Fix This: Isolate Each Script’s Environment
You have a few solid options to avoid object collisions:
1. Run Each Script in a Fresh, Isolated Environment
Modify your sapply() call to run each script in a new, separate environment using the local argument of source():
sapply(list.files('scripts/', full.names=TRUE), function(script_path) { # Create a new empty environment for each script isolated_env <- new.env() # Source the script into this environment source(script_path, local = isolated_env) })
This ensures every script runs in its own sandbox—no objects leak between scripts, and nothing pollutes your global workspace.
2. Extract Results (If You Need Them)
If your scripts produce output you want to keep, you can pull specific objects from the isolated environment after sourcing:
# Store results in a named list (names match script filenames) population_results <- sapply(list.files('scripts/', full.names=TRUE), function(script_path) { isolated_env <- new.env() source(script_path, local = isolated_env) # Assume each script creates an object named `final_result` isolated_env$final_result }, simplify = FALSE)
Now you have all your results in a structured list, with no cross-contamination between scripts.
3. Clear the Global Environment Between Runs (Less Safe)
You could add rm(list = ls(all.names = TRUE)) at the start of each script, but this is risky—it will delete all objects in the global environment, including any you might have needed outside these scripts. Only use this if you’re 100% sure your scripts don’t depend on external objects.
Key Takeaway
Always isolate batch-sourced scripts unless you explicitly want them to share objects. Using local = new.env() is the cleanest, safest way to prevent unexpected object collisions and ensure each script runs with its own set of variables.
内容的提问来源于stack exchange,提问作者shasha

