Repository navigation
[Query] Dependencies
Generated from 'wiki-query.ts' on 2026-11-08, 09:20:49 UTC (v2.17.4), do not edit directly.
Dependencies Query [overview]
Returns all direct dependencies (in- and outputs) of a given R script
This query is requested with the type dependencies.
Run in the REPL: :query @dependencies (<crit>;...) <code | file://path>
This query extracts all dependencies from an R script, using a combination of a Call-Context Query and more advanced tracking in the Dataflow Graph. Loaded libraries are resolved against the signature database.
The query reports one list of entries per category, each entry a call and the value it reads or writes, like the
file of a read.csv:
| Category | Functions known | For example | Value where none is named |
|---|---|---|---|
| Inputs | |||
library (Libraries) |
22 |
library, require, loadNamespace, requireNamespace
|
unknown |
remote (Remote Installs) |
10 |
install_github, install_gitlab, install_bitbucket, install_git
|
unknown |
source (Sourced Files) |
4 |
source, sys.source, source_url, source_gist
|
unknown |
read (Read Data) |
236 |
dbConnect, dbConnect, dbConnect, dbConnect
|
unknown |
| Outputs | |||
write (Outputs) |
213 |
dump, open, seek, open.connection
|
stdout |
visualize (Visualizations) |
579 |
ggplot, ggplotly, ggMarginal, ggcorrplot
|
|
| What the script does with data | |||
transform (Data Transformations) |
140 |
subset, transform, filter, filter_out
|
|
statistics (Statistics) |
74 |
lm, glm, nls, lmer
|
|
test (Tests) |
14 |
test_that, describe, it, test_file
|
What the value of an entry tells, and the fields that say more:
| Entry | How to tell | Meaning |
|---|---|---|
| a file, package, or URL |
value names it |
the call reads or writes it, like "data.csv"
|
| inline data |
value is constant
|
The value resolved, but to data given inline rather than to a path (matrix(0, 2, 2), data.frame(a = 1)). |
| an unknown resource |
value is unknown
|
The value could not be resolved, e.g. a path assembled at runtime. Such a dependency may be missing or fetchable. |
| console output |
value is stdout or stderr
|
print and cat write to stdout, message and warning to stderr
|
| auto-printed output |
implicit is set |
the output is not written by a call asking for it: R echoes the top-level statement on its own |
| through a call of the program |
via is set |
Set on a call of a function of the program that does what this entry reports, transitively: the call of report() writes what the cat() in its body writes. It names the entry within the called function. The value is the one of this call, save("a.csv") writes a.csv even if other calls of save name other files. |
| part of another output | its id is in another entry's parts
|
The other statements that build this output: for a plot, the addons drawn onto it and, when it lands in a file, the device opener and closer around it. Answers which statements produce this output without rebuilding it from linkedIds . A part is reported as an entry of its own as well, so to count plots rather than graphics calls, count the entries no other entry lists in its parts. |
For a script reading library(x), the following query returns the loaded library:
[ { "type": "dependencies" } ](This can be shortened to @dependencies when used with the REPL command :query).
Results (prettified and summarized):
Query: dependencies (3 ms)
Libraries (1)
x via library (node 3)
Show Detailed Results as Json
The analysis ran (including parsing and normalization and the query) within the generation environment.
The JSON contains the ids of the nodes in question (see the Interface wiki page).
{"dependencies":{".meta":{},"library":[{"nodeId":3,"functionName":"library","value":"x"}],"remote":[],"source":[],"read":[],"write":[],"visualize":[],"transform":[],"test":[],"statistics":[]},".meta":{}}The query also handles more complicated scripts and offers information on the loaded libraries, sourced files, data which is read and data which is written. For example, consider the following script:
source("sample.R")
foo <- loadNamespace("bar")
data <- read.csv("data.csv")
#' @importFrom ggplot2 ggplot geom_point aes
ggplot(data, aes(x=x, y=y)) + geom_point()
better::write.csv(data, "data2.csv")
print("hello world!")The following query returns the dependencies of the script.
[ { "type": "dependencies" } ](This can be shortened to @dependencies when used with the REPL command :query).
Show Results
Results (prettified and summarized):
Query: dependencies (8 ms)
Libraries (2)
bar via loadNamespace (node 8)
better via :: (node 32)
Sourced Files (1)
sample.R via source (node 3)
Read Data (1)
data.csv via read.csv (node 14)
Outputs (1)
stdout via print (node 41)
Visualizations (2)
via ggplot (node 28)
via geom_point (node 30, linked 28)
Show Detailed Results as Json
The analysis ran (including parsing and normalization and the query) within the generation environment.
The JSON contains the ids of the nodes in question (see the Interface wiki page).
{"dependencies":{".meta":{},"library":[{"nodeId":8,"functionName":"loadNamespace","value":"bar"},{"nodeId":32,"functionName":"::","value":"better"}],"remote":[],"source":[{"nodeId":3,"functionName":"source","value":"sample.R"}],"read":[{"nodeId":14,"functionName":"read.csv","assignedTo":"data","value":"data.csv"}],"write":[{"nodeId":41,"functionName":"print","value":"stdout"}],"visualize":[{"nodeId":28,"functionName":"ggplot","inputVariables":["data","x","y"],"parts":[30]},{"nodeId":30,"functionName":"geom_point","linkedIds":[28],"inputVariables":["data","x","y"]}],"transform":[],"test":[],"statistics":[]},".meta":{}}Currently, the dependency extraction may fail as it is essentially a set of heuristics guessing the dependencies. We welcome any feedback on this (consider opening a new issue).
In the meantime we offer several properties to overwrite the default behavior (e.g., function names that should be collected)
[ { "type": "dependencies", "ignoreDefaultFunctions": true, "enabledCategories": [ "library" ], "libraryFunctions": [ { "package": "base", "name": "print", "argIdx": 0, "argName": "library", "resolveValue": true } ] } ]Show Results
Results (prettified and summarized):
Query: dependencies (1 ms)
Libraries (1)
hello world! via print (node 41)
Show Detailed Results as Json
The analysis ran (including parsing and normalization and the query) within the generation environment.
The JSON contains the ids of the nodes in question (see the Interface wiki page).
{"dependencies":{".meta":{},"library":[{"nodeId":41,"functionName":"print","value":"hello world!"}],"remote":[],"source":[],"read":[],"write":[],"visualize":[],"transform":[],"test":[],"statistics":[]},".meta":{}}Here, resolveValue tells the dependency query to resolve the value of this argument in case it is not a constant.
By default the query reports only the dependencies the code names itself. Yet R attaches a handful of base packages
to the search path on startup, so a bare sd(x) genuinely depends on stats without any library call saying so.
Set assumedPackages to have those reported as well, as library entries marked implicit and carrying no
nodeId (no single call stands for "R attached this"), with the calls that pulled the package in listed as
linkedIds:
[ { "type": "dependencies", "assumedPackages": true, "enabledCategories": [ "library" ] } ]Results (prettified and summarized):
Query: dependencies (1 ms)
Libraries (2)
base always attached by R, used at 8
stats attached by R at startup, used at 10
Show Detailed Results as Json
The analysis ran (including parsing and normalization and the query) within the generation environment.
The JSON contains the ids of the nodes in question (see the Interface wiki page).
{"dependencies":{".meta":{},"library":[{"functionName":"<attached>","value":"base","implicit":true,"alwaysAttached":true,"linkedIds":[8]},{"functionName":"<attached>","value":"stats","implicit":true,"linkedIds":[10]}],"remote":[],"source":[],"read":[],"write":[],"visualize":[],"transform":[],"test":[],"statistics":[]},".meta":{}}Original Code
sd(c(1, 2, 3))base is reported alongside the others but additionally marked alwaysAttached. The other six are attached by
convention and R_DEFAULT_PACKAGES (or options(defaultPackages=)) can drop any of them, whereas base is always
there and cannot be detached -- so it is never something the script could have asked for, and never something to
suggest a library call for.
To see what takes part in a dependency, ask the query to focus on it: .meta.focus then lists every node the
dependency depends on and every node that depends on it, so a client can gray out the rest. In the REPL, the
criteria go in parentheses, as with :query @dependencies (3@read.csv), which prints the lines taking part:
[ { "type": "dependencies", "focus": [ "3@read.csv" ], "enabledCategories": [ "read" ] } ]Show Results
Results (prettified and summarized):
Query: dependencies (3 ms)
Read Data (1)
a.csv via read.csv (node 10)
focus the lines taking part: 1, 3, 5
Show Detailed Results as Json
The analysis ran (including parsing and normalization and the query) within the generation environment.
The JSON contains the ids of the nodes in question (see the Interface wiki page).
{"dependencies":{".meta":{"focus":[10,8,0,2,1,11,6,18,20]},"library":[],"remote":[],"source":[],"read":[{"nodeId":10,"functionName":"read.csv","assignedTo":"d","value":"a.csv"}],"write":[],"visualize":[],"transform":[],"test":[],"statistics":[]},".meta":{}}Original Code
f <- "a.csv"
g <- 2
d <- read.csv(f)
h <- g + 1
print(d)Beyond libraries, files and outputs, the query knows the visualize category (plots) and the transform category
(Data Transformations): the calls that reshape, filter, join or aggregate data, like dplyr::filter, tidyr::pivot_longer,
merge, aggregate or data.table::setDT. The category is read from the built-in configuration: every built-in labeled
SemanticCallTag.Transforms belongs to it. Every such built-in names its package, so filter is only a transformation when it
resolves to dplyr and never for the time-series stats::filter.
The read, write, visualize, and transform entries additionally state how data flows through the call,
resolved with the dataflow graph instead of the syntax:
-
inputVariables(forwrite,visualize, andtransform) are the variables the result is computed from, through every call in between. What an argument's role in the signature excludes (a file, a flag, a callee) is no input, nor is what a call quotes or looks up in a data mask:dffordf |> filter(x > 1), bothaandbforleft_join(a, b). An addon to a plot draws its data. -
assignedTo(forread,visualize, andtransform) is the variable the result is stored in, following every call that hands it on (a pipe into a call, parentheses, a+adding to a plot) up to<-,=or->:smallforsmall <- filter(df, x > 1), and nothing forf(filter(df, x > 1)). - Every plot additionally carries its
title(fromggtitle,labs(title = )ormain =) and the file it is written to assavedTo(byggsave, which names itsplotor saveslast_plot(), or by the graphics device open when it is drawn).
[ { "type": "dependencies", "enabledCategories": [ "transform", "visualize" ] } ]Results (prettified and summarized):
Query: dependencies (3 ms)
Visualizations (3)
via ggplot (node 38)
via geom_point (node 40, linked 38)
via ggtitle (node 45, linked 38)
Data Transformations (2)
via filter (node 16)
via select (node 24)
Show Detailed Results as Json
The analysis ran (including parsing and normalization and the query) within the generation environment.
The JSON contains the ids of the nodes in question (see the Interface wiki page).
{"dependencies":{".meta":{},"library":[],"remote":[],"source":[],"read":[],"write":[],"visualize":[{"nodeId":38,"functionName":["ggplot","ggplot2",false],"inputVariables":["small"],"assignedTo":"p","parts":[40,45],"title":"Small"},{"nodeId":40,"functionName":["geom_point","ggplot2",false],"linkedIds":[38],"assignedTo":"p","inputVariables":["small"]},{"nodeId":45,"functionName":["ggtitle","ggplot2",false],"linkedIds":[38],"assignedTo":"p","inputVariables":["small"]}],"transform":[{"nodeId":16,"functionName":["filter","dplyr",false],"inputVariables":["measurements"]},{"nodeId":24,"functionName":["select","dplyr",false],"inputVariables":["measurements"],"assignedTo":"small"}],"test":[],"statistics":[]},".meta":{}}Original Code
library(dplyr)
library(ggplot2)
small <- measurements |> filter(x > 1) |> select(x, y)
p <- ggplot(small, aes(x, y)) + geom_point() + ggtitle("Small")
ggsave("small.png", plot = p)Implementation Details
The Dependencies Query is executed by executeDependenciesQuery.
Currently maintained by Florian Sihler and Oliver Gerstl at Ulm University
Email | GitHub | Penguins | Portfolio
- 🧑💻 Developer Onboarding
- 💻 Setup
- 👓 Overview
- 🪟 Interfacing with flowR
- 🌋 Core
- 🧹 Testing & Linting (Benchmark Page)
⁉️ FAQ- ℹ️ Extra Information