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:
::install_github("lindeloev/job") remotes
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:
::job({
job= 10
foo = rnorm(5)
bar })
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)
= mtcars[mtcars$hp > 100, ]
data = mpg ~ hp * wt
model1 = mpg ~ hp + wt
model2
# Send long-running code to job(s).
::job({
job= brm(model1, data)
fit1
})::job({
job= brm(model2, data)
fit2
})
# Continue working in your console
cat("I'm free now! Thank you.
Sincerely, 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(brm_result = {
job# Job-specific settings
options(mc.cores = 3)
# Compute stuff
= brm(model1, data)
fit = add_criterion(fit, "loo")
fit = hypothesis(fit, "hp > 0")
the_test
# Print stuff inside the job
print(summary(fit))
# Control what is returned to the main session
::export(c(fit, the_test))
jobimport = 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.