R编程教学:如何从子进程将R对象传入父进程并实现脚本隔离
Great question—using separate environments works for simple variable isolation, but it doesn't prevent global state changes (like loading libraries) from leaking into your main session. The cleanest solution here is to run each script in a fully independent child R process, which keeps their environments completely separate from both your parent session and each other.
The easiest way to do this in R is with the callr package—it's built specifically for running R code in child processes and seamlessly passing objects back to the parent.
Step 1: Install & Load callr
First, make sure you have the package installed:
install.packages("callr") library(callr)
Step 2: Run Scripts in Isolated Child Processes
You can run code directly as a string, or execute external .R files. Both approaches keep the child process completely isolated.
Example 1: Running Inline Code
Let's replicate your original example but with full isolation. Even though both scripts load a library, the parent session won't be affected:
# Define student code (includes a library call that won't pollute the parent) student_code <- " library(dplyr) x <- 4 y <- x * 2 # Return objects we want to compare as a list list(student_x = x, student_y = y) " # Run in a child process and capture results student_output <- r(function() { eval(parse(text = student_code)) }) # Define solution code solution_code <- " library(dplyr) x <- 5 y <- x * 3 list(solution_x = x, solution_y = y) " # Run in another isolated child process solution_output <- r(function() { eval(parse(text = solution_code)) }) # Compare results from the parent session student_output$student_x == solution_output$solution_x # FALSE student_output$student_y == solution_output$solution_y # FALSE
Example 2: Running External Script Files
If your student/solution code is in separate .R files, use r_script() instead. For example, if you have student_script.R:
# student_script.R library(ggplot2) # Create some objects filtered_data <- mtcars %>% filter(cyl == 4) car_plot <- ggplot(filtered_data, aes(mpg, wt)) + geom_point() # Return objects as a list to pass back list(data = filtered_data, plot = car_plot)
Then in your parent session:
student_output <- r_script("student_script.R") # Access the objects just like any other R object student_output$plot # Will display the ggplot
Why This Works
Each call to r() or r_script() spins up a brand-new R session in a child process. This means:
- Any libraries loaded in the child process don't affect the parent session
- Global variables, options, or other state changes stay confined to the child
- Multiple child processes don't interfere with each other
Alternative: Lower-Level processx (If You Need More Control)
If you want fine-grained control over the child process (like setting environment variables or capturing stdout/stderr), you can use processx (the package callr is built on). However, you'll need to handle object serialization manually:
- In the child script, save objects to an
.rdsfile:
# child_script.R x <- 5 saveRDS(x, "child_output.rds")
- In the parent session, run the child process and load the
.rds:
library(processx) run_rscript("child_script.R") x_from_child <- readRDS("child_output.rds")
This is more work than callr, but useful for advanced use cases.
内容的提问来源于stack exchange,提问作者filipsch

