Skip to contents

This vignette is the reference for running Julia scripts as targets steps with JuliaCall: every tar_target_jl() argument, how to choose the Julia install and project, and the common use cases. It mirrors vignette("python"): the shape of a Julia step is identical to a Python one, only the bridge and the environment arguments differ. For a gentler tour start with vignette("get_started").

Code blocks are illustrative and not executed when the vignette builds.

The two constructors

Both return a single targets target and forward every targets::tar_target_raw() argument (pattern, format, iteration, deployment, resources, cue, …).

Arguments

Scripts, data, and output

These behave exactly as for Python (see vignette("python")):

Argument Meaning
script Path to the Julia script to run (required). Runs in the Main module.
pre_script Optional R script run before the Julia script. Assign a named list to_jl to push objects into Main.
post_script Optional R script run after the Julia script. jl_get() and jl_call() are available; its last expression is the value (object mode) or file paths (file mode).
inputs Named vector mapping in-step names to upstream targets, e.g. c(df = "prepared").
output "object" (default) or "file".
retrieve Julia variable name(s) to return when there is no post-script (object mode).
files Paths to return when there is no post-script (file mode).

As with Python, any of script / pre_script / post_script may be a literal path or a tar_target_path("name") reference to track the file.

Choosing the Julia install / project

Argument Meaning
julia_version A version string (e.g. "1.11"), resolved to a juliaup-managed install. Used when julia_home is not given.
julia_home The directory containing the julia executable. Defaults to getOption("tarpolyglot.julia_home"); when unset and no julia_version, JuliaCall discovers Julia on PATH.
julia_project A Julia project environment (folder with Project.toml / Manifest.toml) to Pkg.activate(). When NULL, Julia’s default global environment (@v#.#) is used.
julia_packages Character vector of packages to using before running the script.

The three-script model

 upstream targets ─► pre_script (R) ─► script (.jl) ─► post_script (R) ─► target value
                     builds `to_jl`     computes         reads jl_get("name") /
                                        `result`         jl_call(fn, ...)
  1. script: the Julia file, run in Main.
  2. pre_script: the inputs are already bound by name. Assign a named list to_jl; each element is julia_assign()ed as a variable in Main.
  3. post_script: JuliaCall has no py-style proxy, so you read variables back through jl_get("name") (a shortcut for JuliaCall::julia_eval("name")) and call Julia functions with jl_call (an alias of JuliaCall::julia_call()).

Object output

jl/stats.jl:

# `x` was pushed from R by the pre-script.
seq = isa(x, AbstractVector) ? x : [x]
result = Dict("sum" => sum(seq), "n" => length(seq), "mean" => sum(seq) / length(seq))

R/pre_push.R:

to_jl <- list(x = x)   # `x` came from inputs = c(x = "prepared_x")

R/post_result.R:

res <- jl_get("result")
data.frame(sum = res$sum, n = res$n, mean = res$mean)   # last expression = value

_targets.R:

library(targets)
library(tarpolyglot)

list(
  tar_target(prepared_x, c(1, 2, 3, 4)),

  # (a) return a Julia variable directly with `retrieve` (no post-script)
  tar_target_jl(
    name = jl_direct,
    script = "jl/stats.jl",
    inputs = c(x = "prepared_x"),
    pre_script = "R/pre_push.R",
    retrieve = "result"
  ),

  # (b) reshape the result in a post-script
  tar_target_jl(
    name = jl_prepost,
    script = "jl/stats.jl",
    inputs = c(x = "prepared_x"),
    pre_script = "R/pre_push.R",
    post_script = "R/post_result.R"
  )
)

File output

tar_target_jl(
  name = jl_file,
  script = "jl/write.jl",            # writes a file, stores its path in `out_path`
  inputs = c(x = "prepared_x"),
  pre_script = "R/pre_push.R",
  post_script = "R/post_files.R",    # returns jl_get("out_path")
  output = "file"
)

Dynamic branching (iris example)

list(
  tar_target(iris_groups, split(iris, iris$Species), iteration = "list"),
  tar_target_jl(
    name = fit_by_group,
    script = "jl/fit.jl",
    inputs = c(df = "iris_groups"),
    pre_script = "R/pre_push_jl.R",  # to_jl <- list(df = df)
    retrieve = "result",
    pattern = map(iris_groups),      # one branch per species
    iteration = "list"
  )
)

Choosing the Julia install and project

Use case 1: Julia on PATH (default)

Set nothing; JuliaCall discovers the julia on PATH and uses the global environment.

tar_target_jl(
  name = probe,
  script = "jl/probe.jl",
  retrieve = "result"
)

Use case 2: a specific juliaup version

tar_target_jl(
  name = fit,
  script = "jl/fit.jl",
  julia_version = "1.11",            # resolved via juliaup
  retrieve = "result"
)

Use case 3: an explicit Julia home

If discovery fails (e.g. a fresh install not yet on PATH, or the Windows juliaup shim), point at the bin directory. You can set it once globally:

options(tarpolyglot.julia_home = "C:/Users/me/.julia/juliaup/.../bin")

or per step:

tar_target_jl(
  name = fit,
  script = "jl/fit.jl",
  julia_home = "C:/Users/me/.julia/juliaup/.../bin",
  retrieve = "result"
)

For reproducibility, activate a Julia project with a committed Manifest.toml, and using the packages the script needs:

tar_target_jl(
  name = solve,
  script = "jl/solve.jl",
  julia_project = "julia/MyEnv",     # folder with Project.toml + Manifest.toml
  julia_packages = c("LinearAlgebra", "Statistics"),
  retrieve = "result"
)

The requested project takes priority over an ambient JULIA_PROJECT environment variable (e.g. one inherited by crew workers): it is cleared for the duration of the Julia binding, so your explicit julia_project (or the global environment you get when none is given) wins.

One interpreter per session. JuliaCall binds a single Julia per R session, so all Julia targets that run in the same session share one project and set of loaded packages. To use different projects in one pipeline, run those targets on separate crew workers (see vignette("get_started")).

Tracking scripts as dependencies

list(
  tar_target(fit_jl, "jl/fit.jl", format = "file"),

  tar_target_jl(
    name = fit,
    script = tar_target_path("fit_jl"),   # re-runs when jl/fit.jl changes
    inputs = c(x = "data"),
    retrieve = "result"
  )
)

Conversion caveats

  • Julia is 1-indexed (unlike Python).
  • Check the JuliaCall conversion rules for which R/Julia types round-trip; for anything that does not, use file mode.

See ?tar_target_jl and ?run_jl_step for the full argument reference.