{"version":"https://jsonfeed.org/version/1","title":"rOpenSci - open tools for open science","home_page_url":"https://ropensci.org/rbloggers/index.xml","feed_url":"https://ropensci.org/rbloggers/index.xml/index.json","description":"Open Tools and R Packages for Open Science","items":[{"id":"https://ropensci.org/blog/2026/04/13/reviser/","title":"reviser: Analyzing Real-Time Data Revisions in R","content_text":"\u003cp\u003eEconomic data are rarely static.\nGross domestic product (GDP), inflation, employment, and other official statistics arrive as early estimates, then get revised as new source data arrive, seasonal adjustment is updated, or benchmarking changes are applied.\nThose revisions matter because they can change the narrative around turning points, policy mistakes, and forecast performance.\u003c/p\u003e\n\u003cp\u003e\u003ca href=\"https://docs.ropensci.org/reviser/\"\u003e\u003ccode\u003ereviser\u003c/code\u003e\u003c/a\u003e is an R package by Marc Burri and Philipp Wegmüller for working with these vintage datasets directly.\nA vintage dataset records multiple published versions of the same time series, so you can compare what was known at each release date with what was reported later.\n\u003ccode\u003ereviser\u003c/code\u003e gives you a consistent workflow to:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003ereshape release vintages between wide and tidy formats;\u003c/li\u003e\n\u003cli\u003eextract revisions relative to earlier or final releases;\u003c/li\u003e\n\u003cli\u003esummarize bias, dispersion, and serial dependence in revisions;\u003c/li\u003e\n\u003cli\u003eidentify the first release that is statistically close to the eventual benchmark;\u003c/li\u003e\n\u003cli\u003enowcast future revisions with state-space models.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eThe package is aimed at users who already work with real-time macroeconomic data and want tools that go beyond plotting revision triangles by hand.\nOne design goal is to keep that workflow in pure R.\u003c/p\u003e\n\u003cp\u003e\u003ccode\u003ereviser\u003c/code\u003e was reviewed through \u003ca href=\"https://github.com/ropensci/software-review/issues/709\"\u003erOpenSci statistical software peer review\u003c/a\u003e.\nMany thanks to reviewers \u003ca href=\"https://github.com/AlexGibberd\"\u003eAlex Gibberd\u003c/a\u003e, and \u003ca href=\"https://github.com/TanguyBarthelemy\"\u003eTanguy Barthelemy\u003c/a\u003e, and to editor \u003ca href=\"https://github.com/rkillick\"\u003eRebecca Killick\u003c/a\u003e, for feedback that improved the package.\u003c/p\u003e\n\u003ch2 id=\"why-revision-analysis-deserves-its-own-workflow\"\u003e\n\n\u003ca class=\"anchor d-print-none\" href=\"#why-revision-analysis-deserves-its-own-workflow\"\u003e\n  \u003csmall\u003e\u0026#x1F517;\u003c/small\u003e\n\u003c/a\u003e\n\nWhy revision analysis deserves its own workflow\n\u003c/h2\u003e\u003cp\u003eRevisions are not just measurement noise.\nThey encode how information enters the data-production process.\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eSome revisions reflect genuinely new information.\u003c/li\u003e\n\u003cli\u003eOthers reflect noise that could, in principle, have been reduced earlier.\u003c/li\u003e\n\u003cli\u003eStill others come from methodological changes or benchmark updates.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eThese distinctions matter if you are evaluating early data releases, building nowcasts, or asking whether first releases are already efficient summaries of the available information.\u003c/p\u003e\n\u003cp\u003eThe \u003ccode\u003ereviser\u003c/code\u003e vignettes organize this workflow into three layers:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003eStructure vintages consistently.\u003c/li\u003e\n\u003cli\u003eMeasure and test revision properties.\u003c/li\u003e\n\u003cli\u003eModel the revision process when you want to predict future changes.\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch2 id=\"a-compact-example-with-gdp-vintages\"\u003e\n\n\u003ca class=\"anchor d-print-none\" href=\"#a-compact-example-with-gdp-vintages\"\u003e\n  \u003csmall\u003e\u0026#x1F517;\u003c/small\u003e\n\u003c/a\u003e\n\nA compact example with GDP vintages\n\u003c/h2\u003e\u003cp\u003eThe first step is to reshape the data into a tidy vintage format, where each row corresponds to an observed value, the date it refers to, and the publication date of that estimate.\u003c/p\u003e\n\u003cp\u003eThe package ships with a GDP example dataset in long vintage format.\nSuppose we want to focus on U.S. GDP growth, visualize how estimates moved during the 2008-09 global financial crisis, and then ask whether early releases were systematically biased relative to a later benchmark.\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-r\" data-lang=\"r\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nf\"\u003elibrary\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ereviser\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nf\"\u003elibrary\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003edplyr\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nf\"\u003elibrary\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003etsbox\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003egdp_us\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;-\u003c/span\u003e \u003cspan class=\"n\"\u003egdp\u003c/span\u003e \u003cspan class=\"o\"\u003e|\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"nf\"\u003efilter\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e \u003cspan class=\"o\"\u003e==\u003c/span\u003e \u003cspan class=\"s\"\u003e\u0026#34;US\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"o\"\u003e|\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"n\"\u003etsbox\u003c/span\u003e\u003cspan class=\"o\"\u003e::\u003c/span\u003e\u003cspan class=\"nf\"\u003ets_pc\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e \u003cspan class=\"o\"\u003e|\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"n\"\u003etsbox\u003c/span\u003e\u003cspan class=\"o\"\u003e::\u003c/span\u003e\u003cspan class=\"nf\"\u003ets_span\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estart\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"s\"\u003e\u0026#34;1980-01-01\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003egdp_wide\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;-\u003c/span\u003e \u003cspan class=\"nf\"\u003evintages_wide\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003egdp_us\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003egdp_long\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;-\u003c/span\u003e \u003cspan class=\"nf\"\u003evintages_long\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003egdp_wide\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003ekeep_na\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"kc\"\u003eFALSE\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003eWith the vintages in tidy form, we can plot how the published path changed over time.\nThe y-axis in the figure reports quarter-on-quarter GDP growth rates.\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-r\" data-lang=\"r\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nf\"\u003eplot_vintages\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"n\"\u003egdp_long\u003c/span\u003e \u003cspan class=\"o\"\u003e|\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nf\"\u003efilter\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e      \u003cspan class=\"n\"\u003epub_date\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026gt;=\u003c/span\u003e \u003cspan class=\"nf\"\u003eas.Date\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;2009-01-01\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e      \u003cspan class=\"n\"\u003epub_date\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e \u003cspan class=\"nf\"\u003eas.Date\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;2010-01-01\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e      \u003cspan class=\"n\"\u003etime\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e \u003cspan class=\"nf\"\u003eas.Date\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;2008-01-01\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e      \u003cspan class=\"n\"\u003etime\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e \u003cspan class=\"nf\"\u003eas.Date\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;2010-01-01\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"n\"\u003etype\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"s\"\u003e\u0026#34;line\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"n\"\u003etitle\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"s\"\u003e\u0026#34;Revisions of GDP during the 2008-09 global financial crisis\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"n\"\u003eylab\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"s\"\u003e\u0026#34;Quarter-on-quarter GDP growth rate\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cfigure\u003e\u003cimg src=\"/blog/2026/04/13/reviser/gdp-example-plot-1.svg\"\n    alt=\"Multiple vintage paths for U.S. GDP growth, highlighting how estimates published in 2009 changed over time.\" width=\"100%\"\u003e\u003cfigcaption\u003e\n      \u003cp\u003eGDP growth vintages for the United States during the 2008-09 global financial crisis.\u003c/p\u003e\n    \u003c/figcaption\u003e\n\u003c/figure\u003e\n\n\u003cp\u003eDuring volatile periods, the vintage paths can diverge enough that the story told by the first release is noticeably different from the story told a year later.\u003c/p\u003e\n\u003cp\u003eOnce the data are in tidy vintage form, you can compare a set of early releases to a later benchmark release.\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-r\" data-lang=\"r\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003efinal_release\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;-\u003c/span\u003e \u003cspan class=\"nf\"\u003eget_nth_release\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003egdp_long\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003en\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"m\"\u003e10\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003eearly_releases\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;-\u003c/span\u003e \u003cspan class=\"nf\"\u003eget_nth_release\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003egdp_long\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003en\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"m\"\u003e0\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e\u003cspan class=\"m\"\u003e6\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003esummary_tbl\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;-\u003c/span\u003e \u003cspan class=\"nf\"\u003eget_revision_analysis\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eearly_releases\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003efinal_release\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cpre tabindex=\"0\"\u003e\u003ccode\u003eWarning: Both \u0026#39;release\u0026#39; and \u0026#39;pub_date\u0026#39; columns are present in \u0026#39;df.\n      The \u0026#39;release\u0026#39; column will be used for grouping.\n\u003c/code\u003e\u003c/pre\u003e\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-r\" data-lang=\"r\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003esummary_tbl\u003c/span\u003e \u003cspan class=\"o\"\u003e|\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"nf\"\u003eselect\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003erelease\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"nf\"\u003e`Bias \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003emean\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"n\"\u003e`, `\u003c/span\u003e\u003cspan class=\"nf\"\u003eBias \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003erobust\u003c/span\u003e \u003cspan class=\"n\"\u003ep\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003evalue\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"n\"\u003e`, `Noise\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"n\"\u003eSignal`\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cpre tabindex=\"0\"\u003e\u003ccode\u003e\n=== Revision Analysis Summary ===\n\n# A tibble: 7 × 5\n  id    release   `Bias (mean)` `Bias (robust p-value)` `Noise/Signal`\n  \u0026lt;chr\u0026gt; \u0026lt;chr\u0026gt;             \u0026lt;dbl\u0026gt;                   \u0026lt;dbl\u0026gt;          \u0026lt;dbl\u0026gt;\n1 US    release_0        -0.014                   0.52           0.22 \n2 US    release_1        -0.015                   0.425          0.202\n3 US    release_2        -0.013                   0.507          0.205\n4 US    release_3        -0.003                   0.851          0.194\n5 US    release_4        -0.014                   0.326          0.157\n6 US    release_5        -0.021                   0.181          0.152\n7 US    release_6        -0.018                   0.202          0.13 \n\n=== Interpretation ===\n\nid=US, release=release_0:\n  • No significant bias detected (p = 0.52 )\n  • Moderate revision volatility (Noise/Signal = 0.22 )\n\nid=US, release=release_1:\n  • No significant bias detected (p = 0.425 )\n  • Moderate revision volatility (Noise/Signal = 0.202 )\n\nid=US, release=release_2:\n  • No significant bias detected (p = 0.507 )\n  • Moderate revision volatility (Noise/Signal = 0.205 )\n\nid=US, release=release_3:\n  • No significant bias detected (p = 0.851 )\n  • Moderate revision volatility (Noise/Signal = 0.194 )\n\nid=US, release=release_4:\n  • No significant bias detected (p = 0.326 )\n  • Moderate revision volatility (Noise/Signal = 0.157 )\n\nid=US, release=release_5:\n  • No significant bias detected (p = 0.181 )\n  • Moderate revision volatility (Noise/Signal = 0.152 )\n\nid=US, release=release_6:\n  • No significant bias detected (p = 0.202 )\n  • Moderate revision volatility (Noise/Signal = 0.13 )\n\u003c/code\u003e\u003c/pre\u003e\u003cp\u003eThis is where \u003ccode\u003ereviser\u003c/code\u003e moves beyond a reshape-and-plot package.\nThe revision summary reports quantities that applied work often needs but usually rebuilds ad hoc: mean bias, quantiles, volatility, noise-to-signal ratios, and hypothesis tests for bias, serial correlation, and news-versus-noise interpretations.\u003c/p\u003e\n\u003cp\u003eIn the bundled example, the early U.S. GDP releases over this sample show little evidence of systematic bias relative to the later benchmark.\nThe package also supports efficient-release diagnostics, where the question is not only whether revisions exist, but when additional revisions stop adding meaningful information.\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-r\" data-lang=\"r\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003eefficient_release\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;-\u003c/span\u003e \u003cspan class=\"nf\"\u003eget_first_efficient_release\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eearly_releases\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003efinal_release\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nf\"\u003esummary\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eefficient_release\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cpre tabindex=\"0\"\u003e\u003ccode\u003eEfficient release:  0 \n\nModel summary: \n\nCall:\nstats::lm(formula = formula, data = df_wide)\n\nResiduals:\n     Min       1Q   Median       3Q      Max \n-0.89186 -0.12669  0.02046  0.11475  0.97986 \n\nCoefficients:\n            Estimate Std. Error t value Pr(\u0026gt;|t|)    \n(Intercept)  0.00299    0.02223   0.134    0.893    \nrelease_0    0.97412    0.01692  57.567   \u0026lt;2e-16 ***\n---\nSignif. codes:  0 \u0026#39;***\u0026#39; 0.001 \u0026#39;**\u0026#39; 0.01 \u0026#39;*\u0026#39; 0.05 \u0026#39;.\u0026#39; 0.1 \u0026#39; \u0026#39; 1\n\nResidual standard error: 0.2518 on 166 degrees of freedom\n  (10 observations deleted due to missingness)\nMultiple R-squared:  0.9523,\tAdjusted R-squared:  0.952 \nF-statistic:  3314 on 1 and 166 DF,  p-value: \u0026lt; 2.2e-16\n\n\nTest summary: \n\nLinear hypothesis test:\n(Intercept) = 0\nrelease_0 = 1\n\nModel 1: restricted model\nModel 2: final ~ release_0\n\nNote: Coefficient covariance matrix supplied.\n\n  Res.Df Df      F Pr(\u0026gt;F)\n1    168                 \n2    166  2 1.9283 0.1486\n\u003c/code\u003e\u003c/pre\u003e\u003cp\u003eThat is exactly the kind of result that is hard to see from a revision triangle alone but straightforward to formalize once the workflow is standardized.\nIn this sample, the result points to the first release as already being statistically close to the later benchmark, which suggests subsequent revisions add relatively little systematic information.\u003c/p\u003e\n\u003ch2 id=\"from-descriptive-analysis-to-revision-nowcasting\"\u003e\n\n\u003ca class=\"anchor d-print-none\" href=\"#from-descriptive-analysis-to-revision-nowcasting\"\u003e\n  \u003csmall\u003e\u0026#x1F517;\u003c/small\u003e\n\u003c/a\u003e\n\nFrom descriptive analysis to revision nowcasting\n\u003c/h2\u003e\u003cp\u003eFor many users, revision summaries will be the main use case.\nBut \u003ccode\u003ereviser\u003c/code\u003e also includes model-based tools for users who want to treat revisions as an explicit latent-data problem.\nThat matters if you need to make decisions on preliminary data but also want a structured way to estimate how those figures are likely to change later.\u003c/p\u003e\n\u003cp\u003eTwo vignettes walk through nowcasting revisions with:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003ethe generalized Kishor-Koenig family via \u003ccode\u003ekk_nowcast()\u003c/code\u003e;\u003c/li\u003e\n\u003cli\u003ethe Jacobs-Van Norden model via \u003ccode\u003ejvn_nowcast()\u003c/code\u003e.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eBoth approaches cast the revision problem into state-space form, which makes it possible to estimate the dynamics of news and noise in successive data releases.\nFor technical users, this is the part of the package that turns revision analysis from retrospective diagnosis into a forecasting problem.\u003c/p\u003e\n\u003cp\u003eHere is a compact \u003ccode\u003ekk_nowcast()\u003c/code\u003e example following the Kishor-Koenig workflow from the \u003ca href=\"https://docs.ropensci.org/reviser/articles/nowcasting-revisions-kk.html\"\u003evignette\u003c/a\u003e for the Euro Area (EA).\u003cbr\u003e\nThe key idea is to first identify an efficient release \u003ccode\u003ee\u003c/code\u003e, then estimate the revision system on the corresponding panel of releases.\nIn this euro area example, the efficient-release step selects \u003ccode\u003ee = 2\u003c/code\u003e, so the model treats the third published release as the earliest one that is already close to the later benchmark.\nThat is a useful substantive result on its own: it suggests that most of the economically relevant signal arrives within the first few releases, while later revisions are smaller adjustments around that path.\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-r\" data-lang=\"r\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003egdp_ea\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;-\u003c/span\u003e \u003cspan class=\"n\"\u003ereviser\u003c/span\u003e\u003cspan class=\"o\"\u003e::\u003c/span\u003e\u003cspan class=\"n\"\u003egdp\u003c/span\u003e \u003cspan class=\"o\"\u003e|\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"n\"\u003etsbox\u003c/span\u003e\u003cspan class=\"o\"\u003e::\u003c/span\u003e\u003cspan class=\"nf\"\u003ets_pc\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e \u003cspan class=\"o\"\u003e|\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"n\"\u003edplyr\u003c/span\u003e\u003cspan class=\"o\"\u003e::\u003c/span\u003e\u003cspan class=\"nf\"\u003efilter\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003eid\u003c/span\u003e \u003cspan class=\"o\"\u003e==\u003c/span\u003e \u003cspan class=\"s\"\u003e\u0026#34;EA\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003etime\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026gt;=\u003c/span\u003e \u003cspan class=\"nf\"\u003emin\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003epub_date\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003etime\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;=\u003c/span\u003e \u003cspan class=\"nf\"\u003eas.Date\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;2020-01-01\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003ereleases\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;-\u003c/span\u003e \u003cspan class=\"nf\"\u003eget_nth_release\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003egdp_ea\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003en\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"m\"\u003e0\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e\u003cspan class=\"m\"\u003e14\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003efinal_release\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;-\u003c/span\u003e \u003cspan class=\"nf\"\u003eget_nth_release\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003egdp_ea\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003en\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"m\"\u003e15\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003eefficient_release\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;-\u003c/span\u003e \u003cspan class=\"nf\"\u003eget_first_efficient_release\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ereleases\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003efinal_release\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003efit_kk\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;-\u003c/span\u003e \u003cspan class=\"nf\"\u003ekk_nowcast\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"n\"\u003edf\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003eefficient_release\u003c/span\u003e\u003cspan class=\"o\"\u003e$\u003c/span\u003e\u003cspan class=\"n\"\u003edata\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"n\"\u003ee\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003eefficient_release\u003c/span\u003e\u003cspan class=\"o\"\u003e$\u003c/span\u003e\u003cspan class=\"n\"\u003ee\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"n\"\u003emodel\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"s\"\u003e\u0026#34;KK\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"n\"\u003emethod\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"s\"\u003e\u0026#34;MLE\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nf\"\u003esummary\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003efit_kk\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cpre tabindex=\"0\"\u003e\u003ccode\u003e\n=== Kishor-Koenig Model ===\n\nConvergence: Success \nLog-likelihood: 125.7 \nAIC: -231.41 \nBIC: -198.23 \n\nParameter Estimates:\n Parameter Estimate Std.Error\n        F0    0.633     0.131\n      G0_0    0.950     0.031\n      G0_1   -0.037     0.152\n      G0_2   -0.181     0.220\n      G1_0   -0.009     0.011\n      G1_1    0.594     0.061\n      G1_2    0.194     0.092\n        v0    0.380     0.068\n      eps0    0.008     0.001\n      eps1    0.001     0.000\n\u003c/code\u003e\u003c/pre\u003e\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-r\" data-lang=\"r\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nf\"\u003eplot\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003efit_kk\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cfigure\u003e\u003cimg src=\"/blog/2026/04/13/reviser/kk-nowcast-example-1.svg\"\n    alt=\"Diagnostic plot from a Kishor-Koenig nowcast model for euro area GDP revisions, summarizing the fitted revision dynamics.\" width=\"100%\"\u003e\u003cfigcaption\u003e\n      \u003cp\u003eDiagnostic plot from the Kishor-Koenig nowcast example.\u003c/p\u003e\n    \u003c/figcaption\u003e\n\u003c/figure\u003e\n\n\u003cp\u003eThe fitted object contains estimated parameters, filtered and smoothed latent states, and plotting methods for the implied efficient-release path.\nThat gives you a direct route from descriptive revision analysis to a state-space nowcast of future revisions.\nFor a broader audience, the main takeaway is not the individual coefficients.\nIt is that the model converges cleanly on this sample, summarizes the revision process in a compact latent-state form, and provides a practical way to judge whether a new release is likely to be revised materially later on.\nSubstantively, the model separates persistent signal from transitory revision noise, so the output is useful when you want to judge whether new releases are likely to be revised materially.\u003c/p\u003e\n\u003ch2 id=\"what-reviser-adds\"\u003e\n\n\u003ca class=\"anchor d-print-none\" href=\"#what-reviser-adds\"\u003e\n  \u003csmall\u003e\u0026#x1F517;\u003c/small\u003e\n\u003c/a\u003e\n\nWhat reviser adds\n\u003c/h2\u003e\u003cp\u003eWhat stands out in \u003ccode\u003ereviser\u003c/code\u003e is not a single function, but the coherence of the workflow:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003ethe package has explicit conventions for vintage data;\u003c/li\u003e\n\u003cli\u003edescriptive revision analysis and formal testing sit in the same API;\u003c/li\u003e\n\u003cli\u003eefficient-release analysis connects directly to applied questions about which release to trust;\u003c/li\u003e\n\u003cli\u003enowcasting tools extend the same workflow rather than forcing a separate modeling stack.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eIf you work with real-time macroeconomic data, that combination is useful because revision analysis is usually fragmented across custom scripts, one-off spreadsheets, and package combinations that do not share a common data structure.\u003c/p\u003e\n\u003ch2 id=\"try-it-and-push-it-further\"\u003e\n\n\u003ca class=\"anchor d-print-none\" href=\"#try-it-and-push-it-further\"\u003e\n  \u003csmall\u003e\u0026#x1F517;\u003c/small\u003e\n\u003c/a\u003e\n\nTry it and push it further\n\u003c/h2\u003e\u003cp\u003eYou can install the package from the rOpenSci R-universe:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-r\" data-lang=\"r\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nf\"\u003einstall.packages\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"s\"\u003e\u0026#34;reviser\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"n\"\u003erepos\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nf\"\u003ec\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;https://ropensci.r-universe.dev\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"s\"\u003e\u0026#34;https://cloud.r-project.org\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003eThen start with the package site and vignettes:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003edocs: \u003ca href=\"https://docs.ropensci.org/reviser\"\u003ehttps://docs.ropensci.org/reviser\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003esource: \u003ca href=\"https://github.com/ropensci/reviser\"\u003ehttps://github.com/ropensci/reviser\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eWe would be happy to hear feedback from those of you trying out the package with different datasets.\nIf you have a real-time dataset with a different release structure, that would be a good stress test for the package.\nIf you find gaps in the workflow or have a use case to share, open an issue or contribute an example.\nRevision analysis gets more useful as it becomes easier to compare workflows across datasets rather than rebuilding them from scratch each time.\u003c/p\u003e\n","url":"https://ropensci.org/blog/2026/04/13/reviser/","date_published":"2026-04-13T00:00:00+00:00"},{"id":"https://ropensci.org/blog/2026/04/08/r-universe-bioc/","title":"Collaborating between Bioconductor and R-universe on Development of Common Infrastructure","content_text":"\u003cp\u003eFor more than two decades, the \u003ca href=\"https://www.bioconductor.org/\"\u003eBioconductor project\u003c/a\u003e has been a cornerstone of the R ecosystem, providing high-quality, peer-reviewed tools for bioinformatics and computational biology. Its curated repository model, rigorous review standards, and tightly coordinated release process have helped establish Bioconductor as one of the most trusted distribution channels in scientific computing.\u003c/p\u003e\n\u003cp\u003eHowever, the infrastructure that supports such a long-standing and large-scale project inevitably accumulates technical debt. Legacy build systems, bespoke tooling, and historically grown workflows add up to costly and unsustainable maintenance work. For this reason, Bioconductor is collaborating with \u003ca href=\"https://r-universe.dev/\"\u003eR-universe\u003c/a\u003e to gradually modernize parts of its infrastructure, while accommodating the project’s scale, governance, and established processes. In turn, Bioconductor is helping R-universe expand and refine its features as we learn to serve the complex needs of the Bioconductor community.\u003c/p\u003e\n\u003cp\u003eThis collaboration reflects a core principle of R-universe as an R Consortium \u003ca href=\"https://r-consortium.org/all-projects/\"\u003eInfrastructure Steering Committee (ISC)\u003c/a\u003e top-level project: supporting reviewed package repositories such as rOpenSci and Bioconductor, and providing modern, open, and reusable infrastructure that strengthens the broader R ecosystem.\u003c/p\u003e\n\u003ch2 id=\"a-shared-mission-tooling-for-managed-repositories\"\u003e\n\n\u003ca class=\"anchor d-print-none\" href=\"#a-shared-mission-tooling-for-managed-repositories\"\u003e\n  \u003csmall\u003e\u0026#x1F517;\u003c/small\u003e\n\u003c/a\u003e\n\nA shared mission: Tooling for managed repositories\n\u003c/h2\u003e\u003cp\u003eR-universe was designed as a next-generation package distribution and build system for R. It provides:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eContinuous building and checking of R packages across platforms\u003c/li\u003e\n\u003cli\u003eBinary packages for Windows, macOS, Linux, and WebAssembly\u003c/li\u003e\n\u003cli\u003eTransparent and reproducible build environments managed via GitHub actions\u003c/li\u003e\n\u003cli\u003eDashboards and metadata APIs for monitoring ecosystem health and activity\u003c/li\u003e\n\u003cli\u003eCRAN-like package repositories with discoverable metrics and documentation\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eFrom the outset, a key objective has been to support curated and reviewed communities — such as rOpenSci and Bioconductor — by offering modern infrastructure without requiring them to redesign their governance model or review processes.\u003c/p\u003e\n\u003cp\u003eFor Bioconductor, this means incrementally introducing piece-wise functionality, with consideration for established release cycles and quality control mechanisms:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003eSetting up independent build and dashboard tooling, replicating processes from the current Bioconductor build systems on R-universe infrastructure\u003c/li\u003e\n\u003cli\u003eMirroring Windows and macOS binaries produced on R-universe to Bioconductor\u003c/li\u003e\n\u003cli\u003eExploring further integration of results and metadata produced by R-universe for Bioconductor health/activity monitoring and aiding the curation processes\u003c/li\u003e\n\u003cli\u003ePotential future steps toward deeper automation and harmonization\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003eBy taking small gradual steps towards adopting R-universe components, everyone gets the opportunity to experiment with new tooling and evaluate where adjustments may be needed in order to minimize disruption to existing practices.\u003c/p\u003e\n\u003cp\u003eAn important milestone in this venture is that Bioconductor now uses R-universe to build the Windows and macOS binaries, which significantly reduces costs and the maintenance load on the Bioconductor team. Beyond binary distribution, we are currently exploring deeper integration of R-universe’s continuous check results into Bioconductor’s quality control and release processes.\u003c/p\u003e\n\u003ch2 id=\"two-universes-release-and-development\"\u003e\n\n\u003ca class=\"anchor d-print-none\" href=\"#two-universes-release-and-development\"\u003e\n  \u003csmall\u003e\u0026#x1F517;\u003c/small\u003e\n\u003c/a\u003e\n\nTwo Universes: Release and Development\n\u003c/h2\u003e\u003cp\u003eBioconductor maintains two distinct repositories:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eA \u003cstrong\u003erelease\u003c/strong\u003e branch for stable packages\u003c/li\u003e\n\u003cli\u003eA \u003cstrong\u003edevel\u003c/strong\u003e branch for ongoing development and the next release cycle\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eTo mirror this structure, we currently operate two dedicated R-universe instances:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003cstrong\u003eDevelopment branch:\u003c/strong\u003e \u003ca href=\"https://bioc.r-universe.dev\"\u003ehttps://bioc.r-universe.dev\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eRelease branch:\u003c/strong\u003e \u003ca href=\"https://bioc-release.r-universe.dev\"\u003ehttps://bioc-release.r-universe.dev\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eThese universes integrate directly with Bioconductor’s existing Git infrastructure and provide continuous builds for packages in both branches.\u003c/p\u003e\n\u003cp\u003eThrough the R-universe dashboard, package maintainers and users can:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eInspect cross-platform check results\u003c/li\u003e\n\u003cli\u003eReview extended BiocCheck diagnostics\u003c/li\u003e\n\u003cli\u003eMonitor build logs and dependency graphs\u003c/li\u003e\n\u003cli\u003eExplore rich package metadata and metrics\u003c/li\u003e\n\u003cli\u003ePublish binary packages for Windows, macOS, and Linux\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eThis provides a familiar yet modern interface for Bioconductor contributors, aligned with what users increasingly expect from contemporary R package infrastructure.\u003c/p\u003e\n\u003cp\u003eInformation about each package is available on \u003ccode\u003ehttps://bioc.r-universe.dev/{pkgname}\u003c/code\u003e. For example,  \u003ca href=\"https://bioc.r-universe.dev/DESeq2\"\u003ehttps://bioc.r-universe.dev/DESeq2\u003c/a\u003e provides details on the DESeq2 package as shown below:\u003c/p\u003e\n\n\n\n\u003cdiv class=\"box\" \u003e\n  \u003cfigure  itemprop=\"associatedMedia\" itemscope itemtype=\"http://schema.org/ImageObject\"\u003e\n    \u003cdiv class=\"img\"\u003e\n      \u003cimg itemprop=\"thumbnail\" src=\"https://docs.r-universe.dev/img/bioc-pkg.png\" alt=\"screenshot of r-universe package\"/\u003e\n    \u003c/div\u003e\n    \u003ca href=\"https://docs.r-universe.dev/img/bioc-pkg.png\" itemprop=\"contentUrl\" aria-disabled=\"true\"\u003e\u003c/a\u003e\n  \u003c/figure\u003e\n\u003c/div\u003e\n\n\u003cp\u003eIf this is your first time visiting R-universe, we recommend clicking the \u0026ldquo;Website Tour\u0026rdquo; button which will walk you through the most important information in 1 or 2 minutes.\u003c/p\u003e\n\u003ch2 id=\"technical-documentation-for-bioconductor-maintainers\"\u003e\n\n\u003ca class=\"anchor d-print-none\" href=\"#technical-documentation-for-bioconductor-maintainers\"\u003e\n  \u003csmall\u003e\u0026#x1F517;\u003c/small\u003e\n\u003c/a\u003e\n\nTechnical Documentation for Bioconductor Maintainers\n\u003c/h2\u003e\u003cp\u003eThe R-universe project maintains comprehensive technical documentation at \u003ca href=\"https://docs.r-universe.dev\"\u003ehttps://docs.r-universe.dev\u003c/a\u003e. For Bioconductor specifically, we created a dedicated section summarizing the most relevant topics for developers to get started with R-universe: \u003ca href=\"https://docs.r-universe.dev/bioconductor/\"\u003ehttps://docs.r-universe.dev/bioconductor/\u003c/a\u003e\u003c/p\u003e\n\u003cp\u003eAs the collaboration evolves and new components get introduced, the documentation will continue to be expanded. The goal is to provide Bioconductor maintainers with a clear reference point for understanding how R-universe fits into their development workflow, while maintaining compatibility with the established practices that have made Bioconductor a successful project within the R community.\u003c/p\u003e\n\u003ch2 id=\"looking-ahead\"\u003e\n\n\u003ca class=\"anchor d-print-none\" href=\"#looking-ahead\"\u003e\n  \u003csmall\u003e\u0026#x1F517;\u003c/small\u003e\n\u003c/a\u003e\n\nLooking Ahead\n\u003c/h2\u003e\u003cp\u003eAdopting new infrastructure inevitably involves adjustments. For Bioconductor developers, integrating with a new build and distribution system will likely require some changes to workflows, and time to become familiar with new or different package checks, build diagnostics, and binary distribution.\u003c/p\u003e\n\u003cp\u003eHowever, by gradually moving toward common infrastructure, the Bioconductor project will benefit from improvements that are being continuously developed and maintained for the broader R ecosystem. A system based on modern continuous integration (CI) will provide developers with improved tooling, and will give the core team more time to focus on community coordination and quality control, rather than on maintaining costly infrastructure. At the same time, the shared platform provided by R-universe can help to increase the visibility and accessibility of Bioconductor software to the greater R community.\u003c/p\u003e\n\u003cp\u003eWe look forward to continuing this alliance and to working with the Bioconductor community to ensure that the next generation of infrastructure supports the project for many years to come.\u003c/p\u003e\n","url":"https://ropensci.org/blog/2026/04/08/r-universe-bioc/","date_published":"2026-04-08T00:00:00+00:00"},{"id":"https://ropensci.org/blog/2026/04/02/tree-sitter-overview/","title":"A Better R Programming Experience Thanks to Tree-sitter","content_text":"\u003cp\u003eA little bit less than two years ago, building on work by Jim Hester and Kevin Ushey, Davis Vaughan completed a very impactful JavaScript file for the R community: an R grammar for the Tree-sitter parsing generator. He even got a round of applause for it during a talk at the useR! 2024 conference! So, did he get cheered for\u0026hellip; grammatical rules in a \u003ca href=\"https://github.com/r-lib/tree-sitter-r/blob/next/grammar.js\"\u003eJavaScript file\u003c/a\u003e? \u0026#x1f605;\u003c/p\u003e\n\u003cp\u003eNo, the audience was excited about the \u003cem\u003eimproved developer experience for R\u003c/em\u003e that this file unlocked. R tooling around Tree-sitter is how you get\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003ereformatting through \u003ca href=\"https://posit-dev.github.io/air/\"\u003eAir\u003c/a\u003e and linting through \u003ca href=\"https://jarl.etiennebacher.com/\"\u003eJarl\u003c/a\u003e;\u003c/li\u003e\n\u003cli\u003eauto-completion or help on hover in the \u003ca href=\"https://lionel-.github.io/slidedecks/2024-07-11-ark\"\u003ePositron IDE\u003c/a\u003e;\u003c/li\u003e\n\u003cli\u003ebetter \u003ca href=\"https://github.com/orgs/community/discussions/120397\"\u003esearch\u003c/a\u003e for R on GitHub;\u003c/li\u003e\n\u003cli\u003eand more!\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eIn this post, we\u0026rsquo;ll explain what Tree-sitter is, and how tools built on Tree-sitter can benefit your R development workflow.\u003c/p\u003e\n\u003ch2 id=\"code-parsing-what-is-tree-sitter\"\u003e\n\n\u003ca class=\"anchor d-print-none\" href=\"#code-parsing-what-is-tree-sitter\"\u003e\n  \u003csmall\u003e\u0026#x1F517;\u003c/small\u003e\n\u003c/a\u003e\n\nCode parsing: what is Tree-sitter?\n\u003c/h2\u003e\u003cp\u003e\u003ca href=\"https://tree-sitter.github.io/tree-sitter/\"\u003eTree-sitter\u003c/a\u003e is a code parsing generator written in C, with bindings existing in several languages including Rust (and R!).\u003c/p\u003e\n\u003cp\u003eLet\u0026rsquo;s rewind a little bit. What does it mean to parse code?\u003c/p\u003e\n\u003cp\u003eBasically, given a string of code like\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-r\" data-lang=\"r\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003ea\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;-\u003c/span\u003e \u003cspan class=\"nf\"\u003emean\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ex\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003ena.rm\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"kc\"\u003eTRUE\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003eHow do you know that \u003ccode\u003emean\u003c/code\u003e is a function name, \u003ccode\u003ena.rm\u003c/code\u003e an argument name, \u003ccode\u003eTRUE\u003c/code\u003e a logical? You have to \u003cem\u003eparse\u003c/em\u003e that code into what\u0026rsquo;s called a parse tree. You do that in your head when reading R code. \u0026#x1f638;\u003c/p\u003e\n\u003cp\u003eR itself can obviously parse R code, thanks to its \u003ca href=\"https://github.com/wch/r-source/blob/trunk/src/main/gram.y\"\u003egrammar\u003c/a\u003e. See for instance the \u003ca href=\"https://github.com/wch/r-source/commit/a1425adea54bcc98eef86081522b5dbb3e149cdc#diff-ba804d7fa3fa053c1f57d46369f4432cb55c9c4f69f46ae6510d0d1fcc59f382\"\u003ecommit that introduced R\u0026rsquo;s native pipe\u003c/a\u003e, which necessitated extending R\u0026rsquo;s syntax thus modifying its grammar.\u003c/p\u003e\n\u003cp\u003eYou can use \u003ca href=\"https://rdrr.io/r/base/parse.html\"\u003e\u003ccode\u003eparse()\u003c/code\u003e\u003c/a\u003e and \u003ca href=\"https://rdrr.io/r/utils/getParseData.html\"\u003e\u003ccode\u003egetParseData()\u003c/code\u003e\u003c/a\u003e to parse R code.\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\n\u003cpre class='chroma'\u003e\u003ccode class='language-r' data-lang='r'\u003e\u003cspan\u003e\u003cspan class='nf'\u003e\u003ca href='https://rdrr.io/r/base/parse.html'\u003eparse\u003c/a\u003e\u003c/span\u003e\u003cspan class='o'\u003e(\u003c/span\u003e\u003c/span\u003e\n\u003cspan\u003e  text \u003cspan class='o'\u003e=\u003c/span\u003e \u003cspan class='s'\u003e\"a \u0026lt;- mean(x, na.rm = TRUE)\"\u003c/span\u003e,\u003c/span\u003e\n\u003cspan\u003e  keep.source \u003cspan class='o'\u003e=\u003c/span\u003e \u003cspan class='kc'\u003eTRUE\u003c/span\u003e\u003c/span\u003e\n\u003cspan\u003e\u003cspan class='o'\u003e)\u003c/span\u003e \u003cspan class='o'\u003e|\u0026gt;\u003c/span\u003e\u003c/span\u003e\n\u003cspan\u003e  \u003cspan class='nf'\u003e\u003ca href='https://rdrr.io/r/utils/getParseData.html'\u003egetParseData\u003c/a\u003e\u003c/span\u003e\u003cspan class='o'\u003e(\u003c/span\u003e\u003cspan class='o'\u003e)\u003c/span\u003e\u003c/span\u003e\n\u003cspan\u003e\u003cspan class='c'\u003e#\u0026gt;    line1 col1 line2 col2 id parent                token terminal  text\u003c/span\u003e\u003c/span\u003e\n\u003cspan\u003e\u003cspan class='c'\u003e#\u0026gt; 23     1    1     1   26 23      0                 expr    FALSE      \u003c/span\u003e\u003c/span\u003e\n\u003cspan\u003e\u003cspan class='c'\u003e#\u0026gt; 1      1    1     1    1  1      3               SYMBOL     TRUE     a\u003c/span\u003e\u003c/span\u003e\n\u003cspan\u003e\u003cspan class='c'\u003e#\u0026gt; 3      1    1     1    1  3     23                 expr    FALSE      \u003c/span\u003e\u003c/span\u003e\n\u003cspan\u003e\u003cspan class='c'\u003e#\u0026gt; 2      1    3     1    4  2     23          LEFT_ASSIGN     TRUE    \u0026lt;-\u003c/span\u003e\u003c/span\u003e\n\u003cspan\u003e\u003cspan class='c'\u003e#\u0026gt; 21     1    6     1   26 21     23                 expr    FALSE      \u003c/span\u003e\u003c/span\u003e\n\u003cspan\u003e\u003cspan class='c'\u003e#\u0026gt; 4      1    6     1    9  4      6 SYMBOL_FUNCTION_CALL     TRUE  mean\u003c/span\u003e\u003c/span\u003e\n\u003cspan\u003e\u003cspan class='c'\u003e#\u0026gt; 6      1    6     1    9  6     21                 expr    FALSE      \u003c/span\u003e\u003c/span\u003e\n\u003cspan\u003e\u003cspan class='c'\u003e#\u0026gt; 5      1   10     1   10  5     21                  '('     TRUE     (\u003c/span\u003e\u003c/span\u003e\n\u003cspan\u003e\u003cspan class='c'\u003e#\u0026gt; 7      1   11     1   11  7      9               SYMBOL     TRUE     x\u003c/span\u003e\u003c/span\u003e\n\u003cspan\u003e\u003cspan class='c'\u003e#\u0026gt; 9      1   11     1   11  9     21                 expr    FALSE      \u003c/span\u003e\u003c/span\u003e\n\u003cspan\u003e\u003cspan class='c'\u003e#\u0026gt; 8      1   12     1   12  8     21                  ','     TRUE     ,\u003c/span\u003e\u003c/span\u003e\n\u003cspan\u003e\u003cspan class='c'\u003e#\u0026gt; 13     1   14     1   18 13     21           SYMBOL_SUB     TRUE na.rm\u003c/span\u003e\u003c/span\u003e\n\u003cspan\u003e\u003cspan class='c'\u003e#\u0026gt; 14     1   20     1   20 14     21               EQ_SUB     TRUE     =\u003c/span\u003e\u003c/span\u003e\n\u003cspan\u003e\u003cspan class='c'\u003e#\u0026gt; 15     1   22     1   25 15     16            NUM_CONST     TRUE  TRUE\u003c/span\u003e\u003c/span\u003e\n\u003cspan\u003e\u003cspan class='c'\u003e#\u0026gt; 16     1   22     1   25 16     21                 expr    FALSE      \u003c/span\u003e\u003c/span\u003e\n\u003cspan\u003e\u003cspan class='c'\u003e#\u0026gt; 17     1   26     1   26 17     21                  ')'     TRUE     )\u003c/span\u003e\u003c/span\u003e\n\u003cspan\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\n\u003c/div\u003e\n\u003cp\u003eOr you could transform that same data into XML using Gábor Csárdi\u0026rsquo;s \u003ca href=\"https://r-lib.github.io/xmlparsedata/\"\u003e{xmlparsedata}\u003c/a\u003e:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\n\u003cpre class='chroma'\u003e\u003ccode class='language-r' data-lang='r'\u003e\u003cspan\u003e\u003cspan class='nf'\u003e\u003ca href='https://rdrr.io/r/base/parse.html'\u003eparse\u003c/a\u003e\u003c/span\u003e\u003cspan class='o'\u003e(\u003c/span\u003e\u003c/span\u003e\n\u003cspan\u003e  text \u003cspan class='o'\u003e=\u003c/span\u003e \u003cspan class='s'\u003e\"a \u0026lt;- mean(x, na.rm = TRUE)\"\u003c/span\u003e,\u003c/span\u003e\n\u003cspan\u003e  keep.source \u003cspan class='o'\u003e=\u003c/span\u003e \u003cspan class='kc'\u003eTRUE\u003c/span\u003e\u003c/span\u003e\n\u003cspan\u003e\u003cspan class='o'\u003e)\u003c/span\u003e \u003cspan class='o'\u003e|\u0026gt;\u003c/span\u003e\u003c/span\u003e\n\u003cspan\u003e  \u003cspan class='nf'\u003exmlparsedata\u003c/span\u003e\u003cspan class='nf'\u003e::\u003c/span\u003e\u003cspan class='nf'\u003e\u003ca href='https://rdrr.io/pkg/xmlparsedata/man/xml_parse_data.html'\u003exml_parse_data\u003c/a\u003e\u003c/span\u003e\u003cspan class='o'\u003e(\u003c/span\u003epretty \u003cspan class='o'\u003e=\u003c/span\u003e \u003cspan class='kc'\u003eTRUE\u003c/span\u003e\u003cspan class='o'\u003e)\u003c/span\u003e \u003cspan class='o'\u003e|\u0026gt;\u003c/span\u003e\u003c/span\u003e\n\u003cspan\u003e  \u003cspan class='nf'\u003exml2\u003c/span\u003e\u003cspan class='nf'\u003e::\u003c/span\u003e\u003cspan class='nf'\u003e\u003ca href='http://xml2.r-lib.org/reference/read_xml.html'\u003eread_xml\u003c/a\u003e\u003c/span\u003e\u003cspan class='o'\u003e(\u003c/span\u003e\u003cspan class='o'\u003e)\u003c/span\u003e \u003cspan class='o'\u003e|\u0026gt;\u003c/span\u003e\u003c/span\u003e\n\u003cspan\u003e  \u003cspan class='nf'\u003e\u003ca href='https://rdrr.io/r/base/character.html'\u003eas.character\u003c/a\u003e\u003c/span\u003e\u003cspan class='o'\u003e(\u003c/span\u003e\u003cspan class='o'\u003e)\u003c/span\u003e \u003cspan class='o'\u003e|\u0026gt;\u003c/span\u003e\u003c/span\u003e\n\u003cspan\u003e  \u003cspan class='nf'\u003e\u003ca href='https://rdrr.io/r/base/cat.html'\u003ecat\u003c/a\u003e\u003c/span\u003e\u003cspan class='o'\u003e(\u003c/span\u003e\u003cspan class='o'\u003e)\u003c/span\u003e\u003c/span\u003e\n\u003cspan\u003e\u003cspan class='c'\u003e#\u0026gt; \u0026lt;?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?\u0026gt;\u003c/span\u003e\u003c/span\u003e\n\u003cspan\u003e\u003cspan class='c'\u003e#\u0026gt; \u0026lt;exprlist\u0026gt;\u003c/span\u003e\u003c/span\u003e\n\u003cspan\u003e\u003cspan class='c'\u003e#\u0026gt;   \u0026lt;expr line1=\"1\" col1=\"1\" line2=\"1\" col2=\"26\" start=\"28\" end=\"53\"\u0026gt;\u003c/span\u003e\u003c/span\u003e\n\u003cspan\u003e\u003cspan class='c'\u003e#\u0026gt;     \u0026lt;expr line1=\"1\" col1=\"1\" line2=\"1\" col2=\"1\" start=\"28\" end=\"28\"\u0026gt;\u003c/span\u003e\u003c/span\u003e\n\u003cspan\u003e\u003cspan class='c'\u003e#\u0026gt;       \u0026lt;SYMBOL line1=\"1\" col1=\"1\" line2=\"1\" col2=\"1\" start=\"28\" end=\"28\"\u0026gt;a\u0026lt;/SYMBOL\u0026gt;\u003c/span\u003e\u003c/span\u003e\n\u003cspan\u003e\u003cspan class='c'\u003e#\u0026gt;     \u0026lt;/expr\u0026gt;\u003c/span\u003e\u003c/span\u003e\n\u003cspan\u003e\u003cspan class='c'\u003e#\u0026gt;     \u0026lt;LEFT_ASSIGN line1=\"1\" col1=\"3\" line2=\"1\" col2=\"4\" start=\"30\" end=\"31\"\u0026gt;\u0026amp;lt;-\u0026lt;/LEFT_ASSIGN\u0026gt;\u003c/span\u003e\u003c/span\u003e\n\u003cspan\u003e\u003cspan class='c'\u003e#\u0026gt;     \u0026lt;expr line1=\"1\" col1=\"6\" line2=\"1\" col2=\"26\" start=\"33\" end=\"53\"\u0026gt;\u003c/span\u003e\u003c/span\u003e\n\u003cspan\u003e\u003cspan class='c'\u003e#\u0026gt;       \u0026lt;expr line1=\"1\" col1=\"6\" line2=\"1\" col2=\"9\" start=\"33\" end=\"36\"\u0026gt;\u003c/span\u003e\u003c/span\u003e\n\u003cspan\u003e\u003cspan class='c'\u003e#\u0026gt;         \u0026lt;SYMBOL_FUNCTION_CALL line1=\"1\" col1=\"6\" line2=\"1\" col2=\"9\" start=\"33\" end=\"36\"\u0026gt;mean\u0026lt;/SYMBOL_FUNCTION_CALL\u0026gt;\u003c/span\u003e\u003c/span\u003e\n\u003cspan\u003e\u003cspan class='c'\u003e#\u0026gt;       \u0026lt;/expr\u0026gt;\u003c/span\u003e\u003c/span\u003e\n\u003cspan\u003e\u003cspan class='c'\u003e#\u0026gt;       \u0026lt;OP-LEFT-PAREN line1=\"1\" col1=\"10\" line2=\"1\" col2=\"10\" start=\"37\" end=\"37\"\u0026gt;(\u0026lt;/OP-LEFT-PAREN\u0026gt;\u003c/span\u003e\u003c/span\u003e\n\u003cspan\u003e\u003cspan class='c'\u003e#\u0026gt;       \u0026lt;expr line1=\"1\" col1=\"11\" line2=\"1\" col2=\"11\" start=\"38\" end=\"38\"\u0026gt;\u003c/span\u003e\u003c/span\u003e\n\u003cspan\u003e\u003cspan class='c'\u003e#\u0026gt;         \u0026lt;SYMBOL line1=\"1\" col1=\"11\" line2=\"1\" col2=\"11\" start=\"38\" end=\"38\"\u0026gt;x\u0026lt;/SYMBOL\u0026gt;\u003c/span\u003e\u003c/span\u003e\n\u003cspan\u003e\u003cspan class='c'\u003e#\u0026gt;       \u0026lt;/expr\u0026gt;\u003c/span\u003e\u003c/span\u003e\n\u003cspan\u003e\u003cspan class='c'\u003e#\u0026gt;       \u0026lt;OP-COMMA line1=\"1\" col1=\"12\" line2=\"1\" col2=\"12\" start=\"39\" end=\"39\"\u0026gt;,\u0026lt;/OP-COMMA\u0026gt;\u003c/span\u003e\u003c/span\u003e\n\u003cspan\u003e\u003cspan class='c'\u003e#\u0026gt;       \u0026lt;SYMBOL_SUB line1=\"1\" col1=\"14\" line2=\"1\" col2=\"18\" start=\"41\" end=\"45\"\u0026gt;na.rm\u0026lt;/SYMBOL_SUB\u0026gt;\u003c/span\u003e\u003c/span\u003e\n\u003cspan\u003e\u003cspan class='c'\u003e#\u0026gt;       \u0026lt;EQ_SUB line1=\"1\" col1=\"20\" line2=\"1\" col2=\"20\" start=\"47\" end=\"47\"\u0026gt;=\u0026lt;/EQ_SUB\u0026gt;\u003c/span\u003e\u003c/span\u003e\n\u003cspan\u003e\u003cspan class='c'\u003e#\u0026gt;       \u0026lt;expr line1=\"1\" col1=\"22\" line2=\"1\" col2=\"25\" start=\"49\" end=\"52\"\u0026gt;\u003c/span\u003e\u003c/span\u003e\n\u003cspan\u003e\u003cspan class='c'\u003e#\u0026gt;         \u0026lt;NUM_CONST line1=\"1\" col1=\"22\" line2=\"1\" col2=\"25\" start=\"49\" end=\"52\"\u0026gt;TRUE\u0026lt;/NUM_CONST\u0026gt;\u003c/span\u003e\u003c/span\u003e\n\u003cspan\u003e\u003cspan class='c'\u003e#\u0026gt;       \u0026lt;/expr\u0026gt;\u003c/span\u003e\u003c/span\u003e\n\u003cspan\u003e\u003cspan class='c'\u003e#\u0026gt;       \u0026lt;OP-RIGHT-PAREN line1=\"1\" col1=\"26\" line2=\"1\" col2=\"26\" start=\"53\" end=\"53\"\u0026gt;)\u0026lt;/OP-RIGHT-PAREN\u0026gt;\u003c/span\u003e\u003c/span\u003e\n\u003cspan\u003e\u003cspan class='c'\u003e#\u0026gt;     \u0026lt;/expr\u0026gt;\u003c/span\u003e\u003c/span\u003e\n\u003cspan\u003e\u003cspan class='c'\u003e#\u0026gt;   \u0026lt;/expr\u0026gt;\u003c/span\u003e\u003c/span\u003e\n\u003cspan\u003e\u003cspan class='c'\u003e#\u0026gt; \u0026lt;/exprlist\u0026gt;\u003c/span\u003e\u003c/span\u003e\n\u003cspan\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\n\u003c/div\u003e\n\u003cp\u003eIn both cases, you recognize words such as \u003ccode\u003eLEFT_ASSIGN\u003c/code\u003e or \u003ccode\u003eSYMBOL_FUNCTION_CALL\u003c/code\u003e. Parsing is an essential step before the code is actually executed, but parsed code can also be used for other purposes, such as analyzing code without brittle regular expressions (does it call a particular \u003ca href=\"https://nrennie.rbind.io/blog/how-to-make-your-own-rstats-wrapped/\"\u003efunction\u003c/a\u003e?), navigating code (going from a function call to the definition of that function), or modifying code (replacing all occurrences of a function with another one).\u003c/p\u003e\n\u003cp\u003eNow, Tree-sitter performs this same code parsing but \u003cstrong\u003efaster\u003c/strong\u003e especially thanks to its support of incremental parsing \u0026ndash; which is key to updating the syntax tree as you are typing in your editor for instance! Tree-sitter is agnostic in that it can parse any code as long as there is a grammar for it (think, Rosetta Stone plugins). It\u0026rsquo;s been used for many languages which means many tools have been built around it.\u003c/p\u003e\n\u003cp\u003eTo have Tree-sitter \u0026ldquo;learn\u0026rdquo; a new language you need to give it a file containing the definition of the syntax of that language, what\u0026rsquo;s called a \u003cem\u003egrammar\u003c/em\u003e. This is where the aforementioned JavaScript file by Davis Vaughan and collaborators comes into play! The \u003ca href=\"https://github.com/r-lib/tree-sitter-r\"\u003etreesitter-r repo\u003c/a\u003e, which provides a translation of the R grammar in the format expected by Tree-sitter, is the base of all tools presented in this post which use R code as their input.\u003c/p\u003e\n\u003cp\u003eHere\u0026rsquo;s how to use the {treesitter} R package for the same code as earlier. The {treesitter} R package allows us to use Tree-sitter from R. To parse R code with it, we need the \u003ccode\u003elanguage()\u003c/code\u003e function from {treesitter.r}\u003csup id=\"fnref:1\"\u003e\u003ca href=\"#fn:1\" class=\"footnote-ref\" role=\"doc-noteref\"\u003e1\u003c/a\u003e\u003c/sup\u003e.\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\n\u003cpre class='chroma'\u003e\u003ccode class='language-r' data-lang='r'\u003e\u003cspan\u003e\u003cspan class='kr'\u003e\u003ca href='https://rdrr.io/r/base/library.html'\u003elibrary\u003c/a\u003e\u003c/span\u003e\u003cspan class='o'\u003e(\u003c/span\u003e\u003cspan class='nv'\u003e\u003ca href='https://github.com/DavisVaughan/r-tree-sitter'\u003etreesitter\u003c/a\u003e\u003c/span\u003e\u003cspan class='o'\u003e)\u003c/span\u003e\u003c/span\u003e\n\u003cspan\u003e\u003cspan class='c'\u003e#\u0026gt; \u003c/span\u003e\u003c/span\u003e\n\u003cspan\u003e\u003cspan class='c'\u003e#\u0026gt; Attaching package: 'treesitter'\u003c/span\u003e\u003c/span\u003e\n\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003cspan class='c'\u003e#\u0026gt; The following object is masked from 'package:base':\u003c/span\u003e\u003c/span\u003e\n\u003cspan\u003e\u003cspan class='c'\u003e#\u0026gt; \u003c/span\u003e\u003c/span\u003e\n\u003cspan\u003e\u003cspan class='c'\u003e#\u0026gt;     range\u003c/span\u003e\u003c/span\u003e\n\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003cspan class='nv'\u003elanguage\u003c/span\u003e \u003cspan class='o'\u003e\u0026lt;-\u003c/span\u003e \u003cspan class='nf'\u003etreesitter.r\u003c/span\u003e\u003cspan class='nf'\u003e::\u003c/span\u003e\u003cspan class='nf'\u003e\u003ca href='https://rdrr.io/pkg/treesitter.r/man/language.html'\u003elanguage\u003c/a\u003e\u003c/span\u003e\u003cspan class='o'\u003e(\u003c/span\u003e\u003cspan class='o'\u003e)\u003c/span\u003e\u003c/span\u003e\n\u003cspan\u003e\u003cspan class='nv'\u003eparser\u003c/span\u003e \u003cspan class='o'\u003e\u0026lt;-\u003c/span\u003e \u003cspan class='nf'\u003e\u003ca href='https://davisvaughan.github.io/r-tree-sitter/reference/parser.html'\u003eparser\u003c/a\u003e\u003c/span\u003e\u003cspan class='o'\u003e(\u003c/span\u003e\u003cspan class='nv'\u003elanguage\u003c/span\u003e\u003cspan class='o'\u003e)\u003c/span\u003e\u003c/span\u003e\n\u003cspan\u003e\u003cspan class='nv'\u003etext\u003c/span\u003e \u003cspan class='o'\u003e\u0026lt;-\u003c/span\u003e \u003cspan class='s'\u003e\"a \u0026lt;- mean(x, na.rm = TRUE)\"\u003c/span\u003e\u003c/span\u003e\n\u003cspan\u003e\u003cspan class='nf'\u003e\u003ca href='https://davisvaughan.github.io/r-tree-sitter/reference/parser-parse.html'\u003eparser_parse\u003c/a\u003e\u003c/span\u003e\u003cspan class='o'\u003e(\u003c/span\u003e\u003cspan class='nv'\u003eparser\u003c/span\u003e, \u003cspan class='nv'\u003etext\u003c/span\u003e\u003cspan class='o'\u003e)\u003c/span\u003e\u003c/span\u003e\n\u003cspan\u003e\u003cspan class='c'\u003e#\u0026gt; \u0026lt;tree_sitter_tree\u0026gt;\u003c/span\u003e\u003c/span\u003e\n\u003cspan\u003e\u003cspan class='c'\u003e#\u0026gt; \u003c/span\u003e\u003c/span\u003e\n\u003cspan\u003e\u003cspan class='c'\u003e#\u0026gt; ── Text ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────\u003c/span\u003e\u003c/span\u003e\n\u003cspan\u003e\u003cspan class='c'\u003e#\u0026gt; a \u0026lt;- mean(x, na.rm = TRUE)\u003c/span\u003e\u003c/span\u003e\n\u003cspan\u003e\u003cspan class='c'\u003e#\u0026gt; \u003c/span\u003e\u003c/span\u003e\n\u003cspan\u003e\u003cspan class='c'\u003e#\u0026gt; ── S-Expression ────────────────────────────────────────────────────────────────────────────────────────────────────────────────\u003c/span\u003e\u003c/span\u003e\n\u003cspan\u003e\u003cspan class='c'\u003e#\u0026gt; \u003cspan style='color: #0000BB;'\u003e(\u003c/span\u003eprogram \u003cspan style='color: #555555;'\u003e[(0, 0), (0, 26)]\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\n\u003cspan\u003e\u003cspan class='c'\u003e#\u0026gt;   \u003cspan style='color: #00BB00;'\u003e(\u003c/span\u003ebinary_operator \u003cspan style='color: #555555;'\u003e[(0, 0), (0, 26)]\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\n\u003cspan\u003e\u003cspan class='c'\u003e#\u0026gt;     lhs: \u003cspan style='color: #BB0000;'\u003e(\u003c/span\u003eidentifier \u003cspan style='color: #555555;'\u003e[(0, 0), (0, 1)]\u003c/span\u003e\u003cspan style='color: #BB0000;'\u003e)\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\n\u003cspan\u003e\u003cspan class='c'\u003e#\u0026gt;     operator: \"\u0026lt;-\" \u003cspan style='color: #555555;'\u003e[(0, 2), (0, 4)]\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\n\u003cspan\u003e\u003cspan class='c'\u003e#\u0026gt;     rhs: \u003cspan style='color: #BB0000;'\u003e(\u003c/span\u003ecall \u003cspan style='color: #555555;'\u003e[(0, 5), (0, 26)]\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\n\u003cspan\u003e\u003cspan class='c'\u003e#\u0026gt;       function: \u003cspan style='color: #00BBBB;'\u003e(\u003c/span\u003eidentifier \u003cspan style='color: #555555;'\u003e[(0, 5), (0, 9)]\u003c/span\u003e\u003cspan style='color: #00BBBB;'\u003e)\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\n\u003cspan\u003e\u003cspan class='c'\u003e#\u0026gt;       arguments: \u003cspan style='color: #00BBBB;'\u003e(\u003c/span\u003earguments \u003cspan style='color: #555555;'\u003e[(0, 9), (0, 26)]\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\n\u003cspan\u003e\u003cspan class='c'\u003e#\u0026gt;         open: \"(\" \u003cspan style='color: #555555;'\u003e[(0, 9), (0, 10)]\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\n\u003cspan\u003e\u003cspan class='c'\u003e#\u0026gt;         argument: \u003cspan style='color: #BBBB00;'\u003e(\u003c/span\u003eargument \u003cspan style='color: #555555;'\u003e[(0, 10), (0, 11)]\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\n\u003cspan\u003e\u003cspan class='c'\u003e#\u0026gt;           value: \u003cspan style='color: #BB00BB;'\u003e(\u003c/span\u003eidentifier \u003cspan style='color: #555555;'\u003e[(0, 10), (0, 11)]\u003c/span\u003e\u003cspan style='color: #BB00BB;'\u003e)\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\n\u003cspan\u003e\u003cspan class='c'\u003e#\u0026gt;         \u003cspan style='color: #BBBB00;'\u003e)\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\n\u003cspan\u003e\u003cspan class='c'\u003e#\u0026gt;         \u003cspan style='color: #BBBB00;'\u003e(\u003c/span\u003ecomma \u003cspan style='color: #555555;'\u003e[(0, 11), (0, 12)]\u003c/span\u003e\u003cspan style='color: #BBBB00;'\u003e)\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\n\u003cspan\u003e\u003cspan class='c'\u003e#\u0026gt;         argument: \u003cspan style='color: #BBBB00;'\u003e(\u003c/span\u003eargument \u003cspan style='color: #555555;'\u003e[(0, 13), (0, 25)]\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\n\u003cspan\u003e\u003cspan class='c'\u003e#\u0026gt;           name: \u003cspan style='color: #BB00BB;'\u003e(\u003c/span\u003eidentifier \u003cspan style='color: #555555;'\u003e[(0, 13), (0, 18)]\u003c/span\u003e\u003cspan style='color: #BB00BB;'\u003e)\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\n\u003cspan\u003e\u003cspan class='c'\u003e#\u0026gt;           \"=\" \u003cspan style='color: #555555;'\u003e[(0, 19), (0, 20)]\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\n\u003cspan\u003e\u003cspan class='c'\u003e#\u0026gt;           value: \u003cspan style='color: #BB00BB;'\u003e(\u003c/span\u003etrue \u003cspan style='color: #555555;'\u003e[(0, 21), (0, 25)]\u003c/span\u003e\u003cspan style='color: #BB00BB;'\u003e)\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\n\u003cspan\u003e\u003cspan class='c'\u003e#\u0026gt;         \u003cspan style='color: #BBBB00;'\u003e)\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\n\u003cspan\u003e\u003cspan class='c'\u003e#\u0026gt;         close: \")\" \u003cspan style='color: #555555;'\u003e[(0, 25), (0, 26)]\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\n\u003cspan\u003e\u003cspan class='c'\u003e#\u0026gt;       \u003cspan style='color: #00BBBB;'\u003e)\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\n\u003cspan\u003e\u003cspan class='c'\u003e#\u0026gt;     \u003cspan style='color: #BB0000;'\u003e)\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\n\u003cspan\u003e\u003cspan class='c'\u003e#\u0026gt;   \u003cspan style='color: #00BB00;'\u003e)\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\n\u003cspan\u003e\u003cspan class='c'\u003e#\u0026gt; \u003cspan style='color: #0000BB;'\u003e)\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\n\u003cspan\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\n\u003c/div\u003e\n\u003cp\u003eTree-sitter is the workhorse of many tools, that are mentioned in the diagram below. All of them are dependent on tree-sitter and the R grammar provided to it. Some of them are command-line interfaces (CLIs), while others are R packages.\u003c/p\u003e\n\u003cfigure\u003e\u003cimg src=\"/blog/2026/04/02/tree-sitter-overview/tree-sitter.png\"\n    alt=\"Diagram of Tree-sitter tooling for R. At the center is Tree-sitter especially its Rust bindings and the R grammar for treesitter. At the top is the input, R scripts. At the bottom from treesitter is the treesitter R package,; ast-grep that is used by astgrepr which is used by flir and that is used by the CLAUDE.md instructions for parsing code; Air that is used by Jarl; Ark that is used by the Positron IDE; R code browsing on GitHub.\"\u003e\n\u003c/figure\u003e\n\n\u003ch2 id=\"browsing-code-interactively-positron-ide-github\"\u003e\n\n\u003ca class=\"anchor d-print-none\" href=\"#browsing-code-interactively-positron-ide-github\"\u003e\n  \u003csmall\u003e\u0026#x1F517;\u003c/small\u003e\n\u003c/a\u003e\n\nBrowsing code interactively: Positron IDE, GitHub\n\u003c/h2\u003e\u003cp\u003eThe real reason why the audience applauded Davis Vaughan is that he explained how the R grammar for Tree-sitter had been \u003ca href=\"https://github.com/orgs/community/discussions/120397\"\u003edeployed to GitHub\u003c/a\u003e so that we get almost as good experience browsing R code on GitHub as browsing, say, JS code. If we search for a function name in a repository for instance, its definition will be indicated in the search results. See \u003ca href=\"https://www.youtube.com/watch?v=Gm0ikRBAfwc\"\u003eDavis\u0026rsquo; slides\u003c/a\u003e (also available in \u003ca href=\"https://github.com/DavisVaughan/2024-07-09_useR-2024\"\u003ePDF\u003c/a\u003e), or refer to the video below showing how typing \u003ccode\u003evetiver_model\u003c/code\u003e in the search bar from the R vetiver repo makes the function definition the first result, on which one can click to land into the definition.\u003c/p\u003e\n\u003cvideo controls preload=\"auto\" width=\"100%\"  playsinline class=\"html-video\"\u003e\n    \u003csource src=\"/blog/2026/04/02/tree-sitter-overview/searching-for-vetiver-model-r-new.mp4\" type=\"video/mp4\"\u003e\n  \u003cspan\u003e\u003c/span\u003e\n\u003c/video\u003e\n\u003cp\u003eAlso very useful is the use of Tree-sitter by \u003ca href=\"https://github.com/posit-dev/ark\"\u003eArk\u003c/a\u003e, the R kernel \u003ca href=\"https://lionel-.github.io/slidedecks/2024-07-11-ark/#/language-server-protocol-1\"\u003eused in the Positron IDE\u003c/a\u003e. Ark is how you get autocompletion and help on hover in Positron. The video below shows how you can extend the selection to further steps of a pipeline in Positron.\u003c/p\u003e\n\u003cvideo controls preload=\"auto\" width=\"100%\"  playsinline class=\"html-video\"\u003e\n    \u003csource src=\"/blog/2026/04/02/tree-sitter-overview/expand-selection-2.mp4\" type=\"video/mp4\"\u003e\n  \u003cspan\u003e\u003c/span\u003e\n\u003c/video\u003e\n\u003cp\u003eThis use case of Tree-sitter is also featured in \u003ca href=\"https://www.youtube.com/watch?v=Gm0ikRBAfwc\"\u003eDavis\u0026rsquo; slides\u003c/a\u003e. See also Lionel Henry\u0026rsquo;s and Davis Vaughan\u0026rsquo;s talk about Ark at \u003ca href=\"https://youtu.be/8uRcB34Hhsw?si=UeWqIi9PtEOWqRsp\u0026amp;t=2109\"\u003eposit conf 2024\u003c/a\u003e, especially the part about \u003ca href=\"https://youtu.be/8uRcB34Hhsw?si=GBqntC6tW7D2WhBN\u0026amp;t=2455\"\u003ecode assistance\u003c/a\u003e.\u003c/p\u003e\n\u003cp\u003eOther development environments such as \u003ca href=\"https://lists.gnu.org/archive/html/emacs-devel/2022-11/msg01443.html\"\u003eEmacs\u003c/a\u003e also have support for Tree-sitter.\u003c/p\u003e\n\u003ch2 id=\"searchingbrowsing-code\"\u003e\n\n\u003ca class=\"anchor d-print-none\" href=\"#searchingbrowsing-code\"\u003e\n  \u003csmall\u003e\u0026#x1F517;\u003c/small\u003e\n\u003c/a\u003e\n\nSearching/browsing code\n\u003c/h2\u003e\u003cp\u003eYou can parse and search R code using the {treesitter} R package and \u003ca href=\"https://tree-sitter.github.io/tree-sitter/4-code-navigation.html\"\u003etreesitter query syntax\u003c/a\u003e. The {treesitter} R package is a dependency of the \u003ca href=\"https://simonpcouch.github.io/gander/\"\u003e{gander} package\u003c/a\u003e by Simon Couch, that is meant to be used for a better experience with LLMs when writing R code. Another use case of the {treesitter} R package is the {igraph.r2cdocs} \u003ca href=\"https://roxygen2.r-lib.org/dev/articles/extending.html\"\u003eextension\u003c/a\u003e to {roxygen2} for the {igraph} package, that \u003ca href=\"https://github.com/igraph/igraph.r2cdocs/blob/6be2a327a18deb823302caeab8b60a916f6fac62/R/roxygen.R#L119\"\u003eparses all of igraph R code\u003c/a\u003e to then be able to identify, for each exported function, whether it (in)directly calls a function whose name ends with \u003ccode\u003e_impl\u003c/code\u003e, indicating a wrapper to a C igraph function whose docs can be then be linked from the manual of the R function.\u003c/p\u003e\n\u003cp\u003eThe {pkgdepends} package calls Tree-sitter (\u003ca href=\"https://github.com/r-lib/pkgdepends/blob/main/src/tree-sitter.c\"\u003eC\u003c/a\u003e) to detect \u003ca href=\"https://github.com/r-lib/pkgdepends/blob/634661a7d91b41476fd1ab653fe3087a6e40b8a9/R/scan-deps.R#L340\"\u003edependencies in files\u003c/a\u003e. Below we run it on the source of the \u003ca href=\"https://docs.ropensci.org/saperlipopette/\"\u003esaperlipopette R package\u003c/a\u003e.\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\n\u003cpre class='chroma'\u003e\u003ccode class='language-r' data-lang='r'\u003e\u003cspan\u003e\u003cspan class='nf'\u003epkgdepends\u003c/span\u003e\u003cspan class='nf'\u003e::\u003c/span\u003e\u003cspan class='nf'\u003e\u003ca href='https://r-lib.github.io/pkgdepends/reference/scan_deps.html'\u003escan_deps\u003c/a\u003e\u003c/span\u003e\u003cspan class='o'\u003e(\u003c/span\u003e\u003c/span\u003e\n\u003cspan\u003e  \u003cspan class='s'\u003e\"../../../../../CHAMPIONS/saperlipopette\"\u003c/span\u003e,\u003c/span\u003e\n\u003cspan\u003e  \u003cspan class='s'\u003e\"../../../../../CHAMPIONS\"\u003c/span\u003e\u003c/span\u003e\n\u003cspan\u003e\u003cspan class='o'\u003e)\u003c/span\u003e\u003c/span\u003e\n\u003cspan\u003e\u003cspan class='c'\u003e#\u0026gt; \u003c/span\u003e\u003c/span\u003e\n\u003cspan\u003e\u003cspan class='c'\u003e#\u0026gt; \u003cspan style='color: #BBBB00;'\u003eDependencies:\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\n\u003cspan\u003e\u003cspan class='c'\u003e#\u0026gt; \u003cspan style='color: #555555;'\u003e+ \u003c/span\u003e\u003cspan style='color: #0000BB;'\u003ebrio          \u003c/span\u003e\u003cspan style='color: #555555;'\u003e @ R/blame.R, R/check-editor.R, R/clean-dir.R, R/committed-to-main.R, R/committed-to-wrong-branch.R, R/conflict…\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\n\u003cspan\u003e\u003cspan class='c'\u003e#\u0026gt; \u003cspan style='color: #555555;'\u003e+ \u003c/span\u003e\u003cspan style='color: #0000BB;'\u003ecli           \u003c/span\u003e\u003cspan style='color: #555555;'\u003e @ inst/exo_bisect-Rprofile.en.R, inst/exo_bisect-Rprofile.es.R, inst/exo_bisect-Rprofile.fr.R, inst/exo_blame-…\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\n\u003cspan\u003e\u003cspan class='c'\u003e#\u0026gt; \u003cspan style='color: #555555;'\u003e+ \u003c/span\u003e\u003cspan style='color: #0000BB;'\u003edevtools      \u003c/span\u003e\u003cspan style='color: #555555;'\u003e @ saperlipopette.Rproj\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\n\u003cspan\u003e\u003cspan class='c'\u003e#\u0026gt; \u003cspan style='color: #555555;'\u003e+ \u003c/span\u003e\u003cspan style='color: #0000BB;'\u003efs            \u003c/span\u003e\u003cspan style='color: #555555;'\u003e @ R/blame.R, R/check-editor.R, R/clean-dir.R, R/committed-to-main.R, R/committed-to-wrong-branch.R, R/conflict…\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\n\u003cspan\u003e\u003cspan class='c'\u003e#\u0026gt; \u003cspan style='color: #555555;'\u003e+ \u003c/span\u003e\u003cspan style='color: #0000BB;'\u003egert          \u003c/span\u003e\u003cspan style='color: #555555;'\u003e @ inst/exo_check_editor-Rprofile.en.R, inst/exo_check_editor-Rprofile.es.R, inst/exo_check_editor-Rprofile.fr.…\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\n\u003cspan\u003e\u003cspan class='c'\u003e#\u0026gt; \u003cspan style='color: #555555;'\u003e+ \u003c/span\u003e\u003cspan style='color: #0000BB;'\u003eknitr         \u003c/span\u003e\u003cspan style='color: #555555;'\u003e @ README.Rmd\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\n\u003cspan\u003e\u003cspan class='c'\u003e#\u0026gt; \u003cspan style='color: #555555;'\u003e+ \u003c/span\u003e\u003cspan style='color: #0000BB;'\u003eparsedate     \u003c/span\u003e\u003cspan style='color: #555555;'\u003e @ R/utils-git.R\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\n\u003cspan\u003e\u003cspan class='c'\u003e#\u0026gt; \u003cspan style='color: #555555;'\u003e+ \u003c/span\u003e\u003cspan style='color: #0000BB;'\u003epurrr         \u003c/span\u003e\u003cspan style='color: #555555;'\u003e @ R/create-all.R, R/debug.R, R/log-deleted-file.R, R/log-deleted-line.R, R/revparse.R, R/roxygen2.R, R/worktre…\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\n\u003cspan\u003e\u003cspan class='c'\u003e#\u0026gt; \u003cspan style='color: #555555;'\u003e+ \u003c/span\u003e\u003cspan style='color: #0000BB;'\u003erlang         \u003c/span\u003e\u003cspan style='color: #555555;'\u003e @ R/create-all.R, R/roxygen2.R, R/utils-fs.R, R/utils-usethis.R, R/zzz.R\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\n\u003cspan\u003e\u003cspan class='c'\u003e#\u0026gt; \u003cspan style='color: #555555;'\u003e+ \u003c/span\u003e\u003cspan style='color: #0000BB;'\u003ermarkdown     \u003c/span\u003e\u003cspan style='color: #555555;'\u003e @ README.Rmd, vignettes/saperlipopette.qmd\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\n\u003cspan\u003e\u003cspan class='c'\u003e#\u0026gt; \u003cspan style='color: #555555;'\u003e+ \u003c/span\u003e\u003cspan style='color: #0000BB;'\u003eroxygen2      \u003c/span\u003e\u003cspan style='color: #555555;'\u003e @ R/roxygen2.R, saperlipopette.Rproj\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\n\u003cspan\u003e\u003cspan class='c'\u003e#\u0026gt; \u003cspan style='color: #555555;'\u003e+ \u003c/span\u003e\u003cspan style='color: #0000BB;'\u003esaperlipopette\u003c/span\u003e\u003cspan style='color: #555555;'\u003e @ README.Rmd, vignettes/saperlipopette.qmd\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\n\u003cspan\u003e\u003cspan class='c'\u003e#\u0026gt; \u003cspan style='color: #555555;'\u003e+ \u003c/span\u003e\u003cspan style='color: #0000BB;'\u003etibble        \u003c/span\u003e\u003cspan style='color: #555555;'\u003e @ R/roxygen2.R\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\n\u003cspan\u003e\u003cspan class='c'\u003e#\u0026gt; \u003cspan style='color: #555555;'\u003e+ \u003c/span\u003e\u003cspan style='color: #0000BB;'\u003eusethis       \u003c/span\u003e\u003cspan style='color: #555555;'\u003e @ R/blame.R, R/check-editor.R, R/clean-dir.R, R/committed-to-main.R, R/committed-to-wrong-branch.R, R/conflict…\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\n\u003cspan\u003e\u003cspan class='c'\u003e#\u0026gt; \u003cspan style='color: #555555;'\u003e+ \u003c/span\u003e\u003cspan style='color: #0000BB;'\u003evctrs         \u003c/span\u003e\u003cspan style='color: #555555;'\u003e @ R/roxygen2.R\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\n\u003cspan\u003e\u003cspan class='c'\u003e#\u0026gt; \u003cspan style='color: #555555;'\u003e+ \u003c/span\u003e\u003cspan style='color: #0000BB;'\u003ewithr         \u003c/span\u003e\u003cspan style='color: #555555;'\u003e @ R/blame.R, R/check-editor.R, R/clean-dir.R, R/committed-to-main.R, R/committed-to-wrong-branch.R, R/conflict…\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\n\u003cspan\u003e\u003cspan class='c'\u003e#\u0026gt; \u003c/span\u003e\u003c/span\u003e\n\u003cspan\u003e\u003cspan class='c'\u003e#\u0026gt; \u003cspan style='color: #BBBB00;'\u003eTest dependencies:\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\n\u003cspan\u003e\u003cspan class='c'\u003e#\u0026gt; \u003cspan style='color: #555555;'\u003e+ \u003c/span\u003e\u003cspan style='color: #0000BB;'\u003efs            \u003c/span\u003e\u003cspan style='color: #555555;'\u003e @ tests/testthat/test-blame.R, tests/testthat/test-check-editor.R, tests/testthat/test-clean-dir.R, tests/test…\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\n\u003cspan\u003e\u003cspan class='c'\u003e#\u0026gt; \u003cspan style='color: #555555;'\u003e+ \u003c/span\u003e\u003cspan style='color: #0000BB;'\u003egert          \u003c/span\u003e\u003cspan style='color: #555555;'\u003e @ tests/testthat/test-blame.R, tests/testthat/test-clean-dir.R, tests/testthat/test-committed-to-main.R, tests…\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\n\u003cspan\u003e\u003cspan class='c'\u003e#\u0026gt; \u003cspan style='color: #555555;'\u003e+ \u003c/span\u003e\u003cspan style='color: #0000BB;'\u003erlang         \u003c/span\u003e\u003cspan style='color: #555555;'\u003e @ tests/testthat/test-blame.R, tests/testthat/test-check-editor.R, tests/testthat/test-clean-dir.R, tests/test…\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\n\u003cspan\u003e\u003cspan class='c'\u003e#\u0026gt; \u003cspan style='color: #555555;'\u003e+ \u003c/span\u003e\u003cspan style='color: #0000BB;'\u003esaperlipopette\u003c/span\u003e\u003cspan style='color: #555555;'\u003e @ tests/testthat.R\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\n\u003cspan\u003e\u003cspan class='c'\u003e#\u0026gt; \u003cspan style='color: #555555;'\u003e+ \u003c/span\u003e\u003cspan style='color: #0000BB;'\u003etestthat      \u003c/span\u003e\u003cspan style='color: #555555;'\u003e @ tests/testthat.R\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\n\u003cspan\u003e\u003cspan class='c'\u003e#\u0026gt; \u003cspan style='color: #555555;'\u003e+ \u003c/span\u003e\u003cspan style='color: #0000BB;'\u003ewithr         \u003c/span\u003e\u003cspan style='color: #555555;'\u003e @ tests/testthat/test-blame.R, tests/testthat/test-check-editor.R, tests/testthat/test-clean-dir.R, tests/test…\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\n\u003cspan\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\n\u003c/div\u003e\n\u003cp\u003e\u003ca href=\"https://ast-grep.github.io/\"\u003east-grep\u003c/a\u003e is a useful tool built on Tree-sitter for searching and re-writing code, with a clearer query syntax than Tree-sitter\u0026rsquo;s. Its name is reminiscent of grep, but with ast-grep we do not need to write brittle regular expressions \u0026#x1f638;. \u003ca href=\"https://astgrepr.etiennebacher.com/\"\u003e{astgrepr}\u003c/a\u003e by Etienne Bacher is an R wrapper to the Rust bindings of ast-grep, and is used in Etienne\u0026rsquo;s \u003ca href=\"https://flir.etiennebacher.com/\"\u003e{flir} package\u003c/a\u003e for \u003ca href=\"https://flir.etiennebacher.com/articles/adding_rules\"\u003erefactoring\u003c/a\u003e code.\u003c/p\u003e\n\u003cp\u003eThe ast-grep command-line interface (CLI) itself is featured in a useful \u003ca href=\"https://emilhvitfeldt.com/post/ast-grep-r-claude-code/\"\u003eblog post by Emil Hvitfeldt\u003c/a\u003e where he explains how to document the usage of ast-grep for Claude.\u003c/p\u003e\n\u003ch2 id=\"formatting-and-linting-air-jarl\"\u003e\n\n\u003ca class=\"anchor d-print-none\" href=\"#formatting-and-linting-air-jarl\"\u003e\n  \u003csmall\u003e\u0026#x1F517;\u003c/small\u003e\n\u003c/a\u003e\n\nFormatting and linting: Air, Jarl\n\u003c/h2\u003e\u003cp\u003eSpeaking of CLIs\u0026hellip;\u003c/p\u003e\n\u003cfigure\u003e\u003cimg src=\"/blog/2026/04/02/tree-sitter-overview/meme.png\"\n    alt=\"Cute kitten attacked by robots. The text says \u0026#39;Everytime you use Claude for something a CLI can do, a kitten dies\u0026#39;.\"\u003e\n\u003c/figure\u003e\n\n\u003cp\u003e\u003ca href=\"https://posit-dev.github.io/air/cli.html\"\u003eAir\u003c/a\u003e, by Davis Vaughan and Lionel Henry, is a CLI built on Tree-sitter, in Rust. It \u003cem\u003ereformats\u003c/em\u003e code blazingly fast.\u003c/p\u003e\n\u003cp\u003e\u003ca href=\"https://jarl.etiennebacher.com/\"\u003eJarl\u003c/a\u003e, by Etienne Bacher, is a CLI built on Air, therefore also on Tree-sitter, in Rust. It \u003cem\u003elints\u003c/em\u003e and \u003cem\u003efixes\u003c/em\u003e code, also blazingly fast. It can even detect \u003ca href=\"https://jarl.etiennebacher.com/rules/unreachable_code\"\u003eunreachable code\u003c/a\u003e, \u003ca href=\"https://jarl.etiennebacher.com/rules/unused_function\"\u003eunused functions\u003c/a\u003e and \u003ca href=\"https://jarl.etiennebacher.com/rules/duplicated_function_definition\"\u003eduplicated function definitions\u003c/a\u003e.\u003c/p\u003e\n\u003cp\u003eIn both of these examples, the creation of \u003cem\u003eCLIs\u003c/em\u003e wrapping Rust bindings was more efficient than the creation of R packages wrapping the {treesitter} R package, for several reasons:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eRust CLIs can edit code very fast\u003csup id=\"fnref:2\"\u003e\u003ca href=\"#fn:2\" class=\"footnote-ref\" role=\"doc-noteref\"\u003e2\u003c/a\u003e\u003c/sup\u003e;\u003c/li\u003e\n\u003cli\u003eCLIs are integrated in extensions for popular IDEs (for instance Positron);\u003c/li\u003e\n\u003cli\u003ea CLI is easier to install on CI than an R package that needs, well, an R installation.\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"more-tools\"\u003e\n\n\u003ca class=\"anchor d-print-none\" href=\"#more-tools\"\u003e\n  \u003csmall\u003e\u0026#x1F517;\u003c/small\u003e\n\u003c/a\u003e\n\nMore tools\n\u003c/h2\u003e\u003cp\u003eA brief mention of some other interesting tools we\u0026rsquo;ve explored a bit less.\u003c/p\u003e\n\u003ch3 id=\"configuring-ts-for-parsing-json-and-toml-not-r\"\u003e\n\n\u003ca class=\"anchor d-print-none\" href=\"#configuring-ts-for-parsing-json-and-toml-not-r\"\u003e\n  \u003csmall\u003e\u0026#x1F517;\u003c/small\u003e\n\u003c/a\u003e\n\nConfiguring: {ts} for parsing JSON and TOML (not R!)\n\u003c/h3\u003e\u003cp\u003eThe \u003ca href=\"https://github.com/r-lib/ts\"\u003e{ts}\u003c/a\u003e package by Gábor Csárdi is the backbone of two R packages used for editing and manipulating:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eTOML \u003ca href=\"https://gaborcsardi.github.io/tstoml/\"\u003e{tstoml}\u003c/a\u003e;\u003c/li\u003e\n\u003cli\u003eJSON \u003ca href=\"https://gaborcsardi.github.io/tsjsonc/\"\u003e{tsjson}\u003c/a\u003e.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eCompared to existing parsers in R for those formats, these two packages preserve comments.\u003c/p\u003e\n\u003ch3 id=\"testing-code-muttest\"\u003e\n\n\u003ca class=\"anchor d-print-none\" href=\"#testing-code-muttest\"\u003e\n  \u003csmall\u003e\u0026#x1F517;\u003c/small\u003e\n\u003c/a\u003e\n\nTesting code: {muttest}\n\u003c/h3\u003e\u003cp\u003e\u003ca href=\"https://en.wikipedia.org/wiki/Mutation_testing\"\u003eMutation testing\u003c/a\u003e is a kind of testing where you, say, randomly swap \u003ccode\u003e+\u003c/code\u003e with \u003ccode\u003e-\u003c/code\u003e in your code (you \u003cem\u003emutate\u003c/em\u003e it) and you run your tests to see whether they catch the mutant. The \u003ca href=\"https://github.com/jakubsob/muttest\"\u003e{muttest} package\u003c/a\u003e by Jakub Sobolewski is an R package for mutation testing, that depends on the {treesitter} R package.\u003c/p\u003e\n\u003ch3 id=\"diffing-code-difftastic\"\u003e\n\n\u003ca class=\"anchor d-print-none\" href=\"#diffing-code-difftastic\"\u003e\n  \u003csmall\u003e\u0026#x1F517;\u003c/small\u003e\n\u003c/a\u003e\n\nDiffing code: difftastic\n\u003c/h3\u003e\u003cp\u003eThe difftastic CLI by Wilfred Hughes is \u0026ldquo;a structural diff tool that understands syntax\u0026rdquo;. ✨ This means that difftastic doesn\u0026rsquo;t only compare line or \u0026ldquo;words\u0026rdquo; but actual syntax by looking at lines around the lines that changed (by default, 3). Even better, it understands R out of the box. See this \u003ca href=\"https://masalmon.eu/2026/03/30/difftastic/\"\u003eblog post with examples of R code diffing\u003c/a\u003e.\u003c/p\u003e\n\u003ch2 id=\"conclusion-more-to-come\"\u003e\n\n\u003ca class=\"anchor d-print-none\" href=\"#conclusion-more-to-come\"\u003e\n  \u003csmall\u003e\u0026#x1F517;\u003c/small\u003e\n\u003c/a\u003e\n\nConclusion: more to come?\n\u003c/h2\u003e\u003cp\u003eIn this post, we\u0026rsquo;ve presented an overview of Tree-sitter based tooling for R or in R.\u003c/p\u003e\n\u003cp\u003eNote that this ecosystem of tools is very actively developed, so some tools might come and go. However, the idea that plugging the R grammar into a general parsing generator brings cool features to us R developers, will remain true. Maybe \u003cem\u003eyou\u003c/em\u003e will contribute to this ecosystem, either through an existing tool or by creating a new one?\u003c/p\u003e\n\u003cdiv class=\"footnotes\" role=\"doc-endnotes\"\u003e\n\u003chr\u003e\n\u003col\u003e\n\u003cli id=\"fn:1\"\u003e\n\u003cp\u003eWe could also parse C code with it using \u003ca href=\"https://sounkou-bioinfo.github.io/treesitter.c/\"\u003e{treesitter.c}\u003c/a\u003e.\u0026#160;\u003ca href=\"#fnref:1\" class=\"footnote-backref\" role=\"doc-backlink\"\u003e\u0026#x21a9;\u0026#xfe0e;\u003c/a\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003cli id=\"fn:2\"\u003e\n\u003cp\u003eRust is a lower level language than R so has less overhead; furthermore this kind of Rust code can be easily parallelized.\u0026#160;\u003ca href=\"#fnref:2\" class=\"footnote-backref\" role=\"doc-backlink\"\u003e\u0026#x21a9;\u0026#xfe0e;\u003c/a\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/div\u003e\n","url":"https://ropensci.org/blog/2026/04/02/tree-sitter-overview/","date_published":"2026-04-02T00:00:00+00:00"},{"id":"https://ropensci.org/blog/2026/03/30/news-mars-2026/","title":"rOpenSci News Digest, March 2026","content_text":"\u003c!-- Before sending DELETE THE INDEX_CACHE and re-knit! --\u003e\n\u003cp\u003eDear rOpenSci friends, it\u0026rsquo;s time for our monthly news roundup! \u003c!-- blabla --\u003e You can read this post \u003ca href=\"/blog/2026/03/30/news-mars-2026\"\u003eon our blog\u003c/a\u003e. Now let\u0026rsquo;s dive into the activity at and around rOpenSci!\u003c/p\u003e\n\u003ch2 id=\"ropensci-hq\"\u003e\n\n\u003ca class=\"anchor d-print-none\" href=\"#ropensci-hq\"\u003e\n  \u003csmall\u003e\u0026#x1F517;\u003c/small\u003e\n\u003c/a\u003e\n\nrOpenSci HQ\n\u003c/h2\u003e\u003ch3 id=\"ropensci-dev-guide-100-trilingual-and-improved\"\u003e\n\n\u003ca class=\"anchor d-print-none\" href=\"#ropensci-dev-guide-100-trilingual-and-improved\"\u003e\n  \u003csmall\u003e\u0026#x1F517;\u003c/small\u003e\n\u003c/a\u003e\n\nrOpenSci Dev Guide 1.0.0: Trilingual and Improved\n\u003c/h3\u003e\u003cp\u003erOpenSci Software Peer Review\u0026rsquo;s guidance is gathered in an online book that keeps improving! It is now available in \u003ca href=\"https://devguide.ropensci.org/\"\u003eEnglish\u003c/a\u003e, \u003ca href=\"https://devguide.ropensci.org/es/index.es.html\"\u003eSpanish\u003c/a\u003e and \u003ca href=\"https://devguide.ropensci.org/pt/index.pt.html\"\u003ePortuguese\u003c/a\u003e. Read more in the \u003ca href=\"/blog/2026/03/02/devguide-1.0.0/\"\u003erelease announcement\u003c/a\u003e\u003c/p\u003e\n\u003ch3 id=\"champions-program-update\"\u003e\n\n\u003ca class=\"anchor d-print-none\" href=\"#champions-program-update\"\u003e\n  \u003csmall\u003e\u0026#x1F517;\u003c/small\u003e\n\u003c/a\u003e\n\nChampions Program Update\n\u003c/h3\u003e\u003cp\u003eWe are still going through the Champions selection process, and we\u0026rsquo;re excited to share that the new group of mentors has already been selected and is now actively reviewing Champions applications.\u003c/p\u003e\n\u003cp\u003eThis cohort brings together a wonderful mix of returning Champions stepping into mentorship roles, mentors continuing their contributions, and new members joining the program. The 2026 mentors are Andrea Gómez Vargas, Pablo Paccioretti, Alber Hamersson Sánchez Ipia, Erick Isaac Navarro Delgado, Francisco Cardozo, Luis Verde Arregoitia, Monika Ávila Márquez, Guadalupe Pascal, Pao Corrales, and Elio Campitelli. Together, they represent a diverse and vibrant community across Colombia, Mexico, Argentina, Brazil, and Bolivia, with some currently based in Switzerland, Canada, the United States, and Australia. We\u0026rsquo;re very happy to see this growing, interconnected network supporting the next cohort of Champions.\u003c/p\u003e\n\u003ch3 id=\"r-universe-update\"\u003e\n\n\u003ca class=\"anchor d-print-none\" href=\"#r-universe-update\"\u003e\n  \u003csmall\u003e\u0026#x1F517;\u003c/small\u003e\n\u003c/a\u003e\n\nR-Universe update\n\u003c/h3\u003e\u003cp\u003eYou can now download artifacts and log files from R-Universe without being logged in with a GitHub account, for example \u003ca href=\"https://ropensci.r-universe.dev/opencv#checktable\"\u003ehttps://ropensci.r-universe.dev/opencv#checktable\u003c/a\u003e.\u003c/p\u003e\n\u003ch3 id=\"software-review-and-usage-of-ai-tools\"\u003e\n\n\u003ca class=\"anchor d-print-none\" href=\"#software-review-and-usage-of-ai-tools\"\u003e\n  \u003csmall\u003e\u0026#x1F517;\u003c/small\u003e\n\u003c/a\u003e\n\nSoftware review and usage of AI tools\n\u003c/h3\u003e\u003cp\u003eAuthors submitting new software for \u003ca href=\"/software-review/\"\u003epeer review\u003c/a\u003e are now required to explain potential usage of generative AI tools in their package development. All submission templates now include a mandatory check-box:\u003c/p\u003e\n\u003cpre\u003e\u003ccode\u003e- [ ] Generative AI tools were used to produce some of the material in this submission.\n\nIf so, please describe usage, and include links to any relevant aspects of your repository.\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eThis is the start of our updates to accommodate generative AI tools in package development, as described in our \u003ca href=\"/blog/2026/02/26/ropensci-ai-policy/\"\u003erecent blog post\u003c/a\u003e. The next phase will involve updates to our \u003ca href=\"https://devguide.ropensci.org\"\u003e\u003cem\u003eDev Guide\u003c/em\u003e\u003c/a\u003e, explaining requirements and recommendations for authors, reviewers, and editors. All updates are intended to permit generative AI tools to be used in any useful way, while minimising the burden on those who volunteer their own time to keep our software peer review service running.\u003c/p\u003e\n\u003ch3 id=\"software-review-bot-updates\"\u003e\n\n\u003ca class=\"anchor d-print-none\" href=\"#software-review-bot-updates\"\u003e\n  \u003csmall\u003e\u0026#x1F517;\u003c/small\u003e\n\u003c/a\u003e\n\nSoftware review bot updates\n\u003c/h3\u003e\u003cp\u003eThe \u003ccode\u003eropensci-review-bot\u003c/code\u003e now delivers an initial report to all new software pre-submissions and submissions, identifying the five most similar packages from both all rOpenSci packages, and all CRAN packages. The matches are generated by our \u003ca href=\"https://docs.ropensci.org/pkgmatch\"\u003eropensci-review-tools/pkgmatch package\u003c/a\u003e (itself reviewed in \u003ca href=\"https://github.com/ropensci/software-review/issues/671\"\u003ethis review issue\u003c/a\u003e). Matching is based on an \u003ca href=\"https://en.wikipedia.org/wiki/Tf%E2%80%93idf\"\u003e\u0026ldquo;term frequency-inverse document frequency\u0026rdquo; algorithm\u003c/a\u003e, using inverse document frequencies from all rOpenSci and CRAN packages. Similar package reports can also be manually triggered (by editors only) with \u003ccode\u003e@ropensci-review-bot similar packages\u003c/code\u003e, like in \u003ca href=\"https://github.com/ropensci/software-review/issues/671#issuecomment-4117805740\"\u003ethis example for the pkgmatch package itself\u003c/a\u003e.\u003c/p\u003e\n\u003ch3 id=\"coworking\"\u003e\n\n\u003ca class=\"anchor d-print-none\" href=\"#coworking\"\u003e\n  \u003csmall\u003e\u0026#x1F517;\u003c/small\u003e\n\u003c/a\u003e\n\nCoworking\n\u003c/h3\u003e\u003cp\u003eRead \u003ca href=\"/blog/2023/06/21/coworking/\"\u003eall about coworking\u003c/a\u003e!\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eTuesday April 7th 2026, 9:00 Americas Pacific (16:00 UTC) \u003ca href=\"/events/coworking-2026-04/\"\u003e\u0026ldquo;Getting to know the CSID Network\u0026rdquo;\u003c/a\u003e with \u003ca href=\"/author/steffi-lazerte/\"\u003eSteffi LaZerte\u003c/a\u003e and cohosts \u003ca href=\"/author/irene-ramos/\"\u003eIrene Ramos\u003c/a\u003e and \u003ca href=\"/author/adamu-saleh-saidu\"\u003eAdamu Saleh Saidu\u003c/a\u003e.\n\u003cul\u003e\n\u003cli\u003eLearn more about the \u003ca href=\"https://csidnet.org/\"\u003eCSID Network\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003eMeet cohosts, Irene Ramos and Adamu Saleh Saidu, and learn more about the CSID Network and how you might get involved.\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003eTuesday May 5th 2026, 9:00 Australia Western (01:00 UTC) \u003ca href=\"/events/coworking-2026-05/\"\u003e\u0026ldquo;Code Review with rOpenSci\u0026rdquo;\u003c/a\u003e with \u003ca href=\"/author/steffi-lazerte/\"\u003eSteffi LaZerte\u003c/a\u003e and cohost \u003ca href=\"/author/liz-hare/\"\u003eLiz Hare\u003c/a\u003e.\n\u003cul\u003e\n\u003cli\u003eExplore resources for Code Review\u003c/li\u003e\n\u003cli\u003eSign up to volunteer to do \u003ca href=\"https://airtable.com/app8dssb6a7PG6Vwj/shrnfDI2S9uuyxtDw\"\u003esoftware peer-review\u003c/a\u003e at rOpenSci\u003c/li\u003e\n\u003cli\u003eMeet cohost, Liz Hare, and discuss resources for Code Review with rOpenSci.\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eAnd remember, you can always cowork independently on work related to R, work on packages that tend to be neglected, or work on what ever you need to get done!\u003c/p\u003e\n\u003ch2 id=\"software-package\"\u003e\n\n\u003ca class=\"anchor d-print-none\" href=\"#software-package\"\u003e\n  \u003csmall\u003e\u0026#x1F517;\u003c/small\u003e\n\u003c/a\u003e\n\nSoftware \u0026#x1f4e6;\n\u003c/h2\u003e\u003ch3 id=\"new-packages\"\u003e\n\n\u003ca class=\"anchor d-print-none\" href=\"#new-packages\"\u003e\n  \u003csmall\u003e\u0026#x1F517;\u003c/small\u003e\n\u003c/a\u003e\n\nNew packages\n\u003c/h3\u003e\u003cp\u003eThe following package recently became a part of our software suite:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ca href=\"https://docs.ropensci.org/suwo\"\u003esuwo\u003c/a\u003e, developed by Marcelo Araya-Salas together with Jorge Elizondo-Calvo and Alejandro Rico-Guevara: Streamline searching/downloading of nature media files (e.g. audios, photos) from online repositories. The package offers functions for obtaining media metadata from online repositories, downloading associated media files and updating data sets with new records. It has been \u003ca href=\"https://github.com/ropensci/software-review/issues/729\"\u003ereviewed\u003c/a\u003e by Eric R. Scott and Hugo Gruson.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eDiscover \u003ca href=\"/packages\"\u003emore packages\u003c/a\u003e, read more about \u003ca href=\"/software-review\"\u003eSoftware Peer Review\u003c/a\u003e.\u003c/p\u003e\n\u003ch3 id=\"new-versions\"\u003e\n\n\u003ca class=\"anchor d-print-none\" href=\"#new-versions\"\u003e\n  \u003csmall\u003e\u0026#x1F517;\u003c/small\u003e\n\u003c/a\u003e\n\nNew versions\n\u003c/h3\u003e\u003cp\u003eThe following eleven packages have had an update since the last newsletter: \u003ca href=\"https://docs.ropensci.org/cffr\" title=\"Generate Citation File Format (cff) Metadata for R Packages\"\u003ecffr\u003c/a\u003e (\u003ca href=\"https://github.com/ropensci/cffr/releases/tag/v1.3.0\"\u003e\u003ccode\u003ev1.3.0\u003c/code\u003e\u003c/a\u003e), \u003ca href=\"https://docs.ropensci.org/pkgmatch\" title=\"Find R Packages Matching Either Descriptions or Other R Packages\"\u003epkgmatch\u003c/a\u003e (\u003ca href=\"https://github.com/ropensci-review-tools/pkgmatch/releases/tag/v0.5.2\"\u003e\u003ccode\u003ev0.5.2\u003c/code\u003e\u003c/a\u003e), \u003ca href=\"https://docs.ropensci.org/tarchetypes\" title=\"Archetypes for Targets\"\u003etarchetypes\u003c/a\u003e (\u003ca href=\"https://github.com/ropensci/tarchetypes/releases/tag/0.14.1\"\u003e\u003ccode\u003e0.14.1\u003c/code\u003e\u003c/a\u003e), \u003ca href=\"https://docs.ropensci.org/rgbif\" title=\"Interface to the Global Biodiversity Information Facility API\"\u003ergbif\u003c/a\u003e (\u003ca href=\"https://github.com/ropensci/rgbif/releases/tag/v3.8.5\"\u003e\u003ccode\u003ev3.8.5\u003c/code\u003e\u003c/a\u003e), \u003ca href=\"https://docs.ropensci.org/saperlipopette\" title=\"Create Example Git Messes\"\u003esaperlipopette\u003c/a\u003e (\u003ca href=\"https://github.com/ropensci-training/saperlipopette/releases/tag/v0.1.1\"\u003e\u003ccode\u003ev0.1.1\u003c/code\u003e\u003c/a\u003e), \u003ca href=\"https://docs.ropensci.org/gutenbergr\" title=\"Download and Process Public Domain Works from Project Gutenberg\"\u003egutenbergr\u003c/a\u003e (\u003ca href=\"https://github.com/ropensci/gutenbergr/releases/tag/v0.5.0\"\u003e\u003ccode\u003ev0.5.0\u003c/code\u003e\u003c/a\u003e), \u003ca href=\"https://docs.ropensci.org/trud\" title=\"Query the NHS TRUD API\"\u003etrud\u003c/a\u003e (\u003ca href=\"https://github.com/ropensci/trud/releases/tag/v0.2.1\"\u003e\u003ccode\u003ev0.2.1\u003c/code\u003e\u003c/a\u003e), \u003ca href=\"https://docs.ropensci.org/naijR\" title=\"Operations to Ease Data Analyses Specific to Nigeria\"\u003enaijR\u003c/a\u003e (\u003ca href=\"https://github.com/ropensci/naijR/releases/tag/v0.7.0\"\u003e\u003ccode\u003ev0.7.0\u003c/code\u003e\u003c/a\u003e), \u003ca href=\"https://docs.ropensci.org/sasquatch\" title=\"Use SAS, R, and quarto Together\"\u003esasquatch\u003c/a\u003e (\u003ca href=\"https://github.com/ropensci/sasquatch/releases/tag/v0.1.3\"\u003e\u003ccode\u003ev0.1.3\u003c/code\u003e\u003c/a\u003e), \u003ca href=\"https://docs.ropensci.org/lingtypology\" title=\"Linguistic Typology and Mapping\"\u003elingtypology\u003c/a\u003e (\u003ca href=\"https://github.com/ropensci/lingtypology/releases/tag/v1.1.25\"\u003e\u003ccode\u003ev1.1.25\u003c/code\u003e\u003c/a\u003e), and \u003ca href=\"https://docs.ropensci.org/rerddap\" title=\"General Purpose Client for ERDDAP™ Servers\"\u003ererddap\u003c/a\u003e (\u003ca href=\"https://github.com/ropensci/rerddap/releases/tag/v1.2.3\"\u003e\u003ccode\u003ev1.2.3\u003c/code\u003e\u003c/a\u003e).\u003c/p\u003e\n\u003cp\u003ePost on dfms release: \u003ca href=\"https://sebkrantz.github.io/Rblog/2026/01/29/releasing-dfms-1-0-fast-and-feature-rich-estimation-of-dynamic-factor-models-in-r/\"\u003eReleasing dfms 1.0: Fast and Feature-Rich Estimation of Dynamic Factor Models in R\u003c/a\u003e.\u003c/p\u003e\n\u003ch2 id=\"software-peer-review\"\u003e\n\n\u003ca class=\"anchor d-print-none\" href=\"#software-peer-review\"\u003e\n  \u003csmall\u003e\u0026#x1F517;\u003c/small\u003e\n\u003c/a\u003e\n\nSoftware Peer Review\n\u003c/h2\u003e\u003cp\u003eThere are fifteen recently closed and active submissions and 5 submissions on hold. Issues are at different stages:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003eOne at \u003ca href=\"https://github.com/ropensci/software-review/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+label%3A%226/approved%22\"\u003e\u0026lsquo;6/approved\u0026rsquo;\u003c/a\u003e:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ca href=\"https://github.com/ropensci/software-review/issues/729\"\u003esuwo\u003c/a\u003e, Access Nature Media Repositories Through R. Submitted by \u003ca href=\"https://marce10.github.io/\"\u003eMarcelo Araya-Salas\u003c/a\u003e.\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003eOne at \u003ca href=\"https://github.com/ropensci/software-review/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+label%3A%225/awaiting-reviewer(s)-response%22\"\u003e\u0026lsquo;5/awaiting-reviewer(s)-response\u0026rsquo;\u003c/a\u003e:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ca href=\"https://github.com/ropensci/software-review/issues/671\"\u003epkgmatch\u003c/a\u003e, Find R Packages Matching Either Descriptions or Other R Packages. Submitted by \u003ca href=\"https://mpadge.github.io\"\u003emark padgham\u003c/a\u003e.\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003eTwo at \u003ca href=\"https://github.com/ropensci/software-review/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+label%3A%224/review(s)-in-awaiting-changes%22\"\u003e\u0026lsquo;4/review(s)-in-awaiting-changes\u0026rsquo;\u003c/a\u003e:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e\u003ca href=\"https://github.com/ropensci/software-review/issues/741\"\u003elogolink\u003c/a\u003e, An Interface for Running NetLogo Simulations. Submitted by \u003ca href=\"http://danielvartan.com\"\u003eDaniel Vartanian\u003c/a\u003e.\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003ca href=\"https://github.com/ropensci/software-review/issues/615\"\u003egalamm\u003c/a\u003e, Generalized Additive Latent and Mixed Models. Submitted by \u003ca href=\"https://osorensen.github.io/\"\u003eØystein Sørensen\u003c/a\u003e. (Stats).\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003eSix at \u003ca href=\"https://github.com/ropensci/software-review/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+label%3A%223/reviewer(s)-assigned%22\"\u003e\u0026lsquo;3/reviewer(s)-assigned\u0026rsquo;\u003c/a\u003e:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e\u003ca href=\"https://github.com/ropensci/software-review/issues/760\"\u003epvEBayes\u003c/a\u003e, Empirical Bayes Methods for Pharmacovigilance. Submitted by \u003ca href=\"https://github.com/YihaoTancn\"\u003eYihao Tan\u003c/a\u003e. (Stats).\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003ca href=\"https://github.com/ropensci/software-review/issues/754\"\u003esaperlipopette\u003c/a\u003e, Create Example Git Messes. Submitted by \u003ca href=\"https://masalmon.eu/\"\u003eMaëlle Salmon\u003c/a\u003e.\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003ca href=\"https://github.com/ropensci/software-review/issues/730\"\u003eernest\u003c/a\u003e, A Toolkit for Nested Sampling. Submitted by \u003ca href=\"https://github.com/kylesnap\"\u003eKyle Dewsnap\u003c/a\u003e. (Stats).\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003ca href=\"https://github.com/ropensci/software-review/issues/718\"\u003ercrisp\u003c/a\u003e, Automate the Delineation of Urban River Spaces. Submitted by \u003ca href=\"https://github.com/cforgaci\"\u003eClaudiu Forgaci\u003c/a\u003e. (Stats).\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003ca href=\"https://github.com/ropensci/software-review/issues/709\"\u003ereviser\u003c/a\u003e, Tools for Studying Revision Properties in Real-Time Time Series Vintages. Submitted by \u003ca href=\"https://marcburri.github.io/\"\u003eMarc Burri\u003c/a\u003e.\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003ca href=\"https://github.com/ropensci/software-review/issues/704\"\u003epriorsense\u003c/a\u003e, Prior Diagnostics and Sensitivity Analysis. Submitted by \u003ca href=\"https://github.com/n-kall\"\u003eNoa Kallioinen\u003c/a\u003e. (Stats).\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003eTwo at \u003ca href=\"https://github.com/ropensci/software-review/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+label%3A%222/seeking-reviewer(s)%22\"\u003e\u0026lsquo;2/seeking-reviewer(s)\u0026rsquo;\u003c/a\u003e:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e\u003ca href=\"https://github.com/ropensci/software-review/issues/750\"\u003enycOpenData\u003c/a\u003e, Convenient Access to NYC Open Data API Endpoints. Submitted by \u003ca href=\"https://github.com/martinezc1\"\u003eChristian Martinez\u003c/a\u003e.\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003ca href=\"https://github.com/ropensci/software-review/issues/743\"\u003eRAMEN\u003c/a\u003e, RAMEN: Regional Association of Methylome variability with the Exposome and geNome. Submitted by \u003ca href=\"https://erick-navarrodelgado.netlify.app\"\u003eErick Navarro-Delgado\u003c/a\u003e.\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003eThree at \u003ca href=\"https://github.com/ropensci/software-review/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+label%3A%221/editor-checks%22\"\u003e\u0026lsquo;1/editor-checks\u0026rsquo;\u003c/a\u003e:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e\u003ca href=\"https://github.com/ropensci/software-review/issues/744\"\u003eRAQSAPI\u003c/a\u003e, A Simple Interface to the US EPA Air Quality System Data Mart API. Submitted by \u003ca href=\"https://github.com/mccroweyclinton-EPA\"\u003emccroweyclinton-EPA\u003c/a\u003e.\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003ca href=\"https://github.com/ropensci/software-review/issues/740\"\u003efcmconfr\u003c/a\u003e, Fuzzy Cognitive Map Analysis in R. Submitted by \u003ca href=\"https://github.com/bhroston\"\u003ebenroston\u003c/a\u003e. (Stats).\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003ca href=\"https://github.com/ropensci/software-review/issues/717\"\u003ecoevolve\u003c/a\u003e, Fit Bayesian Generalized Dynamic Phylogenetic Models using Stan. Submitted by \u003ca href=\"https://scottclaessens.github.io/\"\u003eScott Claessens\u003c/a\u003e. (Stats).\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eFind out more about \u003ca href=\"/software-review\"\u003eSoftware Peer Review\u003c/a\u003e and how to get involved.\u003c/p\u003e\n\u003ch2 id=\"on-the-blog\"\u003e\n\n\u003ca class=\"anchor d-print-none\" href=\"#on-the-blog\"\u003e\n  \u003csmall\u003e\u0026#x1F517;\u003c/small\u003e\n\u003c/a\u003e\n\nOn the blog\n\u003c/h2\u003e\u003c!-- Do not forget to rebase your branch! --\u003e\n\u003ch3 id=\"software-review\"\u003e\n\n\u003ca class=\"anchor d-print-none\" href=\"#software-review\"\u003e\n  \u003csmall\u003e\u0026#x1F517;\u003c/small\u003e\n\u003c/a\u003e\n\nSoftware Review\n\u003c/h3\u003e\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e\u003ca href=\"/blog/2026/02/26/ropensci-ai-policy\"\u003eSoftware Review in the Era of AI: What We Are Testing at rOpenSci\u003c/a\u003e by Mark Padgham, Noam Ross, Maëlle Salmon, Yanina Bellini Saibene, Mauro Lepore, Emily Riederer, Jouni Helske, and Francisco Rodriguez-Sanchez. rOpenSci is testing preliminary policies on the use of generative AI tools, with proposed updates to documentation and procedures for authors submitting software for review, for editors, and for reviewers.\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003ca href=\"/blog/2026/03/02/devguide-1.0.0\"\u003erOpenSci Dev Guide 1.0.0: Trilingual and Improved\u003c/a\u003e by Maëlle Salmon, Mark Padgham, and Noam Ross. Updates in version 1.0.0 of the online book \u0026lsquo;rOpenSci Packages: Development, Maintenance, and Peer Review\u0026rsquo;. Other languages: \u003ca href='/es/blog/2026/03/02/r_open_sci_dev_guide_1_0_0_trilingüe_y_mejorada' lang='es'\u003erOpenSci Dev Guide 1.0.0: Trilingüe y mejorada (es)\u003c/a\u003e, \u003ca href='/pt/blog/2026/03/02/guia_de_desenvolvimento_da_r_open_sci_1_0_0_trilíngue_e_aprimorado' lang='pt'\u003eGuia de desenvolvimento da rOpenSci 1.0.0: trilíngue e aprimorado (pt)\u003c/a\u003e.\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003cfigure class=\"center\"\u003e\u003cimg src=\"/blog/2026/03/30/news-mars-2026/cover.png\"\n    alt=\"cover of rOpenSci dev guide, showing a package production line with small humans discussing, examining and promoting packages\" width=\"400\"\u003e\n\u003c/figure\u003e\n\n\u003cul\u003e\n\u003cli\u003e\u003ca href=\"/blog/2026/03/10/patentsview-breaking-release\"\u003eBreaking Release of the patentsview R Package\u003c/a\u003e by Russ Allen and Chris Baker. Breaking Release of the patentsview R Package.\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"calls-for-contributions\"\u003e\n\n\u003ca class=\"anchor d-print-none\" href=\"#calls-for-contributions\"\u003e\n  \u003csmall\u003e\u0026#x1F517;\u003c/small\u003e\n\u003c/a\u003e\n\nCalls for contributions\n\u003c/h2\u003e\u003ch3 id=\"calls-for-maintainers\"\u003e\n\n\u003ca class=\"anchor d-print-none\" href=\"#calls-for-maintainers\"\u003e\n  \u003csmall\u003e\u0026#x1F517;\u003c/small\u003e\n\u003c/a\u003e\n\nCalls for maintainers\n\u003c/h3\u003e\u003cp\u003eIf you\u0026rsquo;re interested in maintaining any of the R packages below, you might enjoy reading our blog post \u003ca href=\"/blog/2023/02/07/what-does-it-mean-to-maintain-a-package/\"\u003eWhat Does It Mean to Maintain a Package?\u003c/a\u003e.\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e\u003ca href=\"https://docs.ropensci.org/NLMR\"\u003eNLMR\u003c/a\u003e, R package to simulate neutral landscape models. \u003ca href=\"https://github.com/ropensci/NLMR/issues/116\"\u003eIssue for volunteering\u003c/a\u003e.\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003ca href=\"https://docs.ropensci.org/landscapetools\"\u003elandscapetools\u003c/a\u003e, R package for some of the less-glamorous tasks involved in landscape analysis. \u003ca href=\"https://github.com/ropensci/landscapetools/issues/48\"\u003eIssue for volunteering\u003c/a\u003e.\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003ca href=\"https://docs.ropensci.org/hddtools\"\u003ehddtools\u003c/a\u003e, Tools to discover hydrological data, accessing catalogues and databases from various data providers. \u003ca href=\"https://github.com/ropensci/hddtools/issues/36\"\u003eIssue for volunteering\u003c/a\u003e.\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003ca href=\"https://docs.ropensci.org/qualtRics/\"\u003equaltRics\u003c/a\u003e, download Qualtrics survey data. \u003ca href=\"https://github.com/ropensci/qualtRics/issues/383\"\u003eIssue for volunteering\u003c/a\u003e.\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch3 id=\"calls-for-contributions-1\"\u003e\n\n\u003ca class=\"anchor d-print-none\" href=\"#calls-for-contributions-1\"\u003e\n  \u003csmall\u003e\u0026#x1F517;\u003c/small\u003e\n\u003c/a\u003e\n\nCalls for contributions\n\u003c/h3\u003e\u003cp\u003eRefer to our \u003ca href=\"/help-wanted/\"\u003ehelp wanted page\u003c/a\u003e \u0026ndash; before opening a PR, we recommend asking in the issue whether help is still needed.\u003c/p\u003e\n\u003ch2 id=\"package-development-corner\"\u003e\n\n\u003ca class=\"anchor d-print-none\" href=\"#package-development-corner\"\u003e\n  \u003csmall\u003e\u0026#x1F517;\u003c/small\u003e\n\u003c/a\u003e\n\nPackage development corner\n\u003c/h2\u003e\u003cp\u003eSome useful tips for R package developers. \u0026#x1f440;\u003c/p\u003e\n\u003ch3 id=\"a-new-r-core-member\"\u003e\n\n\u003ca class=\"anchor d-print-none\" href=\"#a-new-r-core-member\"\u003e\n  \u003csmall\u003e\u0026#x1F517;\u003c/small\u003e\n\u003c/a\u003e\n\nA new R core member!\n\u003c/h3\u003e\u003cp\u003eThe R Foundation announced that \u003ca href=\"https://uk.linkedin.com/in/heathrturnr\"\u003eHeather Turner\u003c/a\u003e has joined the \u003ca href=\"https://www.r-project.org/contributors.html\"\u003eR Core Team\u003c/a\u003e! \u0026#x1f389;\u003c/p\u003e\n\u003ch3 id=\"how-to-browse-the-r-mailing-lists\"\u003e\n\n\u003ca class=\"anchor d-print-none\" href=\"#how-to-browse-the-r-mailing-lists\"\u003e\n  \u003csmall\u003e\u0026#x1F517;\u003c/small\u003e\n\u003c/a\u003e\n\nHow to browse the R mailing lists\n\u003c/h3\u003e\u003cp\u003eThe \u003ca href=\"https://www.r-project.org/mail.html\"\u003eofficial mailing lists of the R project\u003c/a\u003e like \u003ca href=\"https://blog.r-hub.io/2019/04/11/r-package-devel/\"\u003eR-package-devel\u003c/a\u003e are full of important and useful information. How to browse them, given that the default website is not easy to search? You can use the \u003ca href=\"https://mail-archive.com/r-devel@r-project.org/\"\u003email-archive\u003c/a\u003e website (thanks to Hugo Gruson for the reminder!) or a new project by James Balamuta: the \u003ca href=\"https://r-mailing-lists.thecoatlessprofessor.com/\"\u003eR Mailing Lists Archive\u003c/a\u003e!\u003c/p\u003e\n\u003ch3 id=\"claude-code-setting-up-ast-grep-with-r-support\"\u003e\n\n\u003ca class=\"anchor d-print-none\" href=\"#claude-code-setting-up-ast-grep-with-r-support\"\u003e\n  \u003csmall\u003e\u0026#x1F517;\u003c/small\u003e\n\u003c/a\u003e\n\n\u0026ldquo;Claude Code: Setting up ast-grep with R support\u0026rdquo;\n\u003c/h3\u003e\u003cp\u003eThanks to Mauro Lepore for sharing this blog post by Emil Hvitfeldt: \u003ca href=\"https://emilhvitfeldt.com/post/ast-grep-r-claude-code/\"\u003e\u0026ldquo;Claude Code: Setting up ast-grep with R support\u0026rdquo;\u003c/a\u003e. ast-grep is a tool for querying code by syntax rather than brittle regular expressions. The blog post describes how to add R support to this tool, and how to take advantage of it when using Claude.\u003c/p\u003e\n\u003ch3 id=\"on-muffling-messages-from-packages\"\u003e\n\n\u003ca class=\"anchor d-print-none\" href=\"#on-muffling-messages-from-packages\"\u003e\n  \u003csmall\u003e\u0026#x1F517;\u003c/small\u003e\n\u003c/a\u003e\n\nOn muffling messages from packages\n\u003c/h3\u003e\u003cp\u003eA follow-up on our post \u003ca href=\"/blog/2024/02/06/verbosity-control-packages/\"\u003e\u0026ldquo;Please Shut Up! Verbosity Control in Packages\u0026rdquo;\u003c/a\u003e.\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eWith the {cli} R package you can change the default handler for messages. See the \u003ca href=\"https://cli.r-lib.org/articles/semantic-cli.html#cli-messages\"\u003edocs\u003c/a\u003e. It seems mostly used to muffle messages, e.g. in \u003ca href=\"https://github.com/etiennebacher/flir/blob/9254cd01d258d0bafcee41a44e5caa7104fed832/R/lint.R#L104\"\u003eflir\u003c/a\u003e.\u003c/li\u003e\n\u003cli\u003eHere\u0026rsquo;s how the usethis R package \u003ca href=\"https://github.com/r-lib/usethis/commit/f0f3f91494a1b15c1b08ee78dc73ab7d1cf8b6a8\"\u003emuffles gert message selectively\u003c/a\u003e.\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"last-words\"\u003e\n\n\u003ca class=\"anchor d-print-none\" href=\"#last-words\"\u003e\n  \u003csmall\u003e\u0026#x1F517;\u003c/small\u003e\n\u003c/a\u003e\n\nLast words\n\u003c/h2\u003e\u003cp\u003eThanks for reading! If you want to get involved with rOpenSci, check out our \u003ca href=\"https://contributing.ropensci.org\"\u003eContributing Guide\u003c/a\u003e that can help direct you to the right place, whether you want to make code contributions, non-code contributions, or contribute in other ways like sharing use cases. You can also support our work through \u003ca href=\"/donate\"\u003edonations\u003c/a\u003e.\u003c/p\u003e\n\u003cp\u003eIf you haven\u0026rsquo;t subscribed to our newsletter yet, you can \u003ca href=\"/news/\"\u003edo so via a form\u003c/a\u003e. Until it\u0026rsquo;s time for our next newsletter, you can keep in touch with us via our \u003ca href=\"/\"\u003ewebsite\u003c/a\u003e and \u003ca href=\"https://hachyderm.io/@rOpenSci\"\u003eMastodon account\u003c/a\u003e.\u003c/p\u003e\n","url":"https://ropensci.org/blog/2026/03/30/news-mars-2026/","date_published":"2026-03-30T00:00:00+00:00"},{"id":"https://ropensci.org/blog/2026/03/10/patentsview-breaking-release/","title":"Breaking Release of the patentsview R Package","content_text":"\u003cp\u003eThe \u003ca href=\"http://docs.ropensci.org/patentsview/\"\u003epatentsview\u003c/a\u003e R package was created by Chris Baker to simplify interactions with the\nPatentsView API as announced in Chris\u0026rsquo;\n\u003ca href=\"/blog/2017/09/19/patentsview/\"\u003eblog post\u003c/a\u003e\nin 2017.  The API can be queried for data from US patents granted since 1976 as well as\npatent applications since 2001 (not all going on to become granted patents).\u003cbr\u003e\nAs shown in the package\u0026rsquo;s vignettes, location data can be mapped, charts of\nassignees can be created etc. using other R packages, only limited by the\ndeveloper\u0026rsquo;s imagination.\u003c/p\u003e\n\u003cp\u003eFast-forwarding to today finds us in a precarious\nposition as the PatentsView API team had made breaking changes and obsoleted\nthe original API (all calls to the original endpoints return 410 Gone).\nAs such we have spent some time now updating patentsview to work with these API changes.\nThe updated patentsview package is now on CRAN but, unfortunately, as this Tech Note was being prepared\nthe PatentsView API team made troubling changes.\u003c/p\u003e\n\u003cp\u003eIn late February they replaced their\n\u003ca href=\"https://patentsview.org/forum\"\u003eforum\u003c/a\u003e with a message saying the page was temporarily\nunavailable.  Further, they have also removed the link to request an API key, so it\u0026rsquo;s unclear\nwhether they\u0026rsquo;d honor requests for API keys using the link below.  Nothing has been officially\nannounced but the long term viability of the API seems uncertain.\u003c/p\u003e\n\u003cp\u003e\u0026#x1f374; Here you\u0026rsquo;ve come to a fork (and knife) in the road, continue reading\nif you are/were using the original version of the patentsview package, and we\u0026rsquo;ll guide\nyou through the necessary changes.  If you have an interest in US patent data but haven\u0026rsquo;t\nused the patentsview package yet (and are willing to take the risk!), check out the \u003ca href=\"https://docs.ropensci.org/patentsview/articles/ropensci-blog-post.html\"\u003evignette\u003c/a\u003e reworked from Chris\u0026rsquo; original blog post to use the new version of the R package and API.\u003c/p\u003e\n\u003ch2 id=\"new-changes-to-the-api\"\u003e\n\n\u003ca class=\"anchor d-print-none\" href=\"#new-changes-to-the-api\"\u003e\n  \u003csmall\u003e\u0026#x1F517;\u003c/small\u003e\n\u003c/a\u003e\n\nNew changes to the API:\n\u003c/h2\u003e\u003col\u003e\n\u003cli\u003eUsers will need to \u003ca href=\"https://patentsview-support.atlassian.net/servicedesk/customer/portals\"\u003erequest an API key\u003c/a\u003e and set an environmental variable PATENTSVIEW_API_KEY to this value.\u003c/li\u003e\n\u003cli\u003eEndpoint changes:\n\u003cul\u003e\n\u003cli\u003eThe \u003ccode\u003enber_subcategories\u003c/code\u003e, one of the original seven endpoints, was removed\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003ecpc_subsections\u003c/code\u003e is now \u003ccode\u003ecpc_group\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003eThe remaining five original endpoints went from plural to singular, \u003ccode\u003epatents\u003c/code\u003e is now \u003ccode\u003epatent\u003c/code\u003e, for example.\nInterestingly, the returned data structures are still plural for the most part.\u003c/li\u003e\n\u003cli\u003eThere are now 27 endpoints, and more than one may need to be called to retrieve fields that were\navailable from a single call to one of the original endpoints\u003c/li\u003e\n\u003cli\u003eSome of the endpoints now return HATEOAS (Hypermedia as the Engine of Application State) links that can be called to retrieve additional data\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003eSome fields are now nested and need to be fully qualified when used in a query,\nfor instance, \u003ccode\u003esearch_pv('{\u0026quot;cpc_current.cpc_group_id\u0026quot;:\u0026quot;A01B1/00\u0026quot;}')\u003c/code\u003e when using the patent endpoint.\nIn the fields parameter, nested fields can be fully qualified or a new API shorthand can be used,\nwhich allows you to specify group names. When group names are used, all of the group\u0026rsquo;s nested fields will be returned.\nFor example, defining \u003ccode\u003efields = c(\u0026quot;assignees\u0026quot;)\u003c/code\u003e when\nusing the patent endpoint means that all nested assignees\u0026rsquo; fields will be returned by the API.\u003c/li\u003e\n\u003cli\u003eSome field names have changed, most significantly, \u003ccode\u003epatent_number\u003c/code\u003e is now \u003ccode\u003epatent_id\u003c/code\u003e,\nand some fields were removed entirely, for instance, \u003ccode\u003erawinventor_first_name\u003c/code\u003e and \u003ccode\u003erawinventor_last_name\u003c/code\u003e.\u003c/li\u003e\n\u003cli\u003eThe original version of the API had queryable fields and additional fields which could be\nretrieved but couldn\u0026rsquo;t be part of a conditional query.  That notion does not apply to the\nnew version of the API as all fields are now queryable.  You may be able\nto simplify your code if you found yourself doing post processing on returned data\nbecause a field you were interested in was not queryable.\u003c/li\u003e\n\u003cli\u003eNow there isn\u0026rsquo;t supposed to be a difference between\noperators used on strings vs full text fields, as there was in the original\nversion of the API.  See the tip below the \u003ca href=\"https://search.patentsview.org/docs/docs/Search%20API/SearchAPIReference/#syntax\"\u003eSyntax section\u003c/a\u003e.\u003c/li\u003e\n\u003cli\u003eResult set paging has changed significantly.  This only matter to users implementing their own\npaging, as the package continues to handle result set paging with \u003ccode\u003esearch_pv()\u003c/code\u003e\u0026rsquo;s \u003ccode\u003eall_pages = TRUE\u003c/code\u003e.\nThere is a new \u003ca href=\"https://docs.ropensci.org/patentsview/articles/result-set-paging.html\"\u003eResult set paging\u003c/a\u003e vignette to explain the API\u0026rsquo;s paging,\nusing the \u003ccode\u003esize\u003c/code\u003e and \u003ccode\u003eafter\u003c/code\u003e parameters rather than \u003ccode\u003epage\u003c/code\u003e and \u003ccode\u003eper_page\u003c/code\u003e.\u003c/li\u003e\n\u003cli\u003eResult set sizes are seemingly unbounded now.  The original version of the API capped result sets at\n100,000 rows.\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003eThe API team also \u003ca href=\"https://search.patentsview.org/docs/#naming-update\"\u003erenamed the API\u003c/a\u003e,\nPatentsView\u0026rsquo;s Search API is now the PatentSearch API.\nNote that the R package will retain its name, continue to use \u003ccode\u003elibrary(patentsview)\u003c/code\u003e to load the package.\u003c/p\u003e\n\u003ch2 id=\"new-changes-to-the-r-package\"\u003e\n\n\u003ca class=\"anchor d-print-none\" href=\"#new-changes-to-the-r-package\"\u003e\n  \u003csmall\u003e\u0026#x1F517;\u003c/small\u003e\n\u003c/a\u003e\n\nNew changes to the R package:\n\u003c/h2\u003e\u003col\u003e\n\u003cli\u003eThrottling is now enforced by the API and handled by the R package (sleep as specified by the throttle response before a retry)\u003c/li\u003e\n\u003cli\u003eThere are five new vignettes\n\u003cul\u003e\n\u003cli\u003e\u003ca href=\"https://docs.ropensci.org/patentsview/articles/api-changes.html\"\u003eAPI Changes\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://docs.ropensci.org/patentsview/articles/converting-an-existing-script.html\"\u003eConverting an existing script\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://docs.ropensci.org/patentsview/articles/result-set-paging.html\"\u003eResult set paging\u003c/a\u003e, should custom paging be needed\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://docs.ropensci.org/patentsview/articles/understanding-the-api.html\"\u003eUnderstanding the API\u003c/a\u003e, the API team\u0026rsquo;s jupyter notebook converted to R and enhanced\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"/blog/2017/09/19/patentsview/\"\u003eAccessing patent data with the patentsview package\u003c/a\u003e, the blog post that announced the original version of the R package has been updated to work with the new version of the API\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003eThe R package changed internally from using httr to httr2.  This only affects users if\nthey passed additional arguments (\u003ccode\u003e...\u003c/code\u003e) to \u003ccode\u003esearch_pv()\u003c/code\u003e.  Previously if they passed \u003ccode\u003econfig = httr::timeout(40)\u003c/code\u003e\nthey\u0026rsquo;d now pass \u003ccode\u003etimeout = 40\u003c/code\u003e (name-value pairs of valid curl options, as found in \u003ccode\u003ecurl::curl_options()\u003c/code\u003e see \u003ca href=\"https://httr2.r-lib.org/reference/req_options.html\"\u003ereq_options\u003c/a\u003e)\u003c/li\u003e\n\u003cli\u003eNow that the R package is using httr2, users can make use of its \u003ccode\u003elast_request()\u003c/code\u003e method to see what was sent to the API.  This could be useful when trying to fix an invalid request.  Also fun would be seeing the raw API response.\u003c/li\u003e\n\u003c/ol\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003ehttr2::last_request()\nhttr2::last_response()\nhttr2::last_response() |\u0026gt; httr2::resp_body_json() \n\u003c/code\u003e\u003c/pre\u003e\u003col start=\"5\"\u003e\n\u003cli\u003eA new function was added\n\u003ccode\u003eretrieve_linked_data()\u003c/code\u003e to retrieve data from a HATEOAS link the API sent back, retrying if throttled\u003c/li\u003e\n\u003cli\u003eAn existing function was removed.  With the API changes, there is less of a need for\n\u003ccode\u003ecast_pv_data()\u003c/code\u003e which was previously part of the R package.  The API now returns most fields as appropriate\ntypes, boolean, numeric etc., instead of always returning strings.\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch2 id=\"online-api-documentation\"\u003e\n\n\u003ca class=\"anchor d-print-none\" href=\"#online-api-documentation\"\u003e\n  \u003csmall\u003e\u0026#x1F517;\u003c/small\u003e\n\u003c/a\u003e\n\nOnline API documentation\n\u003c/h2\u003e\u003cp\u003eThe PatentsView API team has thoughtfully provided a Swagger UI page for the new version of the API at \u003ca href=\"https://search.patentsview.org/swagger-ui/\"\u003ehttps://search.patentsview.org/swagger-ui/\u003c/a\u003e.\nThink of it as an online version of Postman already loaded with the API\u0026rsquo;s new endpoints and returns.\nThe Swagger UI page documents what fields are returned by each endpoint on a successful call\n(http response code 200).\nYou can even send in requests and see actual API responses if you enter your API key and press\nan endpoint\u0026rsquo;s \u0026ldquo;Try it out\u0026rdquo; and \u0026ldquo;Execute\u0026rdquo; buttons.  Even error responses can be informative, the API\u0026rsquo;s X-Status-Reason response header\nusually points out what went wrong.\u003c/p\u003e\n\u003cp\u003eIn a similar format, the \u003ca href=\"https://search.patentsview.org/docs/docs/Search%20API/EndpointDictionary/\"\u003eupdated API documentation\u003c/a\u003e\nlists what each endpoint does.  Additionally, the R package\u0026rsquo;s \u003ccode\u003efieldsdf\u003c/code\u003e data frame has been updated,\nnow listing the new set of endpoints and fields that can be queried and/or returned.  The R package\u0026rsquo;s\nreference pages have also been updated.\u003c/p\u003e\n\u003ch2 id=\"final-thoughts\"\u003e\n\n\u003ca class=\"anchor d-print-none\" href=\"#final-thoughts\"\u003e\n  \u003csmall\u003e\u0026#x1F517;\u003c/small\u003e\n\u003c/a\u003e\n\nFinal thoughts\n\u003c/h2\u003e\u003cp\u003eAs shown in the updated \u003ca href=\"https://docs.ropensci.org/patentsview/articles/top-assignees.html\"\u003eTop Assignees\u003c/a\u003e vignette, there will be occasions now where multiple API calls are needed to retrieve the same data as in a single API call in the original version of the API and R package.\nAdditionally, the \u003ca href=\"https://docs.ropensci.org/patentsview/articles/ropensci-blog-post.html\"\u003ereworked rOpenSci post\u003c/a\u003e explains what changes had to be made since assignee latitude\nand longitude are no longer available from the patent endpoint.\u003c/p\u003e\n\u003cp\u003eIssues for the R package can be raised in the \u003ca href=\"https://github.com/ropensci/patentsview/issues\"\u003epatentsview repo\u003c/a\u003e.\u003c/p\u003e\n\u003cp\u003eAs we mentioned at the start, the future of the PatentsView API is a bit uncertain. PatentsView is funded by the \u003ca href=\"https://www.uspto.gov/\"\u003eUSPTO\u003c/a\u003e, who may be looking to cut costs. However, until we know for certain, we hope patentsview serves you well. If nothing else,\nit\u0026rsquo;s been a great run, starting in 2015 for the API and 2017 for the R package!\u003c/p\u003e\n","url":"https://ropensci.org/blog/2026/03/10/patentsview-breaking-release/","date_published":"2026-03-10T00:00:00+00:00"}]}