<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>scip-r | M(R)amos</title><link>https://link-ny.github.io/tag/scip-r/</link><atom:link href="https://link-ny.github.io/tag/scip-r/index.xml" rel="self" type="application/rss+xml"/><description>scip-r</description><generator>Hugo Blox Builder (https://hugoblox.com)</generator><language>en-us</language><lastBuildDate>Thu, 12 Nov 2026 00:00:00 +0000</lastBuildDate><image><url>https://link-ny.github.io/media/icon_hu44c5cd0718181b6f9c2753bad0214726_14512_512x512_fill_lanczos_center_3.png</url><title>scip-r</title><link>https://link-ny.github.io/tag/scip-r/</link></image><item><title>Mirroring Bioconductor and building a DuckDB code index for AI models</title><link>https://link-ny.github.io/post/bioc-mirror-duckdb-index/</link><pubDate>Thu, 12 Nov 2026 00:00:00 +0000</pubDate><guid>https://link-ny.github.io/post/bioc-mirror-duckdb-index/</guid><description>&lt;p>The setup described here ran on a virtual machine on
&lt;a href="https://jetstream-cloud.org/" target="_blank" rel="noopener">Jetstream2&lt;/a>, referred to below as &amp;ldquo;this
instance&amp;rdquo;. Nothing in it depends on Jetstream2: any cloud instance or local
machine with enough disk space will do.&lt;/p>
&lt;p>This instance does two things. It keeps a local copy of Bioconductor&amp;rsquo;s source
packages for release 3.23 and devel 3.24. It also runs
&lt;a href="https://github.com/seandavi/scip-r" target="_blank" rel="noopener">scip-r&lt;/a>, written by Sean Davis, over every
package, which produces an index of symbols, references and call relationships,
and packages that index as a DuckDB database that an AI model can query.&lt;/p>
&lt;p>This post walks through how the mirror and index were set up, and how
&lt;code>bioc-index.sh&lt;/code> turns the index into a database.&lt;sup id="fnref:1">&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref">1&lt;/a>&lt;/sup> The mirror steps follow the
&lt;a href="https://seandavi.github.io/bioc-infrastructure/mirror-how-to.html" target="_blank" rel="noopener">mirror
how-to&lt;/a>.
The scripts used here can be downloaded from the
&lt;a href="https://gist.github.com/LiNk-NY/bc994fbd18f2f099157319995c36c9c5" target="_blank" rel="noopener">gist&lt;/a>.&lt;/p>
&lt;h2 id="where-things-stand">Where things stand&lt;/h2>
&lt;p>As of 12 November 2026:&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Source mirror&lt;/strong>: &lt;code>packages/3.23/bioc/src/contrib&lt;/code> (8.2 GB) and
&lt;code>packages/3.24/bioc/src/contrib&lt;/code> (6.9 GB), under
&lt;code>~/bioconductor_repositories&lt;/code>.&lt;/li>
&lt;li>&lt;strong>Index&lt;/strong>: &lt;code>out/&lt;/code> in each version directory, with a &lt;code>parquet/&lt;/code> tree and a
&lt;code>bioc323.duckdb&lt;/code> or &lt;code>bioc324.duckdb&lt;/code> view database.&lt;/li>
&lt;li>&lt;strong>Bundle&lt;/strong>: &lt;code>bioc324-index-20261104.tar.gz&lt;/code> (118.6 MB) with a &lt;code>.sha256&lt;/code> file,
built on 4 November 2026 from 3.24.&lt;/li>
&lt;/ul>
&lt;h2 id="step-1-read-the-manifest">Step 1: read the manifest&lt;/h2>
&lt;p>Each version and repository has a manifest listing every object, with its size
and MD5. Filter the &lt;code>bioc&lt;/code> repository&amp;rsquo;s manifest down to the source tarballs and
index files:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-sh" data-lang="sh">&lt;span class="line">&lt;span class="cl">&lt;span class="nb">cd&lt;/span> ~/bioconductor_repositories
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">curl -fsS https://bioconductor.org/api/v1/manifest/3.24/bioc.tsv.gz &lt;span class="se">\
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="se">&lt;/span> &lt;span class="p">|&lt;/span> gunzip &lt;span class="p">|&lt;/span> cut -f1 &lt;span class="p">|&lt;/span> grep &lt;span class="s1">&amp;#39;/src/contrib/&amp;#39;&lt;/span> &amp;gt; files-3-24.txt
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>The same command with &lt;code>3.23&lt;/code> gives &lt;code>files-3-23.txt&lt;/code>. The 3.23 list has 2,763
paths and the 3.24 list has 2,456.&lt;/p>
&lt;h2 id="step-2-copy-with-rclone">Step 2: copy with rclone&lt;/h2>
&lt;p>Copy the listed files with &lt;code>rclone&lt;/code>:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-sh" data-lang="sh">&lt;span class="line">&lt;span class="cl">rclone copy --http-url https://bioconductor.org :http: &lt;span class="se">\
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="se">&lt;/span> ~/bioconductor_repositories --files-from files-3-24.txt --no-traverse
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>The how-to&amp;rsquo;s &lt;code>mirror-sync.sh&lt;/code> runs this copy and then recreates the symlinks.
This instance ran the copy by hand.&lt;/p>
&lt;p>Paths in &lt;code>--files-from&lt;/code> are relative to the destination, so each file lands
under &lt;code>packages/&amp;lt;version&amp;gt;/bioc/src/contrib/&lt;/code>. Every path in both lists is
present on disk.&lt;/p>
&lt;p>The list counts are higher than the tarball counts (2,763 against 2,758, and
2,456 against 2,451) because each list also includes non-tarball files. For 3.24
those are &lt;code>PACKAGES&lt;/code>, &lt;code>PACKAGES.gz&lt;/code>, &lt;code>PACKAGES.rds&lt;/code> and two &lt;code>Meta/*.rds&lt;/code> files.&lt;/p>
&lt;h2 id="what-this-copy-leaves-out">What this copy leaves out&lt;/h2>
&lt;ul>
&lt;li>&lt;strong>Scope is source only.&lt;/strong> The mirror has the &lt;code>bioc&lt;/code> repository&amp;rsquo;s &lt;code>src/contrib&lt;/code>
and nothing else: no &lt;code>bin/&lt;/code>, no &lt;code>data-annotation&lt;/code>, &lt;code>data-experiment&lt;/code>,
&lt;code>workflows&lt;/code> or &lt;code>books&lt;/code>. The how-to leaves that choice to you, and this
instance picked source only.&lt;/li>
&lt;li>&lt;strong>No &lt;code>release&lt;/code> or &lt;code>devel&lt;/code> symlinks.&lt;/strong> &lt;code>packages/&lt;/code> contains only &lt;code>3.23&lt;/code> and
&lt;code>3.24&lt;/code>. The how-to says URLs that go through those links return 404 without
them. &lt;code>mirror-sync.sh&lt;/code> recreates them; this copy did not.&lt;/li>
&lt;li>&lt;strong>The copy is a snapshot.&lt;/strong> It dates from 4 November 2026. The manifest is
regenerated hourly, and this user has no cron job, so nothing refreshes it.
The how-to suggests a daily entry: &lt;code>17 3 * * * DEST=/srv/bioc /usr/local/bin/mirror-sync.sh&lt;/code>.&lt;/li>
&lt;/ul>
&lt;h2 id="step-3-build-the-index-with-scip-r">Step 3: build the index with scip-r&lt;/h2>
&lt;p>Install scip-r as a uv tool, as in its README:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-sh" data-lang="sh">&lt;span class="line">&lt;span class="cl">uv tool install &lt;span class="s2">&amp;#34;scip-r[export] @ git+https://github.com/seandavi/scip-r&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>For those interested, I submitted a feature request to scip-r as
&lt;a href="https://github.com/seandavi/scip-r/pull/52" target="_blank" rel="noopener">pull request #52&lt;/a> to add
full function signatures in the index.&lt;/p>
&lt;p>Run the batch in each version&amp;rsquo;s &lt;code>bioc&lt;/code> directory:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-sh" data-lang="sh">&lt;span class="line">&lt;span class="cl">&lt;span class="nb">cd&lt;/span> ~/bioconductor_repositories/packages/3.24/bioc
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">scip-r batch src/contrib -o out --jobs &lt;span class="m">14&lt;/span> --export parquet --hive
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>The &lt;code>--resolve&lt;/code> flag records the installed R package versions. It needs R on
the machine, so add it only if R is installed (&lt;code>sudo apt install r-base-core&lt;/code>
on Debian or Ubuntu). This index was built without it: none of the rows in
&lt;code>out/summary.jsonl&lt;/code> has a &lt;code>resolve_run_id&lt;/code>, so it is a static index.&lt;/p>
&lt;p>The output is one directory per package under &lt;code>out/&lt;/code>, a &lt;code>summary.jsonl&lt;/code> with one
line per package, and &lt;code>out/parquet/&lt;/code>, with one directory per table. &lt;code>--hive&lt;/code>
partitions each table by &lt;code>index_package&lt;/code> and &lt;code>index_version&lt;/code>.&lt;/p>
&lt;p>For 3.24, &lt;code>summary.jsonl&lt;/code> has 2,451 rows, all with status &lt;code>ok&lt;/code>. The index has
symbols for 2,431 packages. Six of the packages with no symbols are AHMassBank,
BiocVersion, alabaster.schemas, alabaster, assorthead and convert. Why the
other 14 have no symbols is not yet explained.&lt;/p>
&lt;h2 id="step-4-duckdb-views-over-the-parquet">Step 4: DuckDB views over the Parquet&lt;/h2>
&lt;p>Parquet is the store and DuckDB reads it through views. &lt;code>~/make_duckdb.sh&lt;/code>
creates them:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-sh" data-lang="sh">&lt;span class="line">&lt;span class="cl">~/make_duckdb.sh out out/bioc324.duckdb
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Each view is a &lt;code>read_parquet&lt;/code> over one table directory, for example:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-sql" data-lang="sql">&lt;span class="line">&lt;span class="cl">&lt;span class="k">CREATE&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">OR&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">REPLACE&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">VIEW&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">symbols&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">AS&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="k">SELECT&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">*&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">FROM&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">read_parquet&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;/abs/path/out/parquet/symbols/**/*.parquet&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="n">hive_partitioning&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="k">true&lt;/span>&lt;span class="p">);&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>The views store absolute paths, so the database copy in the bundle only works
on the machine that built it. Install rebuilds the views against the local
Parquet files.&lt;/p>
&lt;p>The schema is described in scip-r&amp;rsquo;s &lt;code>docs/parquet-schema.md&lt;/code>. The six tables
are:&lt;/p>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Table&lt;/th>
&lt;th>One row per&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>&lt;code>metadata&lt;/code>&lt;/td>
&lt;td>indexed package: tool version and provenance&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>documents&lt;/code>&lt;/td>
&lt;td>source file&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>symbols&lt;/code>&lt;/td>
&lt;td>symbol defined in a document&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>external_symbols&lt;/code>&lt;/td>
&lt;td>symbol referenced but defined in another package&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>occurrences&lt;/code>&lt;/td>
&lt;td>reference or definition site, with its enclosing &lt;code>caller&lt;/code>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>relationships&lt;/code>&lt;/td>
&lt;td>S3/S4 method to its generic, or class to its superclass&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;p>For 3.24 the database holds 12,307,301 occurrences, 338,790 external symbols,
36,721 documents and 27,175 relationships.&lt;/p>
&lt;h2 id="step-5-bundle-on-the-vm">Step 5: bundle on the VM&lt;/h2>
&lt;p>&lt;code>bioc-index.sh&lt;/code> is in the working directory. Bundle 3.24 from there:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-sh" data-lang="sh">&lt;span class="line">&lt;span class="cl">&lt;span class="nb">cd&lt;/span> ~/bioconductor_repositories
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">./bioc-index.sh bundle 3.24
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>The script takes &lt;code>3.24&lt;/code> and works out the names: the tag is &lt;code>bioc324&lt;/code> and the
bundle is &lt;code>bioc324-index-&amp;lt;date&amp;gt;.tar.gz&lt;/code>. Its default source is
&lt;code>packages/3.24/bioc/out&lt;/code>, and it writes into the current directory. The bundle
contains &lt;code>parquet/&lt;/code> and &lt;code>bioc324.duckdb&lt;/code>. The database is included for reference
only, because install rebuilds it. The script also writes a &lt;code>.sha256&lt;/code> file next
to the tarball.&lt;/p>
&lt;h2 id="step-6-install-where-the-model-runs">Step 6: install where the model runs&lt;/h2>
&lt;p>Copy the tarball and its &lt;code>.sha256&lt;/code> to the machine that will serve the index.
There, run:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-sh" data-lang="sh">&lt;span class="line">&lt;span class="cl">./bioc-index.sh install bioc324-index-20261104.tar.gz
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>The install verifies the checksum, checks that the &lt;code>duckdb&lt;/code> CLI is on the path,
extracts the bundle into &lt;code>~/bioc-index/&amp;lt;bundle name&amp;gt;&lt;/code> unless you pass a
destination, and recreates the views against the local Parquet files. It then
prints package and symbol counts. The output below is from the Jetstream2 VM,
where the default user is &lt;code>exouser&lt;/code>. On your own machine, &lt;code>~/bioc-index&lt;/code> is
under your home directory instead:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-fallback" data-lang="fallback">&lt;span class="line">&lt;span class="cl">bioc324-index-20261104.tar.gz: OK
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Installed to /home/exouser/bioc-index/bioc324-index-20261104
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">│ 2431 │ 191331 │
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Database: /home/exouser/bioc-index/bioc324-index-20261104/bioc324.duckdb
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>That is 305 MB on disk, and it took about six seconds.&lt;/p>
&lt;p>If you use the snap-packaged &lt;code>duckdb&lt;/code>, pass a destination under &lt;code>$HOME&lt;/code>,
because the snap cannot see &lt;code>/tmp&lt;/code>.&lt;/p>
&lt;h2 id="step-7-query-it">Step 7: query it&lt;/h2>
&lt;p>The queries in this step show what the index can answer, and they are useful
for checking that the install worked. In day-to-day use you would not write
them yourself. The AI model writes and runs them, as described in the next
section. Each query below is paired with a prompt you might give the model to
get it.&lt;/p>
&lt;p>Open the database read-only:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-sh" data-lang="sh">&lt;span class="line">&lt;span class="cl">duckdb -readonly ~/bioc-index/bioc324-index-20261104/bioc324.duckdb
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>The packages with the most function symbols:&lt;/p>
&lt;blockquote>
&lt;p>Which five Bioconductor packages define the most functions?&lt;/p>
&lt;/blockquote>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-sql" data-lang="sql">&lt;span class="line">&lt;span class="cl">&lt;span class="k">SELECT&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">index_package&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">count&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="o">*&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">AS&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">n_symbols&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="k">FROM&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">symbols&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">WHERE&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">is_function&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="k">GROUP&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">BY&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="mi">1&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">ORDER&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">BY&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="mi">2&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">DESC&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">LIMIT&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="mi">5&lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>This returns ChemmineOB (4,566), mia (1,392), igblastr (1,353), xcms (1,235) and
S4Vectors (1,049).&lt;/p>
&lt;p>A call graph for limma, using the &lt;code>GROUP BY caller, symbol&lt;/code> pattern from the
schema doc:&lt;/p>
&lt;blockquote>
&lt;p>In limma, which functions call which other functions most often?&lt;/p>
&lt;/blockquote>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-sql" data-lang="sql">&lt;span class="line">&lt;span class="cl">&lt;span class="k">SELECT&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">caller&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">symbol&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">count&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="o">*&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">AS&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">n&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="k">FROM&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">occurrences&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="k">WHERE&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">caller&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">IS&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">NOT&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">NULL&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">AND&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">NOT&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">is_definition&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">AND&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">index_package&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s1">&amp;#39;limma&amp;#39;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="k">GROUP&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">BY&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">ALL&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">ORDER&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">BY&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">n&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">DESC&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">LIMIT&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="mi">4&lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>The top rows show &lt;code>printtipWeights()&lt;/code> calling &lt;code>base::sum()&lt;/code> 136 times. The
&lt;code>caller&lt;/code> and &lt;code>symbol&lt;/code> columns hold raw SCIP strings such as &lt;code>scip-r . base . sum().&lt;/code>, and &lt;code>local N&lt;/code> marks a file-local symbol. For a clean function-level
graph, add &lt;code>AND NOT is_local&lt;/code> and use the parsed &lt;code>package&lt;/code> and &lt;code>name&lt;/code> columns
instead of splitting the strings.&lt;/p>
&lt;p>Counting how often each function from another package is called:&lt;/p>
&lt;blockquote>
&lt;p>Across Bioconductor, which functions from other packages are called most
often, and by how many packages?&lt;/p>
&lt;/blockquote>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-sql" data-lang="sql">&lt;span class="line">&lt;span class="cl">&lt;span class="k">SELECT&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">package&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">name&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">count&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="o">*&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">AS&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">calls&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="k">count&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="k">DISTINCT&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">index_package&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">AS&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">n_pkgs&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="k">FROM&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">occurrences&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="k">WHERE&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">NOT&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">is_local&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">AND&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">NOT&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">is_definition&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">AND&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">is_function&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="k">AND&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">package&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">&amp;lt;&amp;gt;&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">index_package&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="k">GROUP&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">BY&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">ALL&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">ORDER&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">BY&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">calls&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">DESC&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">LIMIT&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="mi">10&lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Including base R, &lt;code>base::c&lt;/code> leads with 238,725 calls from 2,376 packages,
followed by &lt;code>base::length&lt;/code> and &lt;code>base::return&lt;/code>. Excluding base R, which
you can do by adding &lt;code>AND package NOT IN ('base', 'methods', 'stats', 'utils', 'grid', 'graphics', 'grDevices', 'tools', 'parallel')&lt;/code> (and the
other base packages) to the &lt;code>WHERE&lt;/code> clause, &lt;code>ggplot2::aes&lt;/code> leads with 5,794
calls from 465 packages, followed by &lt;code>dplyr::mutate&lt;/code> and &lt;code>dplyr::filter&lt;/code>. The
prompt for that version:&lt;/p>
&lt;blockquote>
&lt;p>Same question, but leave out base R packages.&lt;/p>
&lt;/blockquote>
&lt;p>Two things to know about these counts:&lt;/p>
&lt;ul>
&lt;li>&lt;code>return&lt;/code> is a function call in R, so it ranks high. Drop it if you only
want library functions.&lt;/li>
&lt;li>Ranking by &lt;code>n_pkgs&lt;/code> instead of &lt;code>calls&lt;/code> finds functions that many packages
share, rather than functions that one package calls heavily.&lt;/li>
&lt;/ul>
&lt;h2 id="giving-it-to-a-model">Giving it to a model&lt;/h2>
&lt;p>A reasonable setup gives the model two things: the scip-r schema doc, and one
tool that runs read-only SQL against the database. With the schema doc in
context, the model can write its own queries. That tool isn&amp;rsquo;t built yet, and it
is the next step.&lt;/p>
&lt;h2 id="things-to-change-next-time">Things to change next time&lt;/h2>
&lt;ol>
&lt;li>Use &lt;code>mirror-sync.sh&lt;/code>, or make the &lt;code>release&lt;/code> and &lt;code>devel&lt;/code> symlinks by hand, so
URLs through those names work.&lt;/li>
&lt;li>Schedule the sync. The copy dates from 4 November 2026, and the
manifest is regenerated every hour.&lt;/li>
&lt;li>Install under &lt;code>$HOME&lt;/code> when you use the snap &lt;code>duckdb&lt;/code>.&lt;/li>
&lt;li>Decide whether the index covers source only, as it does here, or the binaries
too.&lt;/li>
&lt;li>&lt;code>bioc-index.sh&lt;/code> hard-codes &lt;code>SRC_ROOT&lt;/code> to
&lt;code>/home/exouser/bioconductor_repositories/packages&lt;/code>, the path on the
Jetstream2 VM. On another machine, or as a user other than &lt;code>exouser&lt;/code>, either
edit &lt;code>SRC_ROOT&lt;/code> or pass the index directory as the second argument:
&lt;code>./bioc-index.sh bundle 3.24 ~/bioconductor_repositories/packages/3.24/bioc/out&lt;/code>.&lt;/li>
&lt;/ol>
&lt;div class="footnotes" role="doc-endnotes">
&lt;hr>
&lt;ol>
&lt;li id="fn:1">
&lt;p>This post was prepared by Claude Opus 5.5 (model ID
&lt;code>claude-opus-5-5&lt;/code>), an AI model made by Anthropic, using Claude Code.&amp;#160;&lt;a href="#fnref:1" class="footnote-backref" role="doc-backlink">&amp;#x21a9;&amp;#xfe0e;&lt;/a>&lt;/p>
&lt;/li>
&lt;/ol>
&lt;/div></description></item></channel></rss>