Use job::job()
to run chunks of R code in an RStudio job instead of the console. This frees your console while the job(s) go brrrrr in the background. By default, the result is returned to the global environment when the job completes.
Install from CRAN (stable) or GitHub (development):
install.packages("job")
remotes::install_github("lindeloev/job")
Two RStudio Addins are installed with job
. Simply select some code code in your editor and click one of the Addins to run it as a job. The results are returned to the global environment once the job completes.
job::job()
. It imports everything from your environment, so it feels like home. It returns all new or changed variables job.job::empty()
. It imports nothing from your environment, so the code can run in clean isolation. All variables are returned.Write your script as usual. Then wrap parts of it using job::job({<your code>})
to run that chunk as a job:
When the job completes, it silently saves foo
and bar
to your global environment.
brms
is great, but you often restrict yourself to fit as few models as possible fewer models because compilation and sampling takes time. Let’s run it as a job!
# Do light processing in the main session
library(brms)
data = mtcars[mtcars$hp > 100, ]
model1 = mpg ~ hp * wt
model2 = mpg ~ hp + wt
# Send long-running code to job(s).
job::job({
fit1 = brm(model1, data)
})
job::job({
fit2 = brm(model2, data)
})
# Continue working in your console
cat("I'm free now! Thank you.
Yours truly, Console.")
Now you can follow the progress in the jobs pane and your console is free in the meantime.
Extending the brms
-example above, let’s fine-control the first job a bit more:
# Name the code block to return as environment
job::job(brm_result = {
# Job-specific settings
options(mc.cores = 3)
# Compute stuff
fit = brm(model1, data)
fit = add_criterion(fit, "loo")
the_test = hypothesis(fit, "hp > 0")
# Print stuff inside the job
print(summary(fit))
# Control what is returned to the main session
job::export(c(fit, the_test))
}, import = c(data, model1)) # Control what is imported into the job
Because we named the code block brm_result
, it will return the contents as an environment()
called brm_result
(or whatever you called it).brm_result
behaves much like a list()
:
Often, the results of the long-running chunks are the most interesting. But they easily get buried among the other outputs in the console and are eventually lost due to the line limit. RStudio’s jobs history can be used as a nice overview. Make sure to print informative results within the job and give your jobs an appropriate title
, e.g., (job::job({<code here>}, title = "Unit test: first attempt at feature X")
.
See the documentation how you can fine-control the job environment and what results are returned. The job::job() website has worked examples, where finer control is beneficial, including:
job::export()
function.job::job()
to test code chunks in an isolated environment.job::job()
to render large plots.The primary use case for job::job()
are heavy statistical and numerical functions, including MCMC sampling, cross-validation, etc.
But sometimes our flow is disturbed by semi-slow routine tasks too. Try running devtools::test()
, knitr::knit()
, pkgdown::build_site()
, or upgrade.packages()
as a job and see whether that’s an improvement. Here’s a list of semi-slow functions that I regularly run as jobs.
job::job()
is aimed at easing interactive development within RStudio. For tasks that don’t benefit from running in the Jobs pane of RStudio, check out:
The future
package’s %<-%
operator combined with plan(multisession)
.
The callr
package is a general tool to run code in new R sessions.