<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>R-bloggers</title>
	<atom:link href="https://www.r-bloggers.com/feed/" rel="self" type="application/rss+xml" />
	<link>https://www.r-bloggers.com</link>
	<description>R news and tutorials contributed by hundreds of R bloggers</description>
	<lastBuildDate>Thu, 06 Aug 2026 14:00:00 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=5.5.19</generator>

<image>
	<url>https://i0.wp.com/www.r-bloggers.com/wp-content/uploads/2016/08/cropped-R_single_01-200.png?fit=32%2C32&#038;ssl=1</url>
	<title>R-bloggers</title>
	<link>https://www.r-bloggers.com</link>
	<width>32</width>
	<height>32</height>
</image> 
<site xmlns="com-wordpress:feed-additions:1">11524731</site>	<item>
		<title>The GIS Research Assistant Job Has Transformed</title>
		<link>https://www.r-bloggers.com/2026/08/the-gis-research-assistant-job-has-transformed/</link>
		
		<dc:creator><![CDATA[Seascapemodels]]></dc:creator>
		<pubDate>Thu, 06 Aug 2026 14:00:00 +0000</pubDate>
				<category><![CDATA[R bloggers]]></category>
		<guid isPermaLink="false">https://www.seascapemodels.org/posts/2026-08-07-gis-has-changed-forever/</guid>

					<description><![CDATA[<div style = "width:60%; display: inline-block; float:left; ">
<p>I realized this week that I won’t be hiring a GIS focused research assistant the same way as I used to.<br />
Claude Code is just too good at GIS in R now. I guess this happened around the release of Opus 4.7. I just hadn’t really pushed the coding ...</p></div>
<div style = "width: 40%; display: inline-block; float:right;"></div>
<div style="clear: both;"></div>
<strong>Continue reading</strong>: <a href="https://www.r-bloggers.com/2026/08/the-gis-research-assistant-job-has-transformed/">The GIS Research Assistant Job Has Transformed</a>]]></description>
										<content:encoded><![CDATA[<!-- 
<div style="min-height: 30px;">
[social4i size="small" align="align-left"]
</div>
-->

<div style="border: 1px solid; background: none repeat scroll 0 0 #EDEDED; margin: 1px; font-size: 12px;">
[This article was first published on  <strong><a href="https://www.seascapemodels.org/posts/2026-08-07-gis-has-changed-forever/"> Seascapemodels</a></strong>, and kindly contributed to <a href="https://www.r-bloggers.com/" rel="nofollow">R-bloggers</a>].  (You can report issue about the content on this page <a href="https://www.r-bloggers.com/contact-us/">here</a>)
<hr>Want to share your content on R-bloggers?<a href="https://www.r-bloggers.com/add-your-blog/" rel="nofollow"> click here</a> if you have a blog, or <a href="http://r-posts.com/" rel="nofollow"> here</a> if you don't.
</div>
 





<p>I realized this week that I won’t be hiring a GIS focused research assistant the same way as I used to.</p>
<p>Claude Code is just too good at GIS in R now. I guess this happened around the release of Opus 4.7. I just hadn’t really pushed the coding agent until now.</p>
<p>This week I downloaded a global dataset of a coastal habitat of several gigabytes, expecting to spend my free time this week poking around getting a feel for how to do my intended analysis.</p>
<p>30 minutes later the analysis was done.</p>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://i0.wp.com/www.seascapemodels.org/posts/2026-08-07-gis-has-changed-forever/global_wetland_map_combined.png?w=578&#038;ssl=1" class="img-fluid figure-img" data-recalc-dims="1"></p>
<figcaption>Draft map where Claude intersected multiple coastal wetland distributions, complete with cool looking hex shaped spatial units</figcaption>
</figure>
</div>
<p>Claude solved what used to be significant and time consuming GIS issues with no help from me. All I gave it was the end goal and reference to a previous workflow for a similar project.</p>
<p>It smoothly addressed complex challenges like geometry self intersections and spatial intersections of raster to vector data. It even ran small-scale tests to identify processing bottlenecks and find the fastest solution for intersecting two large layers.</p>
<section id="headstarts" class="level2">
<h2 class="anchored" data-anchor-id="headstarts">Headstarts</h2>
<p>Now to be fair I should also acknowledge a couple of headstarts Claude had on this project.</p>
<p>The first was my previous workflow for a similar problem (building a predictive model from spatial data). That gave it a rough set of steps to follow. But, my previous workflow was built entirely on vector (polygon) data, whereas the new analysis required working with rasters. So it successfully solved raster to vector issues with no help from me.</p>
<p>I suspect a second big change in the R GIS ecosystem in last 5-10 years has enabled this coding agent success. Credit is due to the developers of core R spatial packages, especially <code>sf</code>, <code>tmap</code> and <code>terra</code>.</p>
<p>These have significantly streamlined spatial processing and mapping in R, making it easier to deal with complex area and distance calculations on the earth’s curved surface and the ubiquitous self-intersection errors that used to cause major traffic jams in GIS work.</p>
<p>Back around 2020 we were compiling global data on coastal wetlands and aligning that for an <a href="https://www.sciencedirect.com/science/article/pii/S1470160X21008062" rel="nofollow" target="_blank">analysis of coastal wetland health</a>. It took a GIS research assistant and part of the time of a supervising post-doc months just to do the spatial processing.</p>
</section>
<section id="do-i-still-need-a-human-gis-assistant-for-spatial-analyses" class="level2">
<h2 class="anchored" data-anchor-id="do-i-still-need-a-human-gis-assistant-for-spatial-analyses">Do I still need a (human) GIS assistant for spatial analyses?</h2>
<p>One of my research students has taught me that perhaps the answer is yes, but the requirements of the role are different.</p>
<p>You see, my student enthusiastically launched his spatial analysis project with a heap of vibe coding in R. I quickly realized he understood very little of what his coding agent had done, and there was no way we could be sure the results were accurate.</p>
<p>Even in my 30 minute success story told above there were AI mistakes I had to check and fix. A big one was a silly duplicate correction for fraction -> percentage that Claude made. So it had overestimated everything by a factor of 100.</p>
<p>My student turned his story around as well. His enthusiasm for the result and for learning, meant he started again. This time, working (slightly) more slowly. He did the reading, learnt the GIS theory and then used the AI agent to redevelop his analysis step-by-step. That way his understanding could keep pace with the code.</p>
<p>Now in a few short months he’s a competent GIS user and map maker. Credit to his attention to detail too, he won’t trust any exciting result without first running thorough checks.</p>
<p>So what I would want now in an RA is someone who is enthusiastic to learn and who excels at rapid self-paced learning.</p>
<p>In the past meetings with the assistant would often be about how to solve the next processing challenge. Meetings with my GIS, R and AI enabled student are very different. They come with 5+ graphs and maps every week and we discuss patterns. He’ll show me a beautifully prepared graph and ask me ‘what do you notice here…’ waiting to see if I spot the anomalies he’s noticed. Then we discuss.</p>
<p>Attention to detail is more important than ever. We can’t rely on failures in the code or workflow as a red flag for errors anymore. The agents are too good at ‘making it work’. We need analysts who don’t cross the finish line of declaring success when they get the first good result, but who are happy to go back and thoroughly explore every alternative interpretation.</p>
<p>So yes, I’ll still hire a GIS research assistant. But the position description has changed. Less “must know <code>sf</code> and <code>terra</code>”, more “must be sceptical of a beautiful map.” The coding is the easy part now. The judgement was always the hard part &#8211; it’s just that the coding used to take so much time that good judgement was required less often.</p>


</section>

 
<div style="border: 1px solid; background: none repeat scroll 0 0 #EDEDED; margin: 1px; font-size: 13px;">
<div style="text-align: center;">To <strong>leave a comment</strong> for the author, please follow the link and comment on their blog: <strong><a href="https://www.seascapemodels.org/posts/2026-08-07-gis-has-changed-forever/"> Seascapemodels</a></strong>.</div>
<hr />
<a href="https://www.r-bloggers.com/" rel="nofollow">R-bloggers.com</a> offers <strong><a href="https://feedburner.google.com/fb/a/mailverify?uri=RBloggers" rel="nofollow">daily e-mail updates</a></strong> about <a title="The R Project for Statistical Computing" href="https://www.r-project.org/" rel="nofollow">R</a> news and tutorials about <a title="R tutorials" href="https://www.r-bloggers.com/how-to-learn-r-2/" rel="nofollow">learning R</a> and many other topics. <a title="Data science jobs" href="https://www.r-users.com/" rel="nofollow">Click here if you're looking to post or find an R/data-science job</a>.

<hr>Want to share your content on R-bloggers?<a href="https://www.r-bloggers.com/add-your-blog/" rel="nofollow"> click here</a> if you have a blog, or <a href="http://r-posts.com/" rel="nofollow"> here</a> if you don't.
</div><strong>Continue reading</strong>: <a href="https://www.r-bloggers.com/2026/08/the-gis-research-assistant-job-has-transformed/">The GIS Research Assistant Job Has Transformed</a>]]></content:encoded>
					
		
		<enclosure url="" length="0" type="" />

		<post-id xmlns="com-wordpress:feed-additions:1">403006</post-id>	</item>
		<item>
		<title>Windows ARM64 comes to R-universe</title>
		<link>https://www.r-bloggers.com/2026/08/windows-arm64-comes-to-r-universe/</link>
		
		<dc:creator><![CDATA[rOpenSci]]></dc:creator>
		<pubDate>Thu, 06 Aug 2026 00:00:00 +0000</pubDate>
				<category><![CDATA[R bloggers]]></category>
		<guid isPermaLink="false">https://ropensci.org/blog/2026/08/06/r-universe-winarm/</guid>

					<description><![CDATA[<p>Attentive package authors already noticed something new in their r-universe page over the past few weeks: R-universe has quietly started building and checking packages for Windows ARM64.</p>
<p>https://ropensci.r-universe.dev/pdftools#checktable<br />
https://cra...</p>
<strong>Continue reading</strong>: <a href="https://www.r-bloggers.com/2026/08/windows-arm64-comes-to-r-universe/">Windows ARM64 comes to R-universe</a>]]></description>
										<content:encoded><![CDATA[<!-- 
<div style="min-height: 30px;">
[social4i size="small" align="align-left"]
</div>
-->

<div style="border: 1px solid; background: none repeat scroll 0 0 #EDEDED; margin: 1px; font-size: 12px;">
[This article was first published on  <strong><a href="https://ropensci.org/blog/2026/08/06/r-universe-winarm/"> rOpenSci - open tools for open science</a></strong>, and kindly contributed to <a href="https://www.r-bloggers.com/" rel="nofollow">R-bloggers</a>].  (You can report issue about the content on this page <a href="https://www.r-bloggers.com/contact-us/">here</a>)
<hr>Want to share your content on R-bloggers?<a href="https://www.r-bloggers.com/add-your-blog/" rel="nofollow"> click here</a> if you have a blog, or <a href="http://r-posts.com/" rel="nofollow"> here</a> if you don't.
</div>

<p>Attentive package authors already noticed something new in their r-universe page over the past few weeks: R-universe has quietly started building and checking packages for Windows ARM64.</p>
<ul>
<li><a href="https://ropensci.r-universe.dev/pdftools#checktable" rel="nofollow" target="_blank">https://ropensci.r-universe.dev/pdftools#checktable</a></li>
<li><a href="https://cran.r-universe.dev/dplyr#checktable" rel="nofollow" target="_blank">https://cran.r-universe.dev/dplyr#checktable</a></li>
<li><a href="https://bioc-release.r-universe.dev/S4Vectors#checktable" rel="nofollow" target="_blank">https://bioc-release.r-universe.dev/S4Vectors#checktable</a></li>
</ul>
<p>R-universe has supported ARM64 on Linux and macOS for some time already, but not Windows. With this addition, packages are now built and checked on both <strong>x86_64</strong> and <strong>ARM64</strong> across all major operating systems, making the R ecosystem fully ARM ready.</p>
<h2>
Porting the R ecosystem to ARM Windows
</h2><p>The R-universe service is part of <a href="https://contributor.r-project.org/windows-arm64/" rel="nofollow" target="_blank">a broader community effort</a> to bring the R ecosystem to Windows ARM64. This project builds on the work from Tomáš Kalibera, whose efforts laid much of the <a href="https://blog.r-project.org/2024/04/23/r-on-64-bit-arm-windows/index.html" rel="nofollow" target="_blank">groundwork</a> for modernizing R on Windows to support UCRT and ARM.</p>
<p>Among other things, the project provides daily builds of <a href="https://github.com/r-devel/windows-arm64/releases#release-devel" rel="nofollow" target="_blank">base R installers</a> for Windows ARM64 (R-release, R-patched, and R-devel), built on GitHub Actions with the <a href="https://cran.r-project.org/bin/windows/Rtools/rtools45/news.html" rel="nofollow" target="_blank">rtools45 toolchain</a>. Because CRAN repositories do not have Windows ARM64 binaries yet, these installers are patched to install binary packages from R-universe instead, so <code>install.packages()</code> just works. There is nothing users need to configure.</p>
<h3>
What we had to fix along the way
</h3><p>Rolling this out on R-universe turned out to be a great way to find out which parts of the ecosystem were not quite ready for Windows on ARM. Some things that needed patching:</p>
<ul>
<li>The base R installers themselves, to pick up ARM64 binaries from the right repository path.</li>
<li>External software such as <a href="https://github.com/r-windows/JAGS/releases/tag/installers" rel="nofollow" target="_blank">JAGS</a>, which needed some changes to compile <code>rjags</code> and <code>runjags</code> for arm.</li>
<li>Rust integration: many R packages using Rust were hard-coding the <code>x86_64-pc-windows-gnu</code> target. The extendr project shipped a fix in <code>extendr-api</code> 0.8.2, and rustup now supports the <code>aarch64-pc-windows-gnullvm</code> target we need.</li>
<li>Big compiled packages like arrow, plus a few dozen other packages with issues such as unconditionally passing <code>-msse</code> compiler flags (ARM chips do not do SSE) or autoconf scripts misdetecting the toolchain.</li>
</ul>
<p>For broken CRAN and Bioconductor packages we maintain a set of <a href="https://github.com/r-devel/windows-arm64/tree/main/patches" rel="nofollow" target="_blank">install-time patches</a>, and we are in the process of upstreaming these fixes to the package maintainers. With these patches in place, the entire R ecosystem now builds on Windows ARM64. <img src="https://s.w.org/images/core/emoji/13.0.0/72x72/1f389.png" alt="🎉" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
<h3>
Testing in the real world
</h3><p>The fact that everything builds does not yet guarantee that everything behaves exactly as expected. We would love help from users to find any loose ends. Hence if you are running Windows on ARM hardware, or you are using a Windows VM on MacOS, we would love for you to take this for a spin.</p>
<p>For package developers there several ways to test packages with compiled code on Windows ARM64. As mentioned, if your package is already on CRAN or BioConductor, you can find binaries and check results on R-universe at <code>https://cran.r-universe.dev/{pkg}</code> or <code>https://bioc.r-universe.dev/{pkg}</code>.</p>
<p>In addition, GitHub Actions provides free <code>windows-11-arm</code> runners, and the standard workflows from <code>r-lib/actions</code> support them out of the box.</p>
<h2>
Helping the ecosystem evolve
</h2><p>This project is exactly one of the reasons for building the R-universe system. Besides providing an open space for developers to publish new software, it also serves as a versatile infrastructure that lets us experiment with new tooling and platforms to help move the ecosystem forward as a whole. Having an automated platform that continuously builds thousands of packages made it possible to find those missing pieces, fix them, and iterate quickly.</p>
<p>By identifying and fixing the main hurdles now, we want to help package authors address the problems before they hit end-users, and pave the way for a smooth introduction of Windows ARM64 support on mainstream repositories such as CRAN and Posit Package Manager when the time is ready.</p>
<div style="border: 1px solid; background: none repeat scroll 0 0 #EDEDED; margin: 1px; font-size: 13px;">
<div style="text-align: center;">To <strong>leave a comment</strong> for the author, please follow the link and comment on their blog: <strong><a href="https://ropensci.org/blog/2026/08/06/r-universe-winarm/"> rOpenSci - open tools for open science</a></strong>.</div>
<hr />
<a href="https://www.r-bloggers.com/" rel="nofollow">R-bloggers.com</a> offers <strong><a href="https://feedburner.google.com/fb/a/mailverify?uri=RBloggers" rel="nofollow">daily e-mail updates</a></strong> about <a title="The R Project for Statistical Computing" href="https://www.r-project.org/" rel="nofollow">R</a> news and tutorials about <a title="R tutorials" href="https://www.r-bloggers.com/how-to-learn-r-2/" rel="nofollow">learning R</a> and many other topics. <a title="Data science jobs" href="https://www.r-users.com/" rel="nofollow">Click here if you're looking to post or find an R/data-science job</a>.

<hr>Want to share your content on R-bloggers?<a href="https://www.r-bloggers.com/add-your-blog/" rel="nofollow"> click here</a> if you have a blog, or <a href="http://r-posts.com/" rel="nofollow"> here</a> if you don't.
</div><strong>Continue reading</strong>: <a href="https://www.r-bloggers.com/2026/08/windows-arm64-comes-to-r-universe/">Windows ARM64 comes to R-universe</a>]]></content:encoded>
					
		
		<enclosure url="" length="0" type="" />

		<post-id xmlns="com-wordpress:feed-additions:1">402999</post-id>	</item>
		<item>
		<title>The Journey of {nycOpenData}: From Classroom to Community</title>
		<link>https://www.r-bloggers.com/2026/08/the-journey-of-nycopendata-from-classroom-to-community/</link>
		
		<dc:creator><![CDATA[rOpenSci]]></dc:creator>
		<pubDate>Thu, 06 Aug 2026 00:00:00 +0000</pubDate>
				<category><![CDATA[R bloggers]]></category>
		<guid isPermaLink="false">https://ropensci.org/blog/2026/08/06/the-journey-of-nycopendata-from-classroom-to-community/</guid>

					<description><![CDATA[<p>FADE IN<br />
Nine students in the M.S. in Psychology Research program at Brooklyn College, New York City (NYC), USA are taking the course Reproducible Psychological Research, where they are learning how to code for the first time. All of them have their c...</p>
<strong>Continue reading</strong>: <a href="https://www.r-bloggers.com/2026/08/the-journey-of-nycopendata-from-classroom-to-community/">The Journey of {nycOpenData}: From Classroom to Community</a>]]></description>
										<content:encoded><![CDATA[<!-- 
<div style="min-height: 30px;">
[social4i size="small" align="align-left"]
</div>
-->

<div style="border: 1px solid; background: none repeat scroll 0 0 #EDEDED; margin: 1px; font-size: 12px;">
[This article was first published on  <strong><a href="https://ropensci.org/blog/2026/08/06/the-journey-of-nycopendata-from-classroom-to-community/"> rOpenSci - open tools for open science</a></strong>, and kindly contributed to <a href="https://www.r-bloggers.com/" rel="nofollow">R-bloggers</a>].  (You can report issue about the content on this page <a href="https://www.r-bloggers.com/contact-us/">here</a>)
<hr>Want to share your content on R-bloggers?<a href="https://www.r-bloggers.com/add-your-blog/" rel="nofollow"> click here</a> if you have a blog, or <a href="http://r-posts.com/" rel="nofollow"> here</a> if you don't.
</div>

<h2>
FADE IN
</h2><p>Nine students in the M.S. in Psychology Research program at Brooklyn College, New York City (NYC), USA are taking the course <em>Reproducible Psychological Research</em>, where they are learning how to code for the first time. All of them have their cameras off. They are all learning R for the first time, and as an introduction to R, are being taught using the <code>mtcars</code> dataset.</p>
<p>Nine <strong>NYC</strong> graduate students who</p>
<ul>
<li>don’t own a car,</li>
<li>don’t drive a car,</li>
<li>and have no interest in cars.</li>
</ul>
<p>Even with their screens off, with every additional <code>mtcars</code> column we talked about, they fell deeper and deeper asleep during the lectures.</p>
<blockquote>
<p>If I wanted my students to learn anything in my class—not just R—I needed to make an immediate pivot.</p>
</blockquote>
<p>Change needed to happen, and happen fast.</p>
<h2>
Relevance drives rigor
</h2><p>I didn’t take my students’ interests into consideration at the start of the course, and I was paying the price. How do I make sure that no matter what each individual student is interested in, they can be accommodated? Probably a big ask, but part of me felt like I was starting the semester in debt and needed to really pay up.</p>
<p>What do all my students have <em>in common</em>? <strong>They all live in NYC</strong>. Even if they’re not from NYC, they currently call it home.</p>
<p>Then came the idea:</p>
<blockquote>
<p><img src="https://s.w.org/images/core/emoji/13.0.0/72x72/1f4a1.png" alt="💡" class="wp-smiley" style="height: 1em; max-height: 1em;" /> What if I incorporate NYC Open Data into the course?</p>
</blockquote>
<p>For anyone who doesn’t know, NYC does an incredible job of making public data available through the <a href="https://opendata.cityofnewyork.us/" rel="nofollow" target="_blank">NYC Open Data Portal</a>. Thousands of datasets, ranging from 311 calls to transportation data to slashings and stabbings (a favorite of one of my students), are available for free, for anyone, anywhere.</p>
<p>Immediately, there was a switch in my (virtual) classroom. Before, engagement was about as close to zero as you can get. Now, it skyrocketed. Students were asking more questions, which was great.</p>
<p>There were really only two options when it came to using NYC Open Data. The first, which I began using, was downloading static datasets as Excel or CSV files. While this helped with engagement, it also created a new set of problems: using outdated datasets (311, for instance, is updated daily), making sure students downloaded the correct files, and making sure they put them in the correct folders.</p>
<p>Luckily, the portal offers a fantastic solution to all of the problems associated with accessing static files: APIs!</p>
<p>However, this came with an even bigger problem:</p>
<blockquote>
<p>In this class, I had to teach R, statistics, reproducible workflows, data analysis, data cleaning, data visualization, writing, interpretation, and really an innumerable number of additional skills. Did I really want to add APIs to this list?</p>
</blockquote>
<p>Cue an idea.</p>
<h2>
<code>nycOpenData</code>: The beginning
</h2><p>At this point, I knew a few things:</p>
<ol>
<li>Students need relevant data in order to stay engaged.</li>
<li>Students really enjoyed using NYC Open Data.</li>
<li>My students’ heads may explode if I teach them about APIs.</li>
</ol>
<p>So I started thinking:</p>
<blockquote>
<p>How do I incorporate NYC Open Data into the classroom moving forward without using APIs or static files?</p>
</blockquote>
<p><em>What if I make a package?</em></p>
<p>Students are learning R, which means we’re also learning about packages—a crucial, yet simple, concept. What if there was a package dedicated to pulling NYC Open Data? That would fit right into the students’ learning path.</p>
<p>When I looked, there wasn’t one.</p>
<p>So I thought:</p>
<p><em>Why not make it myself?</em></p>
<p>Maybe a crazy idea. I had never developed an R package, never mind one that relied on APIs. What does the process look like? Do I have the skills? Will CRAN accept something that most likely only my nine students and I would ever use?</p>
<p>As a big believer in the mantra, <em>“I’ll do it myself,”</em> I already had the code to pull in the individual datasets in R, so… why not?</p>
<p>So, I went ahead and did it myself.</p>
<h2>
<code>nycOpenData</code>: The middle
</h2><p>Originally, I thought the easiest thing to do was build the package with one function: <code>nyc_311()</code>, which would simply pull in the 311 dataset. The perk was that it was one of the largest and most data-diverse datasets, so it could kill many birds with one stone.</p>
<p>But then I thought,</p>
<blockquote>
<p>“No way will CRAN accept a package with just one function.”</p>
</blockquote>
<p>So, I literally copied and pasted the same exact code 30 different times and adapted it for the 30 most popular datasets on the NYC Open Data Portal.</p>
<p>Through a lot of blood, sweat, and documentation, the first iteration of <a href="https://docs.ropensci.org/nycOpenData/index.html" rel="nofollow" target="_blank"><code>nycOpenData</code></a> was officially created and accepted onto CRAN! I, a person who only installed packages, was now the creator of one? It was amazing to actually give back to the marvelous R community that provided me with so much for so many years.</p>
<p>This not only made teaching with NYC Open Data easier, but more fun too. The package did exactly what it needed to do: make working with NYC Open Data datasets incredibly easy in R.</p>
<p>With this version of <code>nycOpenData</code>, students were able to complete their final projects with one simple prompt:</p>
<blockquote>
<p>Answer any question you have about NYC using open data.</p>
</blockquote>
<p>Those projects eventually became the <a href="https://martinezc1-nyc-open-data-student-gallery.share.connect.posit.cloud/" rel="nofollow" target="_blank">NYC Open Data Student Gallery Book</a>, which was presented at <a href="https://www.youtube.com/watch?v=Vw8PhY7NDGE" rel="nofollow" target="_blank">NYC Open Data Week 2026</a>. Each student’s project became its own chapter, and each student had the opportunity to present their work to the world. These same students who were once falling asleep while I basically sang them a lullaby, now were very much awake, displaying what they’ve learned and uncovered to an audience of professionals.</p>
<p>As an educator, my goal is to help my students be as successful as possible. Through <code>nycOpenData</code>, that goal became a reality.</p>
<p>All of the work I put into this package was worth it.</p>
<h2>
<code>nycOpenData</code>: Student contributions
</h2><p>The following semester, I had the opportunity to teach a follow-up class to the same cohort. Then came another crazy idea:</p>
<blockquote>
<p>What if the same students who used <code>nycOpenData</code> to not only learn, but also conduct research, contributed to the same infrastructure they utilized?</p>
</blockquote>
<p>Basically, what if I helped my students contribute to the <code>nycOpenData</code> package?</p>
<p>This would be similar to what a junior software developer might do. Using my code as a template, they could build their own functions for whatever dataset they were interested in. The package already had 30 functions—what’s another nine?</p>
<p>Through light introductions to GitHub, package development, and open-source software, each of my students successfully contributed their own function to the <code>nycOpenData</code> package. Suddenly, they weren’t just users of open-source software—they were contributors.</p>
<p>Good thing I didn’t do this last semester, as that would have guaranteed brain explosions from my students.</p>
<h2>
<code>nycOpenData</code>: rOpenSci
</h2><p>As time progressed, and as I assessed the student contributions, I became more familiar with package development. Wanting the best product possible, I decided to submit the package to rOpenSci through its <a href="https://github.com/ropensci/software-review/issues/750#issuecomment-5007655734" rel="nofollow" target="_blank"><strong>public peer review process</strong></a>. I was a first-time package developer and wanted guidance from people who had far more experience than I did. I wanted anyone—whether my students or someone using the package halfway around the world—to have the best experience possible. After all, the goal was to make NYC Open Data more accessible for <em>anyone</em>. To go from helping just my students, to my students helping, to potentially helping the overall R community through rOpenSci—I would have never guessed this trajectory.</p>
<p>This ended up being one of the best experiences I’ve had as a programmer.</p>
<p>The review process didn’t simply determine whether the package was ready—it made the package better. Every suggestion strengthened the documentation, improved the user experience, and taught me something new about developing open-source software.</p>
<p><strong>First of all, my editor and reviewers told me exactly what I needed to hear:</strong></p>
<blockquote>
<p>Having 39 functions that basically do the same thing is not only unmanageable, but bad code.</p>
</blockquote>
<p>Which was 100% the truth.</p>
<p>And, if I’m being honest, the package itself came about while I was teaching a course on reproducibility. I was literally teaching my students that copy-and-paste was <em>not</em> something to do, while I was doing the exact same thing. Sure, I brushed it off because I needed to put something together quickly, but it was time to face the facts and fix it.</p>
<p>With that came good news and bad news. As for every action, there is an equal and opposite reaction:</p>
<ul>
<li>The <em>good</em> news: I was able to turn the 39 functions into just 3. Now, all 2,000+ datasets can be pulled from the portal. Easier to maintain, easier for users to understand, and overall a much better product.</li>
<li>The <em>bad</em> news: All of my students’ work was now gone. (Sad face.)</li>
</ul>
<p>Thanks to the thoughtful feedback and hard work of the editor, reviewers, and everyone involved in the review process, <code>nycOpenData</code> was successfully accepted into rOpenSci—an indescribable privilege. I honestly can’t believe the journey from where the package started to where it is today.</p>
<p>I am especially grateful to my editor, <a href="https://ropensci.org/author/ronny-hernandez-mora/" rel="nofollow" target="_blank"><strong>Ronny Hernandez Mora</strong></a>, and reviewers, <a href="https://scholar.google.com/citations?hl=en&#038;user=5GTf-McAAAAJ" rel="nofollow" target="_blank"><strong>Haolin Dong</strong></a> and <a href="https://github.com/MichaelPascale" rel="nofollow" target="_blank"><strong>Michael Pascale</strong></a>, for the time, care, and thoughtful feedback they invested throughout the review. As a first-time package developer, I couldn’t have asked for a better introduction to open-source software development.
With the foundation finally built, another thought entered my mind:</p>
<blockquote>
<p>Can we use this same infrastructure for other open data portals?</p>
</blockquote>
<p>Turns out, you can!</p>
<h2>
The OpenData Ecosystem
</h2><p>With the infrastructure in place, another realization hit me: I never had to build it from scratch again.</p>
<p>The same foundation that powered <code>nycOpenData</code> could be adapted to other open data portals, making it possible to create an entire ecosystem of OpenData packages.</p>
<blockquote>
<p>If students in NYC were motivated by using data regarding their own city, why wouldn’t the same hold true for students in other cities?</p>
</blockquote>
<p>Since then, four additional packages have been built, turning one package into an ecosystem:</p>
<ul>
<li><a href="https://martinezc1.github.io/nysOpenData/" rel="nofollow" target="_blank"><code>nysOpenData</code></a> — New York State Open Data</li>
<li><a href="https://martinezc1.github.io/mtaOpenData/" rel="nofollow" target="_blank"><code>mtaOpenData</code></a> — Metropolitan Transportation Authority Open Data</li>
<li><a href="https://martinezc1.github.io/laOpenData/" rel="nofollow" target="_blank"><code>laOpenData</code></a> — Los Angeles Open Data</li>
<li><a href="https://martinezc1.github.io/chiOpenData/" rel="nofollow" target="_blank"><code>chiOpenData</code></a> — Chicago Open Data</li>
<li><a href="https://martinezc1.github.io/ausOpenData/" rel="nofollow" target="_blank"><code>ausOpenData</code></a> — Austin Open Data</li>
</ul>
<p>The ecosystem continues to grow. A former student and I recently collaborated on the <code>ausOpenData</code> package (which was just recently accepted to CRAN), and a current intern at the <a href="https://nycopendatalab.org/" rel="nofollow" target="_blank">NYC Open Data Lab</a> is building <a href="https://github.com/gomes-sh/sfOpenData" rel="nofollow" target="_blank"><code>sfOpenData</code></a> and <a href="https://github.com/gomes-sh/SeattleOpenData" rel="nofollow" target="_blank"><code>SeattleOpenData</code></a><code>.</code> This not only gives others an opportunity to contribute, but also gives me a chance to continue involving students in the ecosystem after the original <code>nycOpenData</code> functions were “refactored.”</p>
<p>Hopefully, there are many more to come. The hard part is no longer building packages—it is deciding which open data portal comes next.</p>
<h2>
<code>nycOpenData</code>: The Final Product
</h2><p>What started as a single function has turned into six OpenData packages, one of which has been successfully peer-reviewed by rOpenSci, with the others built on the same foundation. <em>Tens of billions</em> of rows of public data, from across the country, are now easily accessible in R for anyone—from researchers and journalists to students and educators.</p>
<p>Looking back, I think this journey embodies the spirit of R.</p>
<p>One of the best things about R is that it is open source. Anyone with an idea can contribute, and those ideas have a way of growing into something much bigger than originally imagined. This entire ecosystem started because nine graduate students didn’t care about the <code>mtcars</code> dataset.</p>
<p>On top of that, the tools used to build this ecosystem were free and open source, and the packages themselves are freely available to anyone. In my family we say, <em>“If it’s for free, it’s for me.”</em></p>
<p>What started in one virtual classroom ended up bringing together students, educators, reviewers, professionals, interns, and thousands of people who have since installed the packages.</p>
<p>Through this entire process, the biggest lesson learned was:</p>
<blockquote>
<p>Relevance isn’t a reward for learning—it is what enables learning.</p>
</blockquote>
<h2>
To my students
</h2><p>While this story has my name attached to it, it wouldn’t exist without students who were willing to try something new, contribute code, ask questions, and occasionally tolerate my crazy ideas. When we started the course, I asked you all to keep an open mind and try something new-and I never would ask you to do something that I wouldn’t.</p>
<p>Thank you for trusting me when I asked you to do something different.</p>
<h2>
FADE OUT
</h2>
<div style="border: 1px solid; background: none repeat scroll 0 0 #EDEDED; margin: 1px; font-size: 13px;">
<div style="text-align: center;">To <strong>leave a comment</strong> for the author, please follow the link and comment on their blog: <strong><a href="https://ropensci.org/blog/2026/08/06/the-journey-of-nycopendata-from-classroom-to-community/"> rOpenSci - open tools for open science</a></strong>.</div>
<hr />
<a href="https://www.r-bloggers.com/" rel="nofollow">R-bloggers.com</a> offers <strong><a href="https://feedburner.google.com/fb/a/mailverify?uri=RBloggers" rel="nofollow">daily e-mail updates</a></strong> about <a title="The R Project for Statistical Computing" href="https://www.r-project.org/" rel="nofollow">R</a> news and tutorials about <a title="R tutorials" href="https://www.r-bloggers.com/how-to-learn-r-2/" rel="nofollow">learning R</a> and many other topics. <a title="Data science jobs" href="https://www.r-users.com/" rel="nofollow">Click here if you're looking to post or find an R/data-science job</a>.

<hr>Want to share your content on R-bloggers?<a href="https://www.r-bloggers.com/add-your-blog/" rel="nofollow"> click here</a> if you have a blog, or <a href="http://r-posts.com/" rel="nofollow"> here</a> if you don't.
</div><strong>Continue reading</strong>: <a href="https://www.r-bloggers.com/2026/08/the-journey-of-nycopendata-from-classroom-to-community/">The Journey of {nycOpenData}: From Classroom to Community</a>]]></content:encoded>
					
		
		<enclosure url="" length="0" type="" />

		<post-id xmlns="com-wordpress:feed-additions:1">402989</post-id>	</item>
		<item>
		<title>Introducing the Bioconductor Student-ECR Council</title>
		<link>https://www.r-bloggers.com/2026/08/introducing-the-bioconductor-student-ecr-council/</link>
		
		<dc:creator><![CDATA[Carissa Chen]]></dc:creator>
		<pubDate>Thu, 06 Aug 2026 00:00:00 +0000</pubDate>
				<category><![CDATA[R bloggers]]></category>
		<guid isPermaLink="false">https://blog.bioconductor.org/posts/2026-08-06-student-ecr-intro/</guid>

					<description><![CDATA[<div style = "width:60%; display: inline-block; float:left; ">
<p>Announcing the Bioconductor Student-ECR Council<br />
From an idea that hatched during the EuroBioC2026 Birds of a Feather session, we are super excited to announce the formation of the Student-ECR Council!</p>
<p>As a newly established Council, we aim...</p></div>
<div style = "width: 40%; display: inline-block; float:right;"></div>
<div style="clear: both;"></div>
<strong>Continue reading</strong>: <a href="https://www.r-bloggers.com/2026/08/introducing-the-bioconductor-student-ecr-council/">Introducing the Bioconductor Student-ECR Council</a>]]></description>
										<content:encoded><![CDATA[<!-- 
<div style="min-height: 30px;">
[social4i size="small" align="align-left"]
</div>
-->

<div style="border: 1px solid; background: none repeat scroll 0 0 #EDEDED; margin: 1px; font-size: 12px;">
[This article was first published on  <strong><a href="https://blog.bioconductor.org/posts/2026-08-06-student-ecr-intro/"> Bioconductor community blog</a></strong>, and kindly contributed to <a href="https://www.r-bloggers.com/" rel="nofollow">R-bloggers</a>].  (You can report issue about the content on this page <a href="https://www.r-bloggers.com/contact-us/">here</a>)
<hr>Want to share your content on R-bloggers?<a href="https://www.r-bloggers.com/add-your-blog/" rel="nofollow"> click here</a> if you have a blog, or <a href="http://r-posts.com/" rel="nofollow"> here</a> if you don't.
</div>
 





<section id="announcing-the-bioconductor-student-ecr-council" class="level2">
<h2 class="anchored" data-anchor-id="announcing-the-bioconductor-student-ecr-council">Announcing the Bioconductor Student-ECR Council</h2>
<p>From an idea that hatched during the EuroBioC2026 Birds of a Feather session, we are super excited to announce the formation of the <a href="https://workinggroups.bioconductor.org/currently-active-working-groups-committees.html#early-career-council" rel="nofollow" target="_blank">Student-ECR Council</a>!</p>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://i1.wp.com/blog.bioconductor.org/posts/2026-08-06-student-ecr-intro/student-ecr-logo.png?w=250&#038;ssl=1" class="img-fluid quarto-figure quarto-figure-center figure-img" alt="Student-ECR Council logo featuring symbols of mentorship, community, events, networking, and career development within Bioconductor."  data-recalc-dims="1"></p>
</figure>
</div>
<p>As a newly established Council, we aim to support <strong>students and early-career researchers (ECRs)</strong> in the Bioconductor community by providing a platform that brings together <strong>developers and data scientists</strong> through mentorship, networking, and professional development opportunities.</p>
</section>
<section id="meet-the-council-members" class="level2">
<h2 class="anchored" data-anchor-id="meet-the-council-members">Meet the Council members</h2>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://i0.wp.com/blog.bioconductor.org/posts/2026-08-06-student-ecr-intro/first-zoom.jpg?w=578&#038;ssl=1" class="img-fluid figure-img" alt="Screenshot of participants at the first virtual Student-ECR Council meeting" data-recalc-dims="1"></p>
<figcaption>The first virtual Student-ECR Council meeting on 21st July, 2026.</figcaption>
</figure>
</div>
<ul>
<li><strong>Carissa Chen</strong> (Postdoctoral Researcher at University of Padova, Italy)</li>
</ul>
<p>I am a computational biologist with a background in molecular biology and bioinformatics. My current research combines deep learning and statistical methods to jointly analyse sub-cellular spatial transcriptomics and histology images. I have been a long-time user of Bioconductor packages and I am now taking my first steps into computational method development. By joining the Student-ECR Council, I hope to support interdisciplinary researchers like myself to navigate the Bioconductor community.</p>
<ul>
<li><strong>Guillaume Deflandre</strong> (PhD student at UCLouvain in Brussels, Belgium)</li>
</ul>
<p>I am a computational biologist with a background in bio-engineering. Initially out of touch with the biomedical field, I took a leap of faith during my Master’s thesis and absolutely loved it! Since then, I have been doing research on how to optimise peptidoform identification in single-cell proteomics. As soon as I delved into this world of bioinformatics, I was introduced to Bioconductor, its packages and its community. They have helped me so much so far, and by joining the Student-ECR Council, I hope to help other researchers in the same way.</p>
<ul>
<li><strong>Jasper Spitzer</strong> (Postdoctoral Researcher at the University of Bonn, Germany)</li>
</ul>
<p>I am a computational biologist with a background in immunology. Throughout my PhD, I’ve focused increasingly on computational work and am now 100% on the computational side. Currently, I am working on large-scale CRISPR screen data as well as single-cell projects and am generally interested in how structure in data can be translated into biology. I’ve been a long-time user of Bioconductor packages and have recently tried to be a more active member of the community. With the positive experience I’ve had in the community, I want to share that fun and excitement by encouraging others to be a part of the community as well.</p>
<ul>
<li><strong>Sophie-Marie Wind</strong> (PhD student at University of Münster, Germany)</li>
</ul>
<p>I am a bioinformatician with a focus on high-throughput data analysis and method development. Currently, I am developing an analysis framework for 4C-seq data. My first contact with Bioconductor was during my master’s studies, when I used Bioconductor packages for data analyses. During my PhD, I became more involved in package development and came to appreciate the supportive and inspiring Bioconductor community. This experience motivated me to become more actively involved. As a member of the Student-ECR Council, I hope to share my enthusiasm for bioinformatics, contribute to the community, and help support other early-career researchers.</p>
<ul>
<li><strong>Kateřina Matějková</strong> (PhD student at Charles University in Prague, Czech Republic)</li>
</ul>
<p>I am a computational biologist with a background in molecular biology and genetics. My research focuses on splicing analysis in Mendelian diseases. I was first introduced to Bioconductor packages during my Master’s, and during my PhD, I joined EuroBioC. I deeply appreciate the supportive and collaborative nature of this community. Currently, we are working to establish a Czech BioC community and create educational initiatives to support early career researchers working at the intersection of biology and informatics.</p>
<ul>
<li><strong>Nyasita Ondari</strong> (Research Associate at International Institute of Tropical Agriculture (IITA), Nairobi, Kenya)</li>
</ul>
<p>I am a bioinformatician focused on building pipelines and workflows for the analysis of large-scale biological data. I have a background in bioinformatics and medical biochemistry. My first introduction to Bioconductor came during my MSc, where I used its packages to analyse my data in R. Since then, my involvement has grown. In March 2025, I instructed the first Bioconductor workshop ever held in Africa, in Nairobi. Today, I lead the <a href="https://training.bioconductor.org/seminars/bioc-africa/" rel="nofollow" target="_blank">Bioconductor Africa Seminar Series</a> and support community engagement and social media across the Bioconductor project.</p>
</section>
<section id="our-vision" class="level2">
<h2 class="anchored" data-anchor-id="our-vision">Our vision</h2>
<p>We aim to create an <strong>inclusive and diverse environment</strong> for students and early-career researchers in the Bioconductor community, from those <strong>discovering Bioconductor for the first time to long-time users and developers</strong> of Bioconductor packages.</p>
<p>Using this platform, our goal is to create opportunities for early-career researchers (ECRs) to connect with one another, cultivating a <strong>positive and supportive</strong> community that embraces <strong>open science</strong> and <strong>reproducible research</strong> practices. We also aim to empower researchers to <strong>contribute</strong> to Bioconductor projects, <strong>strengthening transparency</strong> and <strong>encouraging community-driven software development</strong>. At the same time, we hope to strengthen the <strong>feedback loop between users and developers</strong>, encouraging collaboration and helping shape and continuously improve the Bioconductor ecosystem.</p>
<p>A few of our proposed initiatives include:</p>
<ul>
<li><u>Mentorship programme</u> providing peer support alongside technical guidance on areas such as package development, coding best practices, and contributing to Bioconductor</li>
<li><u>Targeted seminars</u> covering dissemination of the latest research and career panels</li>
<li><u>Workshops</u> such as community-contributed package demonstrations</li>
<li><u>“Good First Issue” hackathons</u> to help new contributors gain experience by working on beginner-friendly issues</li>
</ul>
<p>…and more!</p>
<p>As we’re just getting started, <strong>we would also love to hear your ideas</strong> for future events and initiatives! If you have any suggestions, please take a few minutes to fill in our <a href="https://forms.gle/KQfGcs3ALAPhCYws6" rel="nofollow" target="_blank">poll</a>.</p>
<p>To be notified about upcoming activities, please subscribe to our <a href="https://community-bioc.zulipchat.com/#narrow/channel/611088-student-ecr" rel="nofollow" target="_blank">Zulip channel</a>!</p>
</section>
<section id="bioconductor-mentorship-programme" class="level2">
<h2 class="anchored" data-anchor-id="bioconductor-mentorship-programme">Bioconductor Mentorship Programme</h2>
<p>We are launching the Bioconductor Mentorship Programme and are looking for both <strong>mentees and mentors</strong> for the upcoming intake (tentatively <strong>October/November</strong>). The proposed focus areas may include:</p>
<ul>
<li><u>Package development</u>: developing R scripts to a fully fledged Bioconductor package</li>
<li><u>Technical development</u>: guidance on coding best practices, contributing to existing packages, and navigating the Bioconductor development community.</li>
<li><u>Peer mentoring</u>: managing a PhD, career advice and more. Other areas TBC depending on interest, so please let us know if there are any specific areas you would benefit from!</li>
</ul>
<p>If you are interested in participating in the Bioconductor Mentorship Programme, please express your interest <a href="https://forms.gle/UetvHcEPfai5pMd78" rel="nofollow" target="_blank">here</a>.</p>
</section>
<section id="join-us" class="level2">
<h2 class="anchored" data-anchor-id="join-us">Join us!</h2>
<p>We welcome anyone from <strong>all career stages and scientific backgrounds</strong> to join the Council. Specifically, Council members are people who choose to take an active role, for example by attending meetings when they can and helping to plan or deliver activities according to their interests and availability.</p>
<p>Feel free to pop by our regular Council meetings on the <a href="https://bioconductor.org/help/events/" class="underline" rel="nofollow" target="_blank">third Tuesday of every month at 9am CET</a> to learn more. As we are welcoming new members who may be from different timezones, the meeting time is amenable to change so please don’t hesitate to contact us.</p>
<p>If you are interested in joining the Student-ECR Council, please connect with us on our dedicated <a href="https://community-bioc.zulipchat.com/#narrow/channel/611088-student-ecr" rel="nofollow" target="_blank">Zulip channel</a>, or reach out to us via <a href="https://blog.bioconductor.org/posts/2026-08-06-student-ecr-intro/student-ecr@bioconductor.org" rel="nofollow" target="_blank">email</a>.</p>
<p>Or just say hi and <a href="https://community-bioc.zulipchat.com/#narrow/channel/611088-student-ecr/topic/Welcome.20and.20overview/with/604108019" rel="nofollow" target="_blank">introduce yourself on Zulip</a>! (We need more friends!)</p>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://i0.wp.com/blog.bioconductor.org/posts/2026-08-06-student-ecr-intro/help-us-grow.jpg?w=578&#038;ssl=1" class="img-fluid quarto-figure quarto-figure-center figure-img" alt="Stick man holding megaphone with text: 'Help us grow!'" data-recalc-dims="1"></p>
</figure>
</div>
</section>
<section id="bioc2026-in-seattle" class="level2">
<h2 class="anchored" data-anchor-id="bioc2026-in-seattle">BioC2026 in Seattle</h2>
<p>We will be holding a live Q&#038;A and casual Student-ECR gathering during <a href="https://bioc2026.bioconductor.org/schedule/" rel="nofollow" target="_blank">BioC2026 on Tuesday, August 11, from 8:30 to 9:00 am PT</a>. Members of the Council will join by Zoom to meet attendees and answer questions following their pre-recorded lightning talk on Monday. Come along to meet other ECRs in the Bioconductor community and learn more about how to get involved with the Student-ECR Council!</p>


</section>

<p>
© 2026 Bioconductor. Content is published under <a href="https://creativecommons.org/licenses/by/4.0/" rel="nofollow" target="_blank">Creative Commons CC-BY-4.0 License</a> for the text and <a href="https://opensource.org/licenses/BSD-3-Clause" rel="nofollow" target="_blank">BSD 3-Clause License</a> for any code. | <a href="https://www.r-bloggers.com/" rel="nofollow" target="_blank">R-Bloggers</a>
</p> 
<div style="border: 1px solid; background: none repeat scroll 0 0 #EDEDED; margin: 1px; font-size: 13px;">
<div style="text-align: center;">To <strong>leave a comment</strong> for the author, please follow the link and comment on their blog: <strong><a href="https://blog.bioconductor.org/posts/2026-08-06-student-ecr-intro/"> Bioconductor community blog</a></strong>.</div>
<hr />
<a href="https://www.r-bloggers.com/" rel="nofollow">R-bloggers.com</a> offers <strong><a href="https://feedburner.google.com/fb/a/mailverify?uri=RBloggers" rel="nofollow">daily e-mail updates</a></strong> about <a title="The R Project for Statistical Computing" href="https://www.r-project.org/" rel="nofollow">R</a> news and tutorials about <a title="R tutorials" href="https://www.r-bloggers.com/how-to-learn-r-2/" rel="nofollow">learning R</a> and many other topics. <a title="Data science jobs" href="https://www.r-users.com/" rel="nofollow">Click here if you're looking to post or find an R/data-science job</a>.

<hr>Want to share your content on R-bloggers?<a href="https://www.r-bloggers.com/add-your-blog/" rel="nofollow"> click here</a> if you have a blog, or <a href="http://r-posts.com/" rel="nofollow"> here</a> if you don't.
</div><strong>Continue reading</strong>: <a href="https://www.r-bloggers.com/2026/08/introducing-the-bioconductor-student-ecr-council/">Introducing the Bioconductor Student-ECR Council</a>]]></content:encoded>
					
		
		<enclosure url="https://blog.bioconductor.org/posts/2026-08-06-student-ecr-intro/first-zoom.jpg" length="0" type="image/jpeg" />

		<post-id xmlns="com-wordpress:feed-additions:1">402987</post-id>	</item>
		<item>
		<title>Is SAS Still Used, and Is It Worth Keeping?</title>
		<link>https://www.r-bloggers.com/2026/08/is-sas-still-used-and-is-it-worth-keeping/</link>
		
		<dc:creator><![CDATA[The Jumping Rivers Blog]]></dc:creator>
		<pubDate>Wed, 05 Aug 2026 23:59:00 +0000</pubDate>
				<category><![CDATA[R bloggers]]></category>
		<guid isPermaLink="false">https://www.jumpingrivers.com/blog/is-sas-worth-keeping/</guid>

					<description><![CDATA[<div style = "width:60%; display: inline-block; float:left; ">
<p>SAS is almost 50 years old. It predates the web, and it predates most of the open source tools data teams reach for today. While old, it is not obsolete. SAS remains central to clinical research, banking, insurance and other regulated industries,...</p></div>
<div style = "width: 40%; display: inline-block; float:right;"></div>
<div style="clear: both;"></div>
<strong>Continue reading</strong>: <a href="https://www.r-bloggers.com/2026/08/is-sas-still-used-and-is-it-worth-keeping/">Is SAS Still Used, and Is It Worth Keeping?</a>]]></description>
										<content:encoded><![CDATA[<!-- 
<div style="min-height: 30px;">
[social4i size="small" align="align-left"]
</div>
-->

<div style="border: 1px solid; background: none repeat scroll 0 0 #EDEDED; margin: 1px; font-size: 12px;">
[This article was first published on  <strong><a href="https://www.jumpingrivers.com/blog/is-sas-worth-keeping/"> The Jumping Rivers Blog</a></strong>, and kindly contributed to <a href="https://www.r-bloggers.com/" rel="nofollow">R-bloggers</a>].  (You can report issue about the content on this page <a href="https://www.r-bloggers.com/contact-us/">here</a>)
<hr>Want to share your content on R-bloggers?<a href="https://www.r-bloggers.com/add-your-blog/" rel="nofollow"> click here</a> if you have a blog, or <a href="http://r-posts.com/" rel="nofollow"> here</a> if you don't.
</div>

<p>
<a href = "https://www.jumpingrivers.com/blog/is-sas-worth-keeping/">
<img src="https://www.jumpingrivers.com/blog/is-sas-worth-keeping/" width="400" style="width:400px" class="image-center" style="display: block; margin: auto;" />
</a>
</p>
<p>SAS is almost 50 years old. It predates the web, and it predates most of the open source tools data teams reach for today. While old, it is not obsolete. SAS remains central to clinical research, banking, insurance and other regulated industries, and those organisations do not keep it because it is new. They keep it because it is trusted, governed and built into critical processes.</p>
<p>So its age is beside the point. What matters is whether your organisation would benefit from open source for critical processes and whether it can be trusted. Some teams are already <a href="https://www.jumpingrivers.com/case-studies/nhs-scotland-r-training/" rel="nofollow" target="_blank">moving off it</a>, and the useful question today is: Can regulated industries trust open source, and which of your workloads should adopt it?</p>
<h2 id="why-sas-lasted">Why SAS lasted</h2>
<p>Software survives when organisations trust it, and that matters most where mistakes are expensive.</p>
<p>Clinical research is a clear example. The US FDA defines the <a href="https://www.fda.gov/industry/fda-data-standards-advisory-board/study-data-standards-resources" rel="nofollow" target="_blank">formats it accepts</a> for electronic study data, and those standards include SAS transport files alongside CDISC data models. The FDA does not require sponsors to run their analysis in SAS; the requirement applies to the format used to submit data. But submission standards shape working practices. Over time, organisations have built SAS-based processes around these requirements, including standard outputs, controlled datasets, audit trails and reproducible analysis. The FDA also asks sponsors to provide the <a href="https://www.fda.gov/media/133219/download" rel="nofollow" target="_blank">software programs</a> used for certain efficacy analyses, so reviewers can reproduce the results. In that setting, reproducibility sits at the heart of the process.</p>
<p>Banking and insurance follow the same pattern. Credit risk models and regulatory reports must be explained, tested and defended, and SAS became established because it supported reliable, governed workflows. That is why SAS lasted: it works in environments where trust matters more than novelty.</p>
<aside class="advert">
<p>
Whether you want to start from scratch, or improve your skills, <a href="https://www.jumpingrivers.com/training/?utm_source=blog&#038;utm_medium=banner&#038;utm_campaign=is-sas-worth-keeping" rel="nofollow" target="_blank">Jumping Rivers has a training course for you</a>.
</p>
</aside>
<h2 id="why-organisations-keep-sas-too-long">Why organisations keep SAS too long</h2>
<p>Some organisations have strong reasons to keep SAS. Others keep it because replacing it looks harder than maintaining it.</p>
<h3 id="years-of-logic-sit-inside-the-code">Years of logic sit inside the code</h3>
<p>A mature SAS system contains more than programs. It contains macros, formats, reporting rules and business decisions built up over decades. Some of those rules only exist in the code, the people who wrote them may have left, and the documentation may be incomplete. This creates <a href="https://banking.vision/en/legacy-transformation-in-banking/" rel="nofollow" target="_blank">grown logic</a>: systems built gradually by different people, without one clear design.</p>
<p>Changing the system feels risky because nobody fully understands it. But leaving it unchanged increases the risk over time, as the system becomes more deeply embedded and fewer people retain the knowledge needed to maintain or replace it.</p>
<h3 id="sas-is-only-a-component">SAS is only a component</h3>
<p>SAS is often connected to reporting pipelines, validation processes, internal tools and downstream systems, so removing one part can affect the rest. Banking teams have described cases where <a href="https://sdk.finance/blog/modernizing-legacy-systems-in-banking/" rel="nofollow" target="_blank">legacy systems are closely tied</a> to daily operations, and replacing them requires more than rewriting code. It requires understanding how the whole process works.</p>
<h3 id="risks---skills-are-getting-harder-to-maintain">Risks &#8211; Skills are getting harder to maintain</h3>
<p>Organisations need people who understand the existing SAS system, and they also need people who can design and validate its replacement. These are often the same people. That creates a difficult position: the team needs specialist knowledge to maintain SAS and the same knowledge to move away from it. Waiting has been classed as the safest option by some, but waiting increases the knowledge gap and increases the risk.</p>
<p>The vast majority of UK Universities haven’t taught SAS to undergraduate statistics students in over fifteen years!</p>
<h2 id="migration-to-open-source-is-a-full-stack-problem-that-needs-a-full-stack-solution">Migration to open source is a full-stack problem that needs a full-stack solution</h2>
<p>R and Python can perform the analysis, modelling and reporting that regulated organisations need. The main risk in a <a href="https://www.jumpingrivers.com/training/course/why-use-r/" rel="nofollow" target="_blank">SAS to R migration</a> lies in the process around the language; R itself is rarely the problem.</p>
<p>Regulated teams must prove that the new process works, and similar results are not enough. Outputs may need to match at row, value and format level, and teams must retain evidence showing how each comparison was completed. Undocumented macros create another risk: a macro may hold an important business rule that exists nowhere else, and a direct conversion can reproduce the code while losing the reasoning behind it. Migration means rebuilding the process itself, not simply translating code line by line.</p>
<h2 id="a-proven-method-for-introducing-open-source-phased-migration">A proven method for introducing open source: phased migration</h2>
<p>Replacing the full SAS system at once creates unnecessary risk. A safer migration runs the old and new systems in parallel, so teams can compare outputs, test business rules, automate regression checks, document differences, maintain a rollback route, and validate each stage before release.</p>
<p>This takes longer than converting the code, but it produces a system the organisation can trust. A successful SAS to R migration is phased, governed and validated, with correctness and auditability built in from the start.</p>
<h2 id="is-sas-worth-keeping">Is SAS worth keeping?</h2>
<p>Sometimes SAS still has a clear role in regulated environments, supporting established processes, submission standards and governance models. But not every SAS workload is essential. Some remain because they are critical, and others remain because nobody has reviewed them.</p>
<p>Occasionally, the answer is both SAS and open source, not a choice between the two. Teams can use R or Python for new analysis, modelling and visualisation while keeping SAS for existing governance, reporting or submission processes, which lets organisations modernise without introducing unnecessary risk.</p>
<p>The first step is assessment. Before moving anything, identify which workloads are regulator-facing, which processes contain undocumented logic, which systems depend on SAS outputs, which workloads can move now, and what evidence will be required to validate the change. That gives the organisation a clear migration path.</p>
<h2 id="how-jumping-rivers-helps-you-achieve-open-source">How Jumping Rivers helps you achieve Open Source</h2>
<p>We strategise <a href="https://www.jumpingrivers.com/" rel="nofollow" target="_blank">for teams and systems from SAS to full implementation to R</a>, treating migration as a controlled transformation rather than a code conversion exercise. That means understanding the existing system, identifying risk, validating outputs and moving workloads in stages.</p>
<p>If your organisation is deciding which SAS workloads to keep and which to move, <a href="https://www.jumpingrivers.com/contact/" rel="nofollow" target="_blank">get in touch</a>. If you are still assessing whether R is the right choice, our <a href="https://www.jumpingrivers.com/training/course/why-use-r/" rel="nofollow" target="_blank">Why Use R?</a> course is designed for teams moving from SAS and SPSS. And if your organisation already uses R, <a href="https://www.jumpingrivers.com/litmus/" rel="nofollow" target="_blank">Litmus</a> provides audit-ready risk assessments for open source packages at package and function level.</p>
<p>Migration helps you adopt R. Validation helps you trust it.</p>
<h2 id="frequently-asked-questions">Frequently asked questions</h2>
<p><strong>Is SAS still used in 2026?</strong></p>
<p>Yes. SAS remains widely used in pharmaceutical research, banking, insurance and other regulated industries. Its value comes from governance, auditability and its place within established workflows.</p>
<p><strong>Does the FDA require SAS?</strong></p>
<p>No. The FDA accepts SAS transport files as a submission format, but this does not require sponsors to perform their analysis in SAS. These standards have, however, influenced the tools and processes used for clinical submissions.</p>
<p><strong>Can R replace SAS in clinical trials?</strong></p>
<p>Yes, in many workflows. The main challenge is validation: teams must show that R outputs are reproducible, correct and suitable for regulatory review. Many organisations use SAS and R together during the transition.</p>
<p><strong>What are the main risks of migrating from SAS to R?</strong></p>
<p>The main risks include undocumented business rules, incomplete knowledge of existing systems, differences between old and new outputs, and replacing too much at once. A phased migration with parallel testing and formal validation reduces these risks.</p>
<p><strong>Can SAS and R be used together?</strong></p>
<p>Yes. R can support new analysis, modelling and visualisation while SAS continues to support existing reporting, governance or submission processes. For many organisations, this is the safest route to modernisation.</p>
<h2 id="references">References</h2>
<ul>
<li>Techzine, <a href="https://www.techzine.eu/blogs/analytics/121581/47-years-of-sas-advanced-age-gives-sas-an-edge-in-current-ai-landscape/" rel="nofollow" target="_blank">47 years of SAS: advanced age gives SAS an edge in the current AI landscape</a></li>
<li>US FDA, <a href="https://www.fda.gov/industry/fda-data-standards-advisory-board/study-data-standards-resources" rel="nofollow" target="_blank">Study Data Standards Resources</a></li>
<li>US FDA, <a href="https://www.fda.gov/drugs/electronic-regulatory-submission-and-review/cder-study-data-standards-research-and-development" rel="nofollow" target="_blank">CDER Study Data Standards Research and Development</a></li>
<li>US FDA, <a href="https://www.fda.gov/media/133219/download" rel="nofollow" target="_blank">Study Data Technical Conformance Guide</a></li>
<li>Banking.Vision, <a href="https://banking.vision/en/legacy-transformation-in-banking/" rel="nofollow" target="_blank">The challenge of legacy transformation from a software development perspective</a></li>
<li>SDK.finance, <a href="https://sdk.finance/blog/modernizing-legacy-systems-in-banking/" rel="nofollow" target="_blank">How to Modernize Banking Legacy Systems via Cloud Migration</a></li>
<li>pharmaverse blog, <a href="https://pharmaverse.github.io/blog/posts/2025-09-12_faster_clinical_trial_reporting/faster_clinical_trial_reporting.html" rel="nofollow" target="_blank">Faster Clinical Trial Reporting: Implementing CDISC SDTM and ADaM Standards with Open Source R Packages</a></li>
<li>pharmaverse blog, <a href="https://pharmaverse.github.io/blog/posts/2024-02-01_containers_webassembly_submission/containers_and_webassembly_submissions.html" rel="nofollow" target="_blank">Testing Containers and WebAssembly in Submissions to the FDA</a></li>
</ul>
<p>
For updates and revisions to this article, see the <a href = "https://www.jumpingrivers.com/blog/is-sas-worth-keeping/">original post</a>
</p>
<div style="border: 1px solid; background: none repeat scroll 0 0 #EDEDED; margin: 1px; font-size: 13px;">
<div style="text-align: center;">To <strong>leave a comment</strong> for the author, please follow the link and comment on their blog: <strong><a href="https://www.jumpingrivers.com/blog/is-sas-worth-keeping/"> The Jumping Rivers Blog</a></strong>.</div>
<hr />
<a href="https://www.r-bloggers.com/" rel="nofollow">R-bloggers.com</a> offers <strong><a href="https://feedburner.google.com/fb/a/mailverify?uri=RBloggers" rel="nofollow">daily e-mail updates</a></strong> about <a title="The R Project for Statistical Computing" href="https://www.r-project.org/" rel="nofollow">R</a> news and tutorials about <a title="R tutorials" href="https://www.r-bloggers.com/how-to-learn-r-2/" rel="nofollow">learning R</a> and many other topics. <a title="Data science jobs" href="https://www.r-users.com/" rel="nofollow">Click here if you're looking to post or find an R/data-science job</a>.

<hr>Want to share your content on R-bloggers?<a href="https://www.r-bloggers.com/add-your-blog/" rel="nofollow"> click here</a> if you have a blog, or <a href="http://r-posts.com/" rel="nofollow"> here</a> if you don't.
</div><strong>Continue reading</strong>: <a href="https://www.r-bloggers.com/2026/08/is-sas-still-used-and-is-it-worth-keeping/">Is SAS Still Used, and Is It Worth Keeping?</a>]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">402978</post-id>	</item>
		<item>
		<title>Cross-Validation From Scratch and a Surprise at n=100</title>
		<link>https://www.r-bloggers.com/2026/08/cross-validation-from-scratch-and-a-surprise-at-n100/</link>
		
		<dc:creator><![CDATA[r on Everyday Is A School Day]]></dc:creator>
		<pubDate>Wed, 05 Aug 2026 00:00:00 +0000</pubDate>
				<category><![CDATA[R bloggers]]></category>
		<guid isPermaLink="false">https://www.kenkoonwong.com/blog/crossvalidation/</guid>

					<description><![CDATA[<div style = "width:60%; display: inline-block; float:left; ">
Textbooks say LOOCV has the lowest bias but highest variance compared to 10 and 5-fold. Coded a K-Fold CV from scratch for learning to test that on simulated data 🔍📊 — and at n=1000 it holds up. At n=100? Not so much. 🤔</p>
<p>The above image was generated...</p></div>
<div style = "width: 40%; display: inline-block; float:right;"></div>
<div style="clear: both;"></div>
<strong>Continue reading</strong>: <a href="https://www.r-bloggers.com/2026/08/cross-validation-from-scratch-and-a-surprise-at-n100/">Cross-Validation From Scratch and a Surprise at n=100</a>]]></description>
										<content:encoded><![CDATA[<!-- 
<div style="min-height: 30px;">
[social4i size="small" align="align-left"]
</div>
-->

<div style="border: 1px solid; background: none repeat scroll 0 0 #EDEDED; margin: 1px; font-size: 12px;">
[This article was first published on  <strong><a href="https://www.kenkoonwong.com/blog/crossvalidation/"> r on Everyday Is A School Day</a></strong>, and kindly contributed to <a href="https://www.r-bloggers.com/" rel="nofollow">R-bloggers</a>].  (You can report issue about the content on this page <a href="https://www.r-bloggers.com/contact-us/">here</a>)
<hr>Want to share your content on R-bloggers?<a href="https://www.r-bloggers.com/add-your-blog/" rel="nofollow"> click here</a> if you have a blog, or <a href="http://r-posts.com/" rel="nofollow"> here</a> if you don't.
</div>
<blockquote>
<p>Textbooks say LOOCV has the lowest bias but highest variance compared to 10 and 5-fold. Coded a K-Fold CV from scratch for learning to test that on simulated data <img src="https://s.w.org/images/core/emoji/13.0.0/72x72/1f50d.png" alt="🔍" class="wp-smiley" style="height: 1em; max-height: 1em;" /><img src="https://s.w.org/images/core/emoji/13.0.0/72x72/1f4ca.png" alt="📊" class="wp-smiley" style="height: 1em; max-height: 1em;" /> — and at n=1000 it holds up. At n=100? Not so much. <img src="https://s.w.org/images/core/emoji/13.0.0/72x72/1f914.png" alt="🤔" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
</blockquote>
<p><img src="https://i1.wp.com/www.kenkoonwong.com/blog/crossvalidation/main.png?w=578&#038;ssl=1" alt="" data-recalc-dims="1">
The above image was generated via chatGPT. Uploaded all the text of this blog post and asked it to generate a cartoon. Very impressive! It used to be spelling error and gibberish of text in the past, but now cohesive words on image. Just wow.</p>




<h2 id="motivations">Motivations
  <a href="https://www.kenkoonwong.com/blog/crossvalidation/#motivations" rel="nofollow" target="_blank"><svg class="anchor-symbol" aria-hidden="true" height="26" width="26" viewBox="0 0 22 22" xmlns="http://www.w3.org/2000/svg">
      <path d="M0 0h24v24H0z" fill="currentColor"></path>
      <path d="M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7c-2.76.0-5 2.24-5 5s2.24 5 5 5h4v-1.9H7c-1.71.0-3.1-1.39-3.1-3.1zM8 13h8v-2H8v2zm9-6h-4v1.9h4c1.71.0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4c2.76.0 5-2.24 5-5s-2.24-5-5-5z"></path>
    </svg></a>
</h2>
<p>Crossvalidation is such a crucial step in Machine Learning (and traditional methods) that nowadays is incorporated in easy to use sklearn or tidymodels without us needing to build one from scratch. As with my other learning experience, the best way to learn the concept (other than learning the concept <img src="https://s.w.org/images/core/emoji/13.0.0/72x72/1f923.png" alt="🤣" class="wp-smiley" style="height: 1em; max-height: 1em;" />) is to code it from the ground up and see how it works! In K-Fold CV, the training data is split into K chunks; the model is trained K times, each time holding out a different chunk. Performance is averaged across all K folds, giving a more stable estimate. A special case is Leave-One-Out CV (LOOCV), where each individual observation serves as its own validation set. It’s thorough but computationally expensive. I was told that, bias LOOCV < 10-fold < 5-fold; whereas variance LOOCV > 10-fold > 5-fold. Is that true? Also, what’s with the repeats, does that really reduce variance? Let’s check them out.</p>




<h2 id="objectives">Objectives:
  <a href="https://www.kenkoonwong.com/blog/crossvalidation/#objectives" rel="nofollow" target="_blank"><svg class="anchor-symbol" aria-hidden="true" height="26" width="26" viewBox="0 0 22 22" xmlns="http://www.w3.org/2000/svg">
      <path d="M0 0h24v24H0z" fill="currentColor"></path>
      <path d="M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7c-2.76.0-5 2.24-5 5s2.24 5 5 5h4v-1.9H7c-1.71.0-3.1-1.39-3.1-3.1zM8 13h8v-2H8v2zm9-6h-4v1.9h4c1.71.0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4c2.76.0 5-2.24 5-5s-2.24-5-5-5z"></path>
    </svg></a>
</h2>
<ul>
<li>
<a href="https://www.kenkoonwong.com/blog/crossvalidation/#simulate" rel="nofollow" target="_blank">Simulate data with a known data-generating process</a></li>
<li>
<a href="https://www.kenkoonwong.com/blog/crossvalidation/#kfold" rel="nofollow" target="_blank">Implement K-Fold cross-validation from scratch</a></li>
<li>
<a href="https://www.kenkoonwong.com/blog/crossvalidation/#rmse" rel="nofollow" target="_blank">Assessing RMSE</a></li>
<li>
<a href="https://www.kenkoonwong.com/blog/crossvalidation/#compare" rel="nofollow" target="_blank">Compare candidate models using CV RMSE</a></li>
<li>
<a href="https://www.kenkoonwong.com/blog/crossvalidation/#verify" rel="nofollow" target="_blank">Verify the best model on a held-out test set</a></li>
<li>
<a href="https://www.kenkoonwong.com/blog/crossvalidation/#opportunities" rel="nofollow" target="_blank">Opportunities For Improvement</a></li>
<li>
<a href="https://www.kenkoonwong.com/blog/crossvalidation/#lessons" rel="nofollow" target="_blank">Lessons Learnt</a></li>
</ul>




<h2 id="simulate">Simulate Data
  <a href="https://www.kenkoonwong.com/blog/crossvalidation/#simulate" rel="nofollow" target="_blank"><svg class="anchor-symbol" aria-hidden="true" height="26" width="26" viewBox="0 0 22 22" xmlns="http://www.w3.org/2000/svg">
      <path d="M0 0h24v24H0z" fill="currentColor"></path>
      <path d="M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7c-2.76.0-5 2.24-5 5s2.24 5 5 5h4v-1.9H7c-1.71.0-3.1-1.39-3.1-3.1zM8 13h8v-2H8v2zm9-6h-4v1.9h4c1.71.0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4c2.76.0 5-2.24 5-5s-2.24-5-5-5z"></path>
    </svg></a>
</h2>
<pre>library(tidyverse)

set.seed(1)
n &lt;- 1000
x &lt;- rnorm(n)
w &lt;- rnorm(n)
y &lt;- 0.5*x^2 + -0.5*w + 0.3*w*x + rnorm(n)
df &lt;- tibble(x,y,w)
idx &lt;- sample(1:n, size=0.8*n)
train &lt;- df[idx, ]
test &lt;- df[-idx, ]
</pre><p>The above code simulates a dataset with 1000 observations, where the response variable <code>y</code> is generated based on a known data-generating process involving predictors <code>x</code> and <code>w</code>. The dataset is then split into a training set (80%) and a test set (20%). Let’s visualize.</p>
<pre>df |&gt;
  mutate(w_cut = cut_interval(w, n=5)) |&gt;
  ggplot(aes(x=x, y=y, color=w_cut, group=w_cut)) +
  geom_point(alpha=0.5) +
  theme_bw() +
  geom_smooth(method = &quot;gam&quot;, se=F)
</pre><img src="https://i2.wp.com/www.kenkoonwong.com/blog/crossvalidation/index_files/figure-html/unnamed-chunk-2-1.png?w=450&#038;ssl=1" alt="" data-recalc-dims="1" />
<p>Wow, very interesting visualization where the relationships are definitely not linear here. It’s some form of interaction between <code>x</code> and <code>w</code>. Let’s see if we can recover the underlying data-generating process using K-Fold Cross-Validation.</p>




<h2 id="kfold">K-Fold Cross-Validation From Scratch
  <a href="https://www.kenkoonwong.com/blog/crossvalidation/#kfold" rel="nofollow" target="_blank"><svg class="anchor-symbol" aria-hidden="true" height="26" width="26" viewBox="0 0 22 22" xmlns="http://www.w3.org/2000/svg">
      <path d="M0 0h24v24H0z" fill="currentColor"></path>
      <path d="M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7c-2.76.0-5 2.24-5 5s2.24 5 5 5h4v-1.9H7c-1.71.0-3.1-1.39-3.1-3.1zM8 13h8v-2H8v2zm9-6h-4v1.9h4c1.71.0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4c2.76.0 5-2.24 5-5s-2.24-5-5-5z"></path>
    </svg></a>
</h2>
<pre>folds &lt;- 5
segment_portion &lt;- nrow(train)/folds
formula_list &lt;- list(as.formula(&quot;y~x&quot;),as.formula(&quot;y~I(x^2)&quot;),as.formula(&quot;y~I(x^2)+w+w:x&quot;),as.formula(&quot;y~I(x^3)+w+w:x&quot;),
                     as.formula(&quot;y~w:x&quot;),as.formula(&quot;y~w&quot;),as.formula(&quot;y~x+w+x:w&quot;),as.formula(&quot;y~I(x^2)+w:x&quot;),
                     as.formula(&quot;y~I(x^2)+w&quot;))

cv_log &lt;- tibble()

for (formula in formula_list) {
print(formula)
predict_log &lt;- y_log &lt;- vector(mode=&quot;numeric&quot;,length=segment_portion*folds)
start &lt;- 1
end &lt;- segment_portion 

for (fold in 1:folds) {
    val_i &lt;- train[start:end,]
    train_i &lt;- train[-c(start:end),]
    model_i &lt;- lm(formula,train_i)
    predict_i &lt;- predict(model_i, val_i)
    predict_log[start:end] &lt;- predict_i
    y_log[start:end] &lt;- val_i$y
    start &lt;- end + 1
    end &lt;- start + segment_portion - 1
}

val_df &lt;- tibble(predict=predict_log,y=y_log) |&gt;
  mutate(formula=deparse(formula))
cv_log &lt;- cv_log |&gt;
  bind_rows(val_df)
}

## y ~ x
## y ~ I(x^2)
## y ~ I(x^2) + w + w:x
## y ~ I(x^3) + w + w:x
## y ~ w:x
## y ~ w
## y ~ x + w + x:w
## y ~ I(x^2) + w:x
## y ~ I(x^2) + w
</pre><p>Alright, what we’ve done above is a manual implementation of K-Fold Cross-Validation. We loop through each formula in our list, and for each formula, we split the training data into 5 folds. For each fold, we train the model on the other 4 folds and validate it on the current fold. We store the predictions and actual values for later evaluation.</p>
<p>We basically want to see which formula has the lowest RMSE across the folds. Let’s calculate that next. From the DGP formula, we know that the best model should be <code>y~I(x^2)+w+w:x</code>. Let’s see if we can recover that using K-Fold CV.</p>




<h2 id="rmse">Assessing RMSE
  <a href="https://www.kenkoonwong.com/blog/crossvalidation/#rmse" rel="nofollow" target="_blank"><svg class="anchor-symbol" aria-hidden="true" height="26" width="26" viewBox="0 0 22 22" xmlns="http://www.w3.org/2000/svg">
      <path d="M0 0h24v24H0z" fill="currentColor"></path>
      <path d="M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7c-2.76.0-5 2.24-5 5s2.24 5 5 5h4v-1.9H7c-1.71.0-3.1-1.39-3.1-3.1zM8 13h8v-2H8v2zm9-6h-4v1.9h4c1.71.0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4c2.76.0 5-2.24 5-5s-2.24-5-5-5z"></path>
    </svg></a>
</h2>
<pre>cv_log |&gt;
  group_by(formula) |&gt;
  summarize(rmse = sqrt(mean((y-predict)^2))) |&gt;
  arrange(rmse) |&gt;
  mutate(rmse = format(rmse, digits = 8))

## # A tibble: 9 × 2
##   formula              rmse     
##   &lt;chr&gt;                &lt;chr&gt;    
## 1 y ~ I(x^2) + w + w:x 1.0397338
## 2 y ~ I(x^2) + w       1.1008693
## 3 y ~ I(x^2) + w:x     1.1607225
## 4 y ~ I(x^2)           1.2144857
## 5 y ~ x + w + x:w      1.2826723
## 6 y ~ I(x^3) + w + w:x 1.2912046
## 7 y ~ w                1.3578304
## 8 y ~ w:x              1.3732478
## 9 y ~ x                1.4451807
</pre><p>Here our loss function is RMSE since <code>y</code> is a continuous data and we’re trying to predict that. The formula with the lowest RMSE is indeed <code>y~I(x^2)+w+w:x</code>, which matches the underlying data-generating process. OK at least, right now we are able to recover the underlying DGP using 5-Fold Cross-Validation. But is there a difference between 5 fold, 10 fold, or even LOOCV? If there is a difference, how do we even assess that? 
<a href="https://www.kenkoonwong.com/blog/tmle/" rel="nofollow" target="_blank">In the past we were able to assess bias and variance based on a true ATE</a>, but what on earth is a true RMSE !?!</p>
<p>To check whether the textbook claim (bias LOOCV < 10-fold < 5-fold; variance LOOCV > 10-fold > 5-fold) holds up, we ran a small simulation with help from Claude Sonnet 5. Since we control the data-generating process, we can compare the “correct formula” (assuming the correct formula has the lowest RMSE as above) with 500 different simulated dataset against a “true” RMSE estimated from a large test set (n=10000) — large enough, by the law of large numbers, to treat as ground truth. Averaging across simulations gives bias (how far off CV runs from the true error) and variance (how much CV’s estimate swings from sample to sample) for each method. Is this legit? <img src="https://s.w.org/images/core/emoji/13.0.0/72x72/1f914.png" alt="🤔" class="wp-smiley" style="height: 1em; max-height: 1em;" /> If the textbook claim is correct, we should be able to observe bias LOOCV < 10-fold < 5-fold; variance LOOCV > 10-fold > 5-fold. Let’s see if we can observe that in the simulation below.</p>




<h2 id="compare">Compare Candidate Models
  <a href="https://www.kenkoonwong.com/blog/crossvalidation/#compare" rel="nofollow" target="_blank"><svg class="anchor-symbol" aria-hidden="true" height="26" width="26" viewBox="0 0 22 22" xmlns="http://www.w3.org/2000/svg">
      <path d="M0 0h24v24H0z" fill="currentColor"></path>
      <path d="M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7c-2.76.0-5 2.24-5 5s2.24 5 5 5h4v-1.9H7c-1.71.0-3.1-1.39-3.1-3.1zM8 13h8v-2H8v2zm9-6h-4v1.9h4c1.71.0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4c2.76.0 5-2.24 5-5s-2.24-5-5-5z"></path>
    </svg></a>
</h2>
<pre># set.seed(1)

# k-fold CV RMSE for a given formula and dataset (k = n gives LOOCV)
cv_rmse &lt;- function(data, formula, k) {
  n &lt;- nrow(data)
  folds &lt;- sample(rep(1:k, length.out = n))
  preds &lt;- numeric(n)
  for (i in 1:k) {
    train_i &lt;- data[folds != i, ]
    val_i   &lt;- data[folds == i, ]
    model_i &lt;- lm(formula, train_i)
    preds[folds == i] &lt;- predict(model_i, val_i)
  }
  sqrt(mean((data$y - preds)^2))
}

# &quot;true&quot; RMSE: fit on train, evaluate on a large fresh draw from the DGP
true_rmse &lt;- function(train, formula, n_test = 10000) {
  x &lt;- rnorm(n_test); w &lt;- rnorm(n_test)
  y &lt;- 0.5*x^2 - 0.5*w + 0.3*w*x + rnorm(n_test)
  test &lt;- tibble(x, y, w)
  model &lt;- lm(formula, train)
  sqrt(mean((test$y - predict(model, test))^2))
}

formula_true &lt;- as.formula(&quot;y ~ I(x^2) + w + w:x&quot;)
n_sim   &lt;- 500
n_train &lt;- 100

results &lt;- vector(&quot;list&quot;, n_sim)

for (s in 1:n_sim) {
  x &lt;- rnorm(n_train); w &lt;- rnorm(n_train)
  y &lt;- 0.5*x^2 - 0.5*w + 0.3*w*x + rnorm(n_train)
  train_s &lt;- tibble(x, y, w)

  results[[s]] &lt;- tibble(
    sim      = s,
    true_err = true_rmse(train_s, formula_true),
    loocv    = cv_rmse(train_s, formula_true, k = n_train),
    cv5      = cv_rmse(train_s, formula_true, k = 5),
    cv10     = cv_rmse(train_s, formula_true, k = 10)
  )
}

sim_df &lt;- bind_rows(results)

sim_long &lt;- sim_df |&gt;
  pivot_longer(cols = c(loocv, cv5, cv10), names_to = &quot;method&quot;, values_to = &quot;cv_estimate&quot;)

sim_long |&gt;
  group_by(method) |&gt;
  summarize(
    mean_cv_estimate = mean(cv_estimate),
    mean_true_error   = mean(true_err),
    bias     = mean(cv_estimate - true_err),
    variance = var(cv_estimate),
    .groups  = &quot;drop&quot;
  ) |&gt;
  arrange(bias) |&gt;
  mutate(variance = format(variance, digit = 8))

## # A tibble: 3 × 5
##   method mean_cv_estimate mean_true_error     bias variance     
##   &lt;chr&gt;             &lt;dbl&gt;           &lt;dbl&gt;    &lt;dbl&gt; &lt;chr&gt;        
## 1 loocv              1.00            1.00 0.000703 0.00053227867
## 2 cv10               1.00            1.00 0.000945 0.00053192050
## 3 cv5                1.00            1.00 0.00124  0.00053176441
</pre><p>Wow, looking at the results, we can see that the textbook claim holds up. LOOCV has the lowest bias, but the highest variance. 10-fold CV is in between, and 5-fold CV has the highest bias but lowest variance. But, noticed that we had to increase our digit to 8 to see the difference in variance, it’s really miniscule. Mainly because our n=1000 is already quite large, so the variance is already quite small. If we reduce n to 100, how would that look?</p>
<pre>## # A tibble: 3 × 5
##   method mean_cv_estimate mean_true_error     bias variance    
##   &lt;chr&gt;             &lt;dbl&gt;           &lt;dbl&gt;    &lt;dbl&gt; &lt;chr&gt;       
## 1 loocv              1.02            1.02 -0.00400 0.0063905148
## 2 cv10               1.02            1.02 -0.00138 0.0065753049
## 3 cv5                1.03            1.02  0.00244 0.0068098389
</pre><p>!?!?!?!?! <img src="https://s.w.org/images/core/emoji/13.0.0/72x72/1f937-200d-2642-fe0f.png" alt="🤷‍♂️" class="wp-smiley" style="height: 1em; max-height: 1em;" /> with n=100, the bias and variance order heuristics no longer hold up? Why is this? I don’t know. If you do, please let me know. I even increased the n_sim to 1000, but still same patern. Intersting how I had to push the n up to 850 in order to observe the textbook variance order again, though again it’s quite miniscule.</p>




<h2 id="verify">Verify On Test Set
  <a href="https://www.kenkoonwong.com/blog/crossvalidation/#verify" rel="nofollow" target="_blank"><svg class="anchor-symbol" aria-hidden="true" height="26" width="26" viewBox="0 0 22 22" xmlns="http://www.w3.org/2000/svg">
      <path d="M0 0h24v24H0z" fill="currentColor"></path>
      <path d="M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7c-2.76.0-5 2.24-5 5s2.24 5 5 5h4v-1.9H7c-1.71.0-3.1-1.39-3.1-3.1zM8 13h8v-2H8v2zm9-6h-4v1.9h4c1.71.0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4c2.76.0 5-2.24 5-5s-2.24-5-5-5z"></path>
    </svg></a>
</h2>
<pre>test |&gt;
  mutate(predict = predict(lm(as.formula(&quot;y ~ I(x^2) + w + w:x&quot;), train), test)) |&gt;
  mutate(residual = y-predict) |&gt;
  mutate(res_square = residual^2) |&gt;
  pull(res_square) |&gt;
  mean() |&gt;
  sqrt()

## [1] 1.018281
</pre><p>Alright! The RMSE on test set is quite similar to our average validation sets! <img src="https://s.w.org/images/core/emoji/13.0.0/72x72/1f64c.png" alt="🙌" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Let’s visualize the predicted and actual y of the model on test set.</p>
<pre>test |&gt;
  mutate(predict = predict(lm(as.formula(&quot;y ~ I(x^2) + w + w:x&quot;), train), test)) |&gt;
  ggplot(aes(x=predict, y=y)) +
  geom_point(alpha=0.5) +
  theme_bw() +
  geom_smooth(method = &quot;lm&quot;) +
  labs(title=&quot;Predicted vs Actual y on Test Set&quot;, x=&quot;Predicted y&quot;, y=&quot;Actual y&quot;)
</pre><img src="https://i1.wp.com/www.kenkoonwong.com/blog/crossvalidation/index_files/figure-html/unnamed-chunk-9-1.png?w=450&#038;ssl=1" alt="" data-recalc-dims="1" />
<pre>summary(lm(y ~ predict, data=test |&gt; mutate(predict = predict(lm(as.formula(&quot;y ~ I(x^2) + w + w:x&quot;), train), test))))

## 
## Call:
## lm(formula = y ~ predict, data = mutate(test, predict = predict(lm(as.formula(&quot;y ~ I(x^2) + w + w:x&quot;), 
##     train), test)))
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -2.98185 -0.61410 -0.05514  0.62883  2.28837 
## 
## Coefficients:
##             Estimate Std. Error t value Pr(&gt;|t|)    
## (Intercept)  0.08581    0.08390   1.023    0.308    
## predict      0.80885    0.07562  10.696   &lt;2e-16 ***
## ---
## Signif. codes:  0 &#39;***&#39; 0.001 &#39;**&#39; 0.01 &#39;*&#39; 0.05 &#39;.&#39; 0.1 &#39; &#39; 1
## 
## Residual standard error: 1.007 on 198 degrees of freedom
## Multiple R-squared:  0.3662,	Adjusted R-squared:  0.363 
## F-statistic: 114.4 on 1 and 198 DF,  p-value: &lt; 2.2e-16
</pre><p>Slope here is 0.81, not 1 — even with the correct formula, coefficients are still estimated from a finite, noisy sample, so predict is really “true signal + estimation error.” Regressing y on a noisy version of itself pulls the slope below 1 — a known effect called attenuation (same idea as errors-in-variables bias). More training data shrinks that estimation error, so the slope should creep closer to 1. Intercept stays near 0 because the estimation error isn’t systematically biased in one direction — just noisy — so predictions still center correctly on average. If this is true, then if we increase our n to 10000, we should see slope is closer to 1 and intercept closer to 0. Let’s test this theory out.</p>
<pre>set.seed(1)
n &lt;- 10000
x &lt;- rnorm(n)
w &lt;- rnorm(n)
y &lt;- 0.5*x^2 + -0.5*w + 0.3*w*x + rnorm(n)
df &lt;- tibble(x,y,w)
idx &lt;- sample(1:n, size=0.8*n)
train &lt;- df[idx, ]
test &lt;- df[-idx, ]
formula &lt;- as.formula(&quot;y ~ I(x^2) + w + w:x&quot;)
folds &lt;- 10
segment_portion &lt;- nrow(train)/folds
predict_log &lt;- y_log &lt;- vector(mode=&quot;numeric&quot;,length=segment_portion*folds)
start &lt;- 1
end &lt;- segment_portion 

for (fold in 1:folds) {
    val_i &lt;- train[start:end,]
    train_i &lt;- train[-c(start:end),]
    model_i &lt;- lm(formula,train_i)
    predict_i &lt;- predict(model_i, val_i)
    predict_log[start:end] &lt;- predict_i
    y_log[start:end] &lt;- val_i$y
    start &lt;- end + 1
    end &lt;- start + segment_portion - 1
}

val_df &lt;- tibble(predict=predict_log,y=y_log) 

val_df |&gt;
  summarize(rmse = sqrt(mean((y-predict)^2))) |&gt;
  arrange(rmse) |&gt;
  mutate(rmse = format(rmse, digits = 8))

## # A tibble: 1 × 1
##   rmse     
##   &lt;chr&gt;    
## 1 1.0126176

test |&gt;
  mutate(predict = predict(lm(as.formula(&quot;y ~ I(x^2) + w + w:x&quot;), train), test)) |&gt;
  mutate(residual = y-predict) |&gt;
  mutate(res_square = residual^2) |&gt;
  pull(res_square) |&gt;
  mean() |&gt;
  sqrt()

## [1] 0.9884315

test |&gt;
  mutate(predict = predict(lm(as.formula(&quot;y ~ I(x^2) + w + w:x&quot;), train), test)) |&gt;
  ggplot(aes(x=predict, y=y)) +
  geom_point(alpha=0.5) +
  theme_bw() +
  geom_smooth(method = &quot;lm&quot;) +
  labs(title=&quot;Predicted vs Actual y on Test Set&quot;, x=&quot;Predicted y&quot;, y=&quot;Actual y&quot;)
</pre><img src="https://i0.wp.com/www.kenkoonwong.com/blog/crossvalidation/index_files/figure-html/unnamed-chunk-10-1.png?w=450&#038;ssl=1" alt="" data-recalc-dims="1" />
<pre>summary(lm(y ~ predict, data=test |&gt; mutate(predict = predict(lm(as.formula(&quot;y ~ I(x^2) + w + w:x&quot;), train), test))))

## 
## Call:
## lm(formula = y ~ predict, data = mutate(test, predict = predict(lm(as.formula(&quot;y ~ I(x^2) + w + w:x&quot;), 
##     train), test)))
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -3.08711 -0.67088  0.01239  0.69015  2.86620 
## 
## Coefficients:
##             Estimate Std. Error t value Pr(&gt;|t|)    
## (Intercept)  0.02778    0.02527   1.099    0.272    
## predict      0.96577    0.02369  40.762   &lt;2e-16 ***
## ---
## Signif. codes:  0 &#39;***&#39; 0.001 &#39;**&#39; 0.01 &#39;*&#39; 0.05 &#39;.&#39; 0.1 &#39; &#39; 1
## 
## Residual standard error: 0.9884 on 1998 degrees of freedom
## Multiple R-squared:  0.454,	Adjusted R-squared:  0.4538 
## F-statistic:  1662 on 1 and 1998 DF,  p-value: &lt; 2.2e-16
</pre><p>There you have it! The RMSE on test set is quite similar to our average validation sets! <img src="https://s.w.org/images/core/emoji/13.0.0/72x72/1f64c.png" alt="🙌" class="wp-smiley" style="height: 1em; max-height: 1em;" />  The slope is now 0.97, much closer to 1, and the intercept is 0.02, much closer to 0. This confirms our theory that with more training data, the estimation error decreases, leading to better predictions.</p>




<h2 id="opportunities">Opportunities For Improvement
  <a href="https://www.kenkoonwong.com/blog/crossvalidation/#opportunities" rel="nofollow" target="_blank"><svg class="anchor-symbol" aria-hidden="true" height="26" width="26" viewBox="0 0 22 22" xmlns="http://www.w3.org/2000/svg">
      <path d="M0 0h24v24H0z" fill="currentColor"></path>
      <path d="M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7c-2.76.0-5 2.24-5 5s2.24 5 5 5h4v-1.9H7c-1.71.0-3.1-1.39-3.1-3.1zM8 13h8v-2H8v2zm9-6h-4v1.9h4c1.71.0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4c2.76.0 5-2.24 5-5s-2.24-5-5-5z"></path>
    </svg></a>
</h2>
<ul>
<li>apply crossvalidation from scratch on hyperparameter tuning such as xgboost hyperparam, lasso/ridge/elasticnet/glmnet</li>
<li>learn about nested resampling that uses an additional layer of resampling that separates the tuning activities from the process used to estimate the efficacy of the model. 
<a href="https://www.tidymodels.org/learn/work/nested-resampling/" rel="nofollow" target="_blank">see here</a></li>
<li>learn to code grouped and stratified cv from scratch</li>
<li>learn a bit more on time-series CV</li>
<li>need to try n_sim of 10000 and see if the bias and variance order holds up for n=100, since the simulation is quite slow, I didn’t run it to completion. Update: I did complete an n_sim of 10000 of n=100 and LOOCV still had the lowest variance.</li>
</ul>




<h2 id="lessons">Lessons learnt
  <a href="https://www.kenkoonwong.com/blog/crossvalidation/#lessons" rel="nofollow" target="_blank"><svg class="anchor-symbol" aria-hidden="true" height="26" width="26" viewBox="0 0 22 22" xmlns="http://www.w3.org/2000/svg">
      <path d="M0 0h24v24H0z" fill="currentColor"></path>
      <path d="M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7c-2.76.0-5 2.24-5 5s2.24 5 5 5h4v-1.9H7c-1.71.0-3.1-1.39-3.1-3.1zM8 13h8v-2H8v2zm9-6h-4v1.9h4c1.71.0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4c2.76.0 5-2.24 5-5s-2.24-5-5-5z"></path>
    </svg></a>
</h2>
<ul>
<li>Learnt that we have to use <code>I</code> to indicate that we want to include polynomial terms in the formula, otherwise R will interpret them as interaction terms.</li>
<li>Learnt <code>deparse</code> is useful to convert a formula object into a character string for logging purposes.</li>
</ul>
<p>If you like this article:</p>
<ul>
<li>please feel free to send me a 
<a href="https://www.kenkoonwong.com/blog/" rel="nofollow" target="_blank">comment or visit my other blogs</a></li>
<li>please feel free to follow me on 
<a href="https://bsky.app/profile/kenkoonwong.bsky.social" rel="nofollow" target="_blank">BlueSky</a>, 
<a href="https://twitter.com/kenkoonwong/" rel="nofollow" target="_blank">twitter</a>, 
<a href="https://github.com/kenkoonwong/" rel="nofollow" target="_blank">GitHub</a> or 
<a href="https://rstats.me/@kenkoonwong" rel="nofollow" target="_blank">Mastodon</a></li>
<li>if you would like collaborate please feel free to 
<a href="https://www.kenkoonwong.com/contact/" rel="nofollow" target="_blank">contact me</a></li>
</ul>

<div style="border: 1px solid; background: none repeat scroll 0 0 #EDEDED; margin: 1px; font-size: 13px;">
<div style="text-align: center;">To <strong>leave a comment</strong> for the author, please follow the link and comment on their blog: <strong><a href="https://www.kenkoonwong.com/blog/crossvalidation/"> r on Everyday Is A School Day</a></strong>.</div>
<hr />
<a href="https://www.r-bloggers.com/" rel="nofollow">R-bloggers.com</a> offers <strong><a href="https://feedburner.google.com/fb/a/mailverify?uri=RBloggers" rel="nofollow">daily e-mail updates</a></strong> about <a title="The R Project for Statistical Computing" href="https://www.r-project.org/" rel="nofollow">R</a> news and tutorials about <a title="R tutorials" href="https://www.r-bloggers.com/how-to-learn-r-2/" rel="nofollow">learning R</a> and many other topics. <a title="Data science jobs" href="https://www.r-users.com/" rel="nofollow">Click here if you're looking to post or find an R/data-science job</a>.

<hr>Want to share your content on R-bloggers?<a href="https://www.r-bloggers.com/add-your-blog/" rel="nofollow"> click here</a> if you have a blog, or <a href="http://r-posts.com/" rel="nofollow"> here</a> if you don't.
</div><strong>Continue reading</strong>: <a href="https://www.r-bloggers.com/2026/08/cross-validation-from-scratch-and-a-surprise-at-n100/">Cross-Validation From Scratch and a Surprise at n=100</a>]]></content:encoded>
					
		
		<enclosure url="" length="0" type="" />

		<post-id xmlns="com-wordpress:feed-additions:1">402983</post-id>	</item>
		<item>
		<title>R GUI Comparison Update</title>
		<link>https://www.r-bloggers.com/2026/08/r-gui-comparison-update/</link>
		
		<dc:creator><![CDATA[Bob Muenchen]]></dc:creator>
		<pubDate>Tue, 04 Aug 2026 13:57:51 +0000</pubDate>
				<category><![CDATA[R bloggers]]></category>
		<guid isPermaLink="false">https://r4stats.com/?p=5580</guid>

					<description><![CDATA[<div style = "width:60%; display: inline-block; float:left; "> Graphical user interfaces for the R language are easy to use and getting more powerful all the time. Here is my updated comparison of jamovi, JASP, BlueSky Statistics (free &#038; Pro), Rattle, RKWard, R-Instat, R AnalyticFlow, and R Commander. With so many detailed reviews of Graphical User Interfaces (GUIs) for R ...</div>
<div style = "width: 40%; display: inline-block; float:right;"></div>
<div style="clear: both;"></div>
<strong>Continue reading</strong>: <a href="https://www.r-bloggers.com/2026/08/r-gui-comparison-update/">R GUI Comparison Update</a>]]></description>
										<content:encoded><![CDATA[<!-- 
<div style="min-height: 30px;">
[social4i size="small" align="align-left"]
</div>
-->

<div style="border: 1px solid; background: none repeat scroll 0 0 #EDEDED; margin: 1px; font-size: 12px;">
[This article was first published on  <strong><a href="https://r4stats.com/2026/08/04/r-gui-comparison-update/"> R | r4stats.com</a></strong>, and kindly contributed to <a href="https://www.r-bloggers.com/" rel="nofollow">R-bloggers</a>].  (You can report issue about the content on this page <a href="https://www.r-bloggers.com/contact-us/">here</a>)
<hr>Want to share your content on R-bloggers?<a href="https://www.r-bloggers.com/add-your-blog/" rel="nofollow"> click here</a> if you have a blog, or <a href="http://r-posts.com/" rel="nofollow"> here</a> if you don't.
</div>
<p class="wp-block-paragraph">Graphical user interfaces for the R language are easy to use and getting more powerful all the time. Here is my updated comparison of jamovi, JASP, BlueSky Statistics (free &#038; Pro), Rattle, RKWard, R-Instat, R AnalyticFlow, and R Commander.</p>



<p class="wp-block-paragraph">With so many <a href="https://r4stats.com/articles/software-reviews" rel="nofollow" target="_blank">detailed reviews</a> of Graphical User Interfaces (GUIs) for R available, which should you choose? It’s not too difficult to rate them based on the number of features they offer, so I’ll start there. Then, I’ll follow with a brief overview of each.</p>



<p class="wp-block-paragraph">I’m basing the counts on the number of dialog boxes in each category of the following categories:</p>



<ul class="wp-block-list">
<li>Ease of Use</li>



<li>General Usability</li>



<li>Graphics</li>



<li>Analytics</li>



<li>Reproducibility</li>
</ul>



<p class="wp-block-paragraph">This <span style="margin: 0px; padding: 0px;">data is trickier to collect than you might think. Some software has fewer menu choices, depending instead on more detailed dialog boxes. Studying every menu and dialog box is very time-consuming, but that is what I’ve tried to do to keep this comparison <a href="https://r4stats.com/articles/software-reviews/why-you-should-trust-my-reviews/" rel="nofollow" target="_blank">trustworthy</a>. </span></p>



<p class="wp-block-paragraph">Perhaps the biggest flaw in this methodology is that every feature adds only one point to each GUI’s total score. I encourage you to <a href="https://1drv.ms/f/s!Aj_lpIYJgUBsk_1ydZxopRdgnskQAg?e=s4ccfW" rel="nofollow" title="" target="_blank">download</a> the full dataset and consider which features are most important to you. If you decide to make your own graphs with a different weighting system, I’d love to hear from you in the comments below. Thomas Langkamp did an excellent comparison focused on teaching statistics. You can read it <a href="https://www.researchgate.net/publication/392546873_The_Best_App_for_Teaching_Statistics_How_to_Switch_-_Software_designed_for_teachers_students_to_improve_upon_RStudio_SPSS_and_siblings" title="" rel="nofollow" target="_blank">here</a>.</p>



<h2 class="wp-block-heading">Ease of Use</h2>



<p class="wp-block-paragraph">For ease of use, I’ve defined it primarily by how well each GUI meets its primary goal: avoiding code. They get one point for each of the following abilities, which include being able to install, start, and use the GUI to its maximum effect, including publication-quality output, without knowing anything about the R language itself. Figure 1 shows the result. R Commander is abbreviated Rcmdr, and R AnalyticFlow is abbreviated RAF. The commercial BlueSky Pro comes out on top by a slim margin, followed closely by JASP and RKWard. None of the GUIs achieved the highest possible score of 15, so there is room for improvement.</p>



<p class="wp-block-paragraph">The ease of use features are:</p>



<ul class="wp-block-list">
<li>Installs without the use of R</li>



<li>Starts without the use of R</li>



<li>Remembers recent files</li>



<li>Hides R code by default</li>



<li>Uses its full capability without needing R code</li>



<li>Data editor included</li>



<li>Pub-quality tables w/out R code steps</li>



<li>Simple menus that grow as needed</li>



<li>Table of Contents to ease navigation</li>



<li>Variable labels ease identification in the output</li>



<li>Easy to move blocks of output</li>



<li>Ease reading columns by freezing headers of long tables</li>



<li>Accepts data pasted from the clipboard</li>



<li>Easy to move header row of pasted data into the variable name field</li>



<li>Includes AI interface to ease interpretation of output</li>
</ul>



<figure class="wp-block-image size-full"><a href="https://i2.wp.com/r4stats.com/wp-content/uploads/2026/08/Ease_of_Use.png?ssl=1" rel="nofollow" target="_blank"><img loading="lazy" fetchpriority="high" decoding="async" data-attachment-id="5556" data-permalink="https://r4stats.com/articles/software-reviews/r-gui-comparison/ease_of_use-5/" data-orig-file="https://i2.wp.com/r4stats.com/wp-content/uploads/2026/08/Ease_of_Use.png?w=450&#038;ssl=1" data-orig-size="600,500" data-comments-opened="1" data-image-meta="{"aperture":"0","credit":"","camera":"","caption":"","created_timestamp":"0","copyright":"","focal_length":"0","iso":"0","shutter_speed":"0","title":"","orientation":"0","alt":""}" data-image-title="Ease_of_Use" data-image-description="" data-image-caption="" data-large-file="https://i2.wp.com/r4stats.com/wp-content/uploads/2026/08/Ease_of_Use.png?w=450&#038;ssl=1" src="https://i2.wp.com/r4stats.com/wp-content/uploads/2026/08/Ease_of_Use.png?w=450&#038;ssl=1" alt="" class="wp-image-5556" srcset_temp="https://i2.wp.com/r4stats.com/wp-content/uploads/2026/08/Ease_of_Use.png?w=450&#038;ssl=1 600w, https://r4stats.com/wp-content/uploads/2026/08/Ease_of_Use-300x250.png 300w" sizes="(max-width: 600px) 100vw, 600px" data-recalc-dims="1" /></a><figcaption class="wp-element-caption">Figure 1. The number of ease-of-use features offered by each R GUI.</figcaption></figure>



<h2 class="wp-block-heading">General Usability</h2>



<p class="wp-block-paragraph">This category is dominated by data-wrangling capabilities, which data scientists and statisticians spend most of their time on. It also includes various types of data input and output. We see in Figure 2 that both BlueSky versions and R-Instat come out on top, not just due to their excellent selection of data-wrangling features but also for their use of the rio package for importing and exporting files. The <a href="https://cran.r-project.org/web/packages/rio/vignettes/rio.html" rel="nofollow" target="_blank">rio</a> package combines the import/export capabilities of many other packages, and it is easy to use. I expect the other GUIs will eventually adopt it, raising their scores by around 20 points. </p>



<p class="wp-block-paragraph">The general usability features are:</p>



<ul class="wp-block-list">
<li>Operating systems (how many)</li>



<li>Import data file types (how many)</li>



<li>Import from databases (how many)</li>



<li>Export data file types (how many)</li>



<li>Languages displayable in UI (how many, besides English)</li>



<li>Easy to repeat any step by groups (split-file)</li>



<li>Multiple data files open at once</li>



<li>Multiple output windows</li>



<li>Multiple code windows</li>



<li>Variable metadata view</li>



<li>Variable types (how many)</li>



<li>Variable search/filter in dialogs</li>



<li>Variable sort by name</li>



<li>Variable sort by type</li>



<li>Variable move manually</li>



<li>Model Builder (how many effect types)</li>



<li>Magnify GUI for teaching</li>



<li>R code editor</li>



<li>Comment/uncomment blocks of code</li>



<li>Package management (comes with R and all packages)</li>



<li>Output: word processing features</li>



<li>Output: R Markdown</li>



<li>Output: LaTeX</li>



<li>Data wrangling (how many)</li>



<li>Transform across many variables at once (e.g., row mean)</li>



<li>Transform down many variables at once (e.g., log, sqrt)</li>



<li>Assign factor labels across many variables at once</li>



<li>Project saves/loads data, dialogs, and notes in one file</li>
</ul>



<figure class="wp-block-image size-full"><a href="https://i0.wp.com/r4stats.com/wp-content/uploads/2026/08/General_Usability.png?ssl=1" rel="nofollow" target="_blank"><img loading="lazy" decoding="async" data-attachment-id="5559" data-permalink="https://r4stats.com/articles/software-reviews/r-gui-comparison/general_usability-6/" data-orig-file="https://i0.wp.com/r4stats.com/wp-content/uploads/2026/08/General_Usability.png?w=450&#038;ssl=1" data-orig-size="600,500" data-comments-opened="1" data-image-meta="{"aperture":"0","credit":"","camera":"","caption":"","created_timestamp":"0","copyright":"","focal_length":"0","iso":"0","shutter_speed":"0","title":"","orientation":"0","alt":""}" data-image-title="General_Usability" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/r4stats.com/wp-content/uploads/2026/08/General_Usability.png?w=450&#038;ssl=1" src="https://i0.wp.com/r4stats.com/wp-content/uploads/2026/08/General_Usability.png?w=450&#038;ssl=1" alt="" class="wp-image-5559" srcset_temp="https://i0.wp.com/r4stats.com/wp-content/uploads/2026/08/General_Usability.png?w=450&#038;ssl=1 600w, https://r4stats.com/wp-content/uploads/2026/08/General_Usability-300x250.png 300w" sizes="(max-width: 600px) 100vw, 600px" data-recalc-dims="1" /></a><figcaption class="wp-element-caption">Figure 2. The number of general usability features in each R GUI.</figcaption></figure>



<h2 class="wp-block-heading">Graphics</h2>



<p class="wp-block-paragraph">This category consists mainly of the number of plot types each software offers. However, the other items can be very important to completing your work. They should add more than one point to the graphics score, but I scored them one point since some will view them as very important while others might not need them at all. Be sure to see the full reviews or download the Excel file if those features are important to you. Figure 3 shows the total graphics score for each GUI. jamovi has a solid lead in this category. R-Instat’s ability to layer any geometric object, or “geom,” on top of another could substantially increase its count, but I don’t include that since it requires knowledge of R code.</p>



<p class="wp-block-paragraph">When studying all the graphs in this article, it’s important to consider the difference between the relative and absolute performance. For example, relatively speaking, R Commander is not doing well here, but it does offer over 25 types of plots! That might be fine for your needs.</p>



<p class="wp-block-paragraph">The graphics features are:</p>



<ul class="wp-block-list">
<li>Types of graphs (how many)</li>



<li>Small multiples (i.e., facets)</li>



<li>Large multiples (i.e., by group / split-file)</li>



<li>Export graphics formats (how many)</li>



<li>Interactive Plot Builder</li>



<li>Interactive Plot Editor (e.g., add annotations, arrows, etc.)</li>



<li>Able to combine any graphs into a single image</li>
</ul>



<p class="wp-block-paragraph"><a href="https://r4stats.com/articles/software-reviews/r-gui-comparison/" title="" rel="nofollow" target="_blank">Continued</a>…</p>



<p class="wp-block-paragraph"></p>The post <a href="https://r4stats.com/2026/08/04/r-gui-comparison-update/" rel="nofollow" target="_blank">R GUI Comparison Update</a> first appeared on <a href="https://r4stats.com/" rel="nofollow" target="_blank">r4stats.com</a>.
<div style="border: 1px solid; background: none repeat scroll 0 0 #EDEDED; margin: 1px; font-size: 13px;">
<div style="text-align: center;">To <strong>leave a comment</strong> for the author, please follow the link and comment on their blog: <strong><a href="https://r4stats.com/2026/08/04/r-gui-comparison-update/"> R | r4stats.com</a></strong>.</div>
<hr />
<a href="https://www.r-bloggers.com/" rel="nofollow">R-bloggers.com</a> offers <strong><a href="https://feedburner.google.com/fb/a/mailverify?uri=RBloggers" rel="nofollow">daily e-mail updates</a></strong> about <a title="The R Project for Statistical Computing" href="https://www.r-project.org/" rel="nofollow">R</a> news and tutorials about <a title="R tutorials" href="https://www.r-bloggers.com/how-to-learn-r-2/" rel="nofollow">learning R</a> and many other topics. <a title="Data science jobs" href="https://www.r-users.com/" rel="nofollow">Click here if you're looking to post or find an R/data-science job</a>.

<hr>Want to share your content on R-bloggers?<a href="https://www.r-bloggers.com/add-your-blog/" rel="nofollow"> click here</a> if you have a blog, or <a href="http://r-posts.com/" rel="nofollow"> here</a> if you don't.
</div><strong>Continue reading</strong>: <a href="https://www.r-bloggers.com/2026/08/r-gui-comparison-update/">R GUI Comparison Update</a>]]></content:encoded>
					
		
		<enclosure url="" length="0" type="" />

		<post-id xmlns="com-wordpress:feed-additions:1">402963</post-id>	</item>
		<item>
		<title>Centering a map projection on the mapped region</title>
		<link>https://www.r-bloggers.com/2026/08/centering-a-map-projection-on-the-mapped-region/</link>
		
		<dc:creator><![CDATA[A.M. Barbosa]]></dc:creator>
		<pubDate>Tue, 04 Aug 2026 13:11:00 +0000</pubDate>
				<category><![CDATA[R bloggers]]></category>
		<guid isPermaLink="false">http://modtools.wordpress.com/?p=3510</guid>

					<description><![CDATA[<div style = "width:60%; display: inline-block; float:left; "> The PROJ format for defining Coordinate Reference Systems (CRS) is becoming deprecated, as PROJ strings cannot accurately store modern datum transformations, coordinate epoch information, or complex axis order rules. However, that format is much easier and more practical for humans … Continue reading →</div>
<div style = "width: 40%; display: inline-block; float:right;"></div>
<div style="clear: both;"></div>
<strong>Continue reading</strong>: <a href="https://www.r-bloggers.com/2026/08/centering-a-map-projection-on-the-mapped-region/">Centering a map projection on the mapped region</a>]]></description>
										<content:encoded><![CDATA[<!-- 
<div style="min-height: 30px;">
[social4i size="small" align="align-left"]
</div>
-->

<div style="border: 1px solid; background: none repeat scroll 0 0 #EDEDED; margin: 1px; font-size: 12px;">
[This article was first published on  <strong><a href="https://modtools.wordpress.com/2026/08/04/centering-a-map-projection-on-the-mapped-region/"> modTools</a></strong>, and kindly contributed to <a href="https://www.r-bloggers.com/" rel="nofollow">R-bloggers</a>].  (You can report issue about the content on this page <a href="https://www.r-bloggers.com/contact-us/">here</a>)
<hr>Want to share your content on R-bloggers?<a href="https://www.r-bloggers.com/add-your-blog/" rel="nofollow"> click here</a> if you have a blog, or <a href="http://r-posts.com/" rel="nofollow"> here</a> if you don't.
</div>

<p class="wp-block-paragraph">The PROJ format for defining Coordinate Reference Systems (CRS) is becoming deprecated, as PROJ strings cannot accurately store modern datum transformations, coordinate epoch information, or complex axis order rules. However, that format is much easier and more practical for humans to type and read, and it is still often used as a legacy convenience. I, for one, use it often for centering a map projection on the mapped region, thus avoiding the distortion that occurs away from the projection center. For example, imagine I want to map New Zealand in a Lambert Azimuthal Equal-Area projection in R:</p>


<div class="wp-block-code">
	<div class="cm-editor">
		<div class="cm-scroller">
			
<pre>
library(terra)library(geodata)nz &lt;- gadm(country = &quot;New Zealand&quot;, level = 0, path = tempdir())nz_prj &lt;- project(nz, &quot;+proj=laea&quot;)plot(nz_prj)</pre>
		</div>
	</div>
</div>


<figure class="wp-block-image size-large is-resized"><a href="https://i1.wp.com/modtools.wordpress.com/wp-content/uploads/2026/08/image.png?ssl=1" rel="nofollow" target="_blank"><img loading="lazy" data-attachment-id="3515" data-permalink="https://modtools.wordpress.com/2026/08/04/centering-a-map-projection-on-the-mapped-region/image-28/" data-orig-file="https://modtools.wordpress.com/wp-content/uploads/2026/08/image.png" data-orig-size="1098,418" data-comments-opened="1" data-image-meta="{"aperture":"0","credit":"","camera":"","caption":"","created_timestamp":"0","copyright":"","focal_length":"0","iso":"0","shutter_speed":"0","title":"","orientation":"0","alt":""}" data-image-title="image" data-image-description="" data-image-caption="" data-large-file="https://modtools.wordpress.com/wp-content/uploads/2026/08/image.png?w=584" src="https://i1.wp.com/modtools.wordpress.com/wp-content/uploads/2026/08/image.png?w=450&#038;ssl=1" alt="" class="wp-image-3515" style="aspect-ratio:2.5363167486418208;width:465px;height:auto" srcset_temp="https://i1.wp.com/modtools.wordpress.com/wp-content/uploads/2026/08/image.png?w=450&#038;ssl=1 1024w, https://modtools.wordpress.com/wp-content/uploads/2026/08/image.png?w=150 150w, https://modtools.wordpress.com/wp-content/uploads/2026/08/image.png?w=300 300w, https://modtools.wordpress.com/wp-content/uploads/2026/08/image.png?w=768 768w, https://modtools.wordpress.com/wp-content/uploads/2026/08/image.png 1098w" sizes="(max-width: 1024px) 100vw, 1024px" data-recalc-dims="1" /></a></figure>



<p class="wp-block-paragraph">The map is heavily distorted, because it is far away from the center of the projection, which is 0,0 by default. With the PROJ format, we can easily set the center wherever we want, e.g.:</p>


<div class="wp-block-code">
	<div class="cm-editor">
		<div class="cm-scroller">
			
<pre>
nz_centr &lt;- crds(centroids(aggregate(nz)))nz_centr  # 172.6104 -41.82592nz_prj &lt;- project(nz, &quot;+proj=laea +lat_0=-41.8 +lon_0=172.6&quot;)# (this can be further automated to avoid the hard-coding,# but I keep it like this here for simplicity) plot(nz_prj)</pre>
		</div>
	</div>
</div>


<figure class="wp-block-image size-large is-resized"><a href="https://i0.wp.com/modtools.wordpress.com/wp-content/uploads/2026/08/image-1.png?ssl=1" rel="nofollow" target="_blank"><img loading="lazy" data-attachment-id="3518" data-permalink="https://modtools.wordpress.com/2026/08/04/centering-a-map-projection-on-the-mapped-region/image-29/" data-orig-file="https://modtools.wordpress.com/wp-content/uploads/2026/08/image-1.png" data-orig-size="796,1373" data-comments-opened="1" data-image-meta="{"aperture":"0","credit":"","camera":"","caption":"","created_timestamp":"0","copyright":"","focal_length":"0","iso":"0","shutter_speed":"0","title":"","orientation":"0","alt":""}" data-image-title="image" data-image-description="" data-image-caption="" data-large-file="https://modtools.wordpress.com/wp-content/uploads/2026/08/image-1.png?w=584" src="https://i0.wp.com/modtools.wordpress.com/wp-content/uploads/2026/08/image-1.png?w=450&#038;ssl=1" alt="" class="wp-image-3518" style="aspect-ratio:0.58568329013069;width:179px;height:auto" srcset_temp="https://i0.wp.com/modtools.wordpress.com/wp-content/uploads/2026/08/image-1.png?w=450&#038;ssl=1 594w, https://modtools.wordpress.com/wp-content/uploads/2026/08/image-1.png?w=87 87w, https://modtools.wordpress.com/wp-content/uploads/2026/08/image-1.png?w=174 174w, https://modtools.wordpress.com/wp-content/uploads/2026/08/image-1.png?w=768 768w, https://modtools.wordpress.com/wp-content/uploads/2026/08/image-1.png 796w" sizes="(max-width: 594px) 100vw, 594px" data-recalc-dims="1" /></a></figure>



<p class="wp-block-paragraph">Much better! We now have an equal-area map of New Zealand without visibly distorting the shape, and without having to look for specific equal-area CRSs normally used over there (and again every time we need to map another region of the world). This works as long as we use the WGS84 ellipsoid rather than a local datum, as those are currently not supported when using PROJ. So, I’m still using this regularly, and apprehensive about PROJ being deprecated… If anyone knows of a non-PROJ way of easily defining user-centered projections like this, please let me know!</p>



<p class="wp-block-paragraph"></p>

<div style="border: 1px solid; background: none repeat scroll 0 0 #EDEDED; margin: 1px; font-size: 13px;">
<div style="text-align: center;">To <strong>leave a comment</strong> for the author, please follow the link and comment on their blog: <strong><a href="https://modtools.wordpress.com/2026/08/04/centering-a-map-projection-on-the-mapped-region/"> modTools</a></strong>.</div>
<hr />
<a href="https://www.r-bloggers.com/" rel="nofollow">R-bloggers.com</a> offers <strong><a href="https://feedburner.google.com/fb/a/mailverify?uri=RBloggers" rel="nofollow">daily e-mail updates</a></strong> about <a title="The R Project for Statistical Computing" href="https://www.r-project.org/" rel="nofollow">R</a> news and tutorials about <a title="R tutorials" href="https://www.r-bloggers.com/how-to-learn-r-2/" rel="nofollow">learning R</a> and many other topics. <a title="Data science jobs" href="https://www.r-users.com/" rel="nofollow">Click here if you're looking to post or find an R/data-science job</a>.

<hr>Want to share your content on R-bloggers?<a href="https://www.r-bloggers.com/add-your-blog/" rel="nofollow"> click here</a> if you have a blog, or <a href="http://r-posts.com/" rel="nofollow"> here</a> if you don't.
</div><strong>Continue reading</strong>: <a href="https://www.r-bloggers.com/2026/08/centering-a-map-projection-on-the-mapped-region/">Centering a map projection on the mapped region</a>]]></content:encoded>
					
		
		<enclosure url="https://2.gravatar.com/avatar/e1a349777384e70d2eb7ee3f26788864b1c880ec271cfc1cb8f9d8cc3000cd11?s=96&#038;d=retro&#038;r=G" length="0" type="" />
<enclosure url="https://modtools.wordpress.com/wp-content/uploads/2026/08/image.png?w=1024" length="0" type="" />
<enclosure url="https://modtools.wordpress.com/wp-content/uploads/2026/08/image-1.png?w=594" length="0" type="" />

		<post-id xmlns="com-wordpress:feed-additions:1">402961</post-id>	</item>
		<item>
		<title>JAGS 5.0.0 is released</title>
		<link>https://www.r-bloggers.com/2026/08/jags-5-0-0-is-released/</link>
		
		<dc:creator><![CDATA[Martyn]]></dc:creator>
		<pubDate>Sun, 02 Aug 2026 16:44:02 +0000</pubDate>
				<category><![CDATA[R bloggers]]></category>
		<guid isPermaLink="false">http://martynplummer.wordpress.com/?p=2061</guid>

					<description><![CDATA[<div style = "width:60%; display: inline-block; float:left; "> After an extended beta period, JAGS 5.0.0 is now available. The release is more of a process than a single event, but we have started by uploading the source tarball and the Windows installer to SourceForge. The macOS installer will … Continue reading →</div>
<div style = "width: 40%; display: inline-block; float:right;"></div>
<div style="clear: both;"></div>
<strong>Continue reading</strong>: <a href="https://www.r-bloggers.com/2026/08/jags-5-0-0-is-released/">JAGS 5.0.0 is released</a>]]></description>
										<content:encoded><![CDATA[<!-- 
<div style="min-height: 30px;">
[social4i size="small" align="align-left"]
</div>
-->

<div style="border: 1px solid; background: none repeat scroll 0 0 #EDEDED; margin: 1px; font-size: 12px;">
[This article was first published on  <strong><a href="https://martynplummer.wordpress.com/2026/08/02/jags-5-0-0-is-released/"> R – JAGS News</a></strong>, and kindly contributed to <a href="https://www.r-bloggers.com/" rel="nofollow">R-bloggers</a>].  (You can report issue about the content on this page <a href="https://www.r-bloggers.com/contact-us/">here</a>)
<hr>Want to share your content on R-bloggers?<a href="https://www.r-bloggers.com/add-your-blog/" rel="nofollow"> click here</a> if you have a blog, or <a href="http://r-posts.com/" rel="nofollow"> here</a> if you don't.
</div>

<figure class="wp-block-image size-large"><img loading="lazy" data-attachment-id="2066" data-permalink="https://martynplummer.wordpress.com/img_0134/" data-orig-file="https://martynplummer.wordpress.com/wp-content/uploads/2026/08/img_0134.jpg" data-orig-size="2000,1500" data-comments-opened="1" data-image-meta="{"aperture":"1.64","credit":"","camera":"iPhone 16e","caption":"","created_timestamp":"1784045517","copyright":"","focal_length":"4.2","iso":"20","shutter_speed":"0.00019398642095053","title":"","orientation":"1","alt":""}" data-image-title="img_0134" data-image-description="" data-image-caption="" data-large-file="https://martynplummer.wordpress.com/wp-content/uploads/2026/08/img_0134.jpg?w=584" src="https://i0.wp.com/martynplummer.wordpress.com/wp-content/uploads/2026/08/img_0134.jpg?w=450&#038;ssl=1" alt="" class="wp-image-2066" title="img_0134" srcset_temp="https://i0.wp.com/martynplummer.wordpress.com/wp-content/uploads/2026/08/img_0134.jpg?w=450&#038;ssl=1 1024w, https://martynplummer.wordpress.com/wp-content/uploads/2026/08/img_0134.jpg?w=150 150w, https://martynplummer.wordpress.com/wp-content/uploads/2026/08/img_0134.jpg?w=300 300w, https://martynplummer.wordpress.com/wp-content/uploads/2026/08/img_0134.jpg?w=768 768w, https://martynplummer.wordpress.com/wp-content/uploads/2026/08/img_0134.jpg?w=1440 1440w, https://martynplummer.wordpress.com/wp-content/uploads/2026/08/img_0134.jpg 2000w" sizes="(max-width: 1024px) 100vw, 1024px" data-recalc-dims="1" /><figcaption class="wp-element-caption">View over Loch Muick, Balmoral Estate, Scotland</figcaption></figure>



<p class="wp-block-paragraph">After an extended beta period, JAGS 5.0.0 is now available. The release is more of a process than a single event, but we have started by uploading the <a href="https://sourceforge.net/projects/mcmc-jags/files/JAGS/5.x/Source/" rel="nofollow" target="_blank">source tarball</a> and the <a href="https://sourceforge.net/projects/mcmc-jags/files/JAGS/5.x/Windows/Rtools45/" rel="nofollow" target="_blank">Windows installer</a> to SourceForge. The macOS installer will be along hopefully next week.</p>



<p class="wp-block-paragraph">Thanks to Jeroen Ooms, Windows binary installers are available from the <a href="https://github.com/r-windows/JAGS/releases" rel="nofollow" target="_blank">r-windows project on GitHub</a>. This includes binaries for aarch64/Arm64.</p>



<h2 class="wp-block-heading">Changes since the beta release</h2>



<ul class="wp-block-list">
<li>Better multi-core support on macOS (More on this in a future post).</li>



<li>Fixed a delayed rejection bug in the <code>MNormal</code> sampler.</li>



<li>Added a new elliptical slice sampler contributed by Marcel Jonker. </li>



<li>The <code>dic.samples</code> function could throw a logic error (<a href="https://sourceforge.net/p/mcmc-jags/bugs/66/" rel="nofollow" target="_blank">See ticket #66)</a>. I am unable to reproduce this but JAGS 5.0.0 includes a workaround that should avoid triggering this bug.</li>



<li>Fixed a reproducibility bug in <code>BaseRNGFactory.</code></li>
</ul>



<p class="wp-block-paragraph">I would not normally add a new sampler at this late stage, but the elliptical slice sampler was ready to go and performs surprisingly well for a non-adaptive sampler. If you experience any trouble with this new sampler then you can turn it of with</p>


<div class="wp-block-code">
	<div class="cm-editor">
		<div class="cm-scroller">
			
<pre>
set.factory(&quot;bugs::EllipticalSlice&quot;, type=&quot;sampler&quot;, state=FALSE)</pre>
		</div>
	</div>
</div>


<p class="wp-block-paragraph">JAGS will then fall back on the adaptive random walk Metropolis-Hastings sampler <code>MNormal</code>.</p>



<h2 class="wp-block-heading">The rjags package and CRAN migration</h2>



<p class="wp-block-paragraph">The current rjags package on CRAN (<a href="https://cran.r-project.org/package=rjags" rel="nofollow" target="_blank">version 4-17</a>) will not work with JAGS 5.0.0. You need version 5-x but for the time being this will only be available from SourceForge.</p>



<ul class="wp-block-list">
<li><a href="https://sourceforge.net/projects/mcmc-jags/files/rjags/5/Source/" rel="nofollow" target="_blank">Source tarball</a></li>



<li><a href="https://sourceforge.net/projects/mcmc-jags/files/rjags/5/Windows/" rel="nofollow" target="_blank">Windows binary</a> (x86_64)</li>



<li><a href="https://sourceforge.net/projects/mcmc-jags/files/rjags/5/macOS/" rel="nofollow" target="_blank">macOS binary</a></li>
</ul>



<p class="wp-block-paragraph">The reason for not uploading the rjags package to CRAN is that it currently breaks a lot of reverse dependencies. I have been quite proactive in contacting the maintainers of these package and providing patches, but we still need to give them more time.</p>



<p class="wp-block-paragraph">We are monitoring the reverse dependency situation and will be liaising with the CRAN maintainers.</p>



<h2 class="wp-block-heading">Preview of upcoming posts</h2>



<p class="wp-block-paragraph">In order to help users and developers with the transition to JAGS version 5, a series of “What’s new in JAGS 5.0.0” blog posts are planned covering the following topics.</p>



<ul class="wp-block-list">
<li><strong>Initial values</strong></li>



<li><strong>Reproducibility</strong></li>



<li><strong>Multicore support</strong></li>



<li><strong>ABI compatibility</strong></li>



<li><strong>New diagnostics</strong></li>
</ul>



<p class="wp-block-paragraph">These will include guidance for package maintainers to make the transition to JAGS 5.0.0.</p>



<p class="wp-block-paragraph"></p>

<div style="border: 1px solid; background: none repeat scroll 0 0 #EDEDED; margin: 1px; font-size: 13px;">
<div style="text-align: center;">To <strong>leave a comment</strong> for the author, please follow the link and comment on their blog: <strong><a href="https://martynplummer.wordpress.com/2026/08/02/jags-5-0-0-is-released/"> R – JAGS News</a></strong>.</div>
<hr />
<a href="https://www.r-bloggers.com/" rel="nofollow">R-bloggers.com</a> offers <strong><a href="https://feedburner.google.com/fb/a/mailverify?uri=RBloggers" rel="nofollow">daily e-mail updates</a></strong> about <a title="The R Project for Statistical Computing" href="https://www.r-project.org/" rel="nofollow">R</a> news and tutorials about <a title="R tutorials" href="https://www.r-bloggers.com/how-to-learn-r-2/" rel="nofollow">learning R</a> and many other topics. <a title="Data science jobs" href="https://www.r-users.com/" rel="nofollow">Click here if you're looking to post or find an R/data-science job</a>.

<hr>Want to share your content on R-bloggers?<a href="https://www.r-bloggers.com/add-your-blog/" rel="nofollow"> click here</a> if you have a blog, or <a href="http://r-posts.com/" rel="nofollow"> here</a> if you don't.
</div><strong>Continue reading</strong>: <a href="https://www.r-bloggers.com/2026/08/jags-5-0-0-is-released/">JAGS 5.0.0 is released</a>]]></content:encoded>
					
		
		<enclosure url="https://martynplummer.wordpress.com/wp-content/uploads/2026/05/img_0083.jpg" length="0" type="" />
<enclosure url="https://0.gravatar.com/avatar/fdc509bd31ae635d89cccbdc64ef09464ea1c20d7858c4089a07ea3bea91b8e3?s=96&#038;d=identicon&#038;r=G" length="0" type="" />
<enclosure url="https://martynplummer.wordpress.com/wp-content/uploads/2026/08/img_0134.jpg?w=1024" length="0" type="" />

		<post-id xmlns="com-wordpress:feed-additions:1">402933</post-id>	</item>
		<item>
		<title>How Do I Build a Model? A Starting Guide for New Modellers</title>
		<link>https://www.r-bloggers.com/2026/08/how-do-i-build-a-model-a-starting-guide-for-new-modellers/</link>
		
		<dc:creator><![CDATA[Seascapemodels]]></dc:creator>
		<pubDate>Sun, 02 Aug 2026 14:00:00 +0000</pubDate>
				<category><![CDATA[R bloggers]]></category>
		<guid isPermaLink="false">https://www.seascapemodels.org/posts/2026-08-03-how-do-i-build-a-model/</guid>

					<description><![CDATA[<div style = "width:60%; display: inline-block; float:left; ">
<p>I’ve put together a short guide: How Do I Build a Model? A starting guide for new modellers. It’s free, online, and aimed squarely at the graduate student who has a research question and is staring at a blank script wondering where to even begin...</p></div>
<div style = "width: 40%; display: inline-block; float:right;"></div>
<div style="clear: both;"></div>
<strong>Continue reading</strong>: <a href="https://www.r-bloggers.com/2026/08/how-do-i-build-a-model-a-starting-guide-for-new-modellers/">How Do I Build a Model? A Starting Guide for New Modellers</a>]]></description>
										<content:encoded><![CDATA[<!-- 
<div style="min-height: 30px;">
[social4i size="small" align="align-left"]
</div>
-->

<div style="border: 1px solid; background: none repeat scroll 0 0 #EDEDED; margin: 1px; font-size: 12px;">
[This article was first published on  <strong><a href="https://www.seascapemodels.org/posts/2026-08-03-how-do-i-build-a-model/"> Seascapemodels</a></strong>, and kindly contributed to <a href="https://www.r-bloggers.com/" rel="nofollow">R-bloggers</a>].  (You can report issue about the content on this page <a href="https://www.r-bloggers.com/contact-us/">here</a>)
<hr>Want to share your content on R-bloggers?<a href="https://www.r-bloggers.com/add-your-blog/" rel="nofollow"> click here</a> if you have a blog, or <a href="http://r-posts.com/" rel="nofollow"> here</a> if you don't.
</div>
 





<p>I’ve put together a short guide: <em>How Do I Build a Model? A starting guide for new modellers</em>. It’s free, online, and aimed squarely at the graduate student who has a research question and is staring at a blank script wondering where to even begin.</p>
<p>You can read it online at <a href="https://www.seascapemodels.org/building-ecological-models/" rel="nofollow" target="_blank">How Do I Build a Model?</a>, or <a href="https://github.com/cbrown5/building-ecological-models/blob/main/docs/How-Do-I-Build-a-Model-.pdf" rel="nofollow" target="_blank">download a pdf</a>.</p>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://i1.wp.com/www.seascapemodels.org/posts/2026-08-03-how-do-i-build-a-model/flowchart-loop.png?w=578&#038;ssl=1" class="img-fluid figure-img" data-recalc-dims="1"></p>
<figcaption>First sketch, one of the steps on the way to buliding a working model</figcaption>
</figure>
</div>
<p>I’ve never settled into one corner of ecological modelling. I’m not the Bayesian guy, or the foodweb model guy, or the machine learning guy, though I’ve dabbled in all three. That haphazard career has given me a broad view across a lot of different modelling traditions, and I keep noticing the same meta-principles showing up regardless of the discipline. This guide is my attempt to write those down.</p>
<p>It’s not a textbook on any particular method. Once you know what type of model you’re building, go read a book by a discipline expert (I’ve listed some favourites in the final chapter). This guide is for the step before that: turning a question into a model in the first place.</p>
<section id="whats-in-it" class="level2">
<h2 class="anchored" data-anchor-id="whats-in-it">What’s in it</h2>
<ol type="1">
<li><strong>Start with the question.</strong> How you actually grow into a research question, through reading, writing, and talking it through with people whose work you admire (and some whose work you don’t).</li>
<li><strong>From a question to a type of model.</strong> Once you know your question, how to read papers differently, paying attention to the <em>how</em> and the <em>why</em>.</li>
<li><strong>Terminology: variables, parameters, and the rest.</strong> A clean-up of vocabulary that gets used loosely and causes confusion.</li>
<li><strong>Know why you’re building a model.</strong> Causal inference, prediction, or something else. Knowing your purpose is what narrows down the type of model you need.</li>
<li><strong>Sketching your model.</strong> Why you should start at a whiteboard with boxes and arrows before you touch an equation, and how to read those arrows as equations later.</li>
<li><strong>The different types of uncertainty.</strong> Why “how uncertain am I?” is really several different questions, and why that distinction matters for what you do next.</li>
<li><strong>Writing your model’s equations.</strong> Turning the diagram into notation, with a nod to Edwards &#038; Auger-Méthé’s guidance for ecologists, which I’d recommend reading in full regardless.</li>
<li><strong>Understand your constraints.</strong> Computational, data, and time constraints, and how they shape what model you can realistically build.</li>
<li><strong>The modelling workflow.</strong> Feedback loops of writing code, debugging, running, plotting, interpreting.</li>
<li><strong>Tools and software.</strong> The endless R-versus-Python debate, and why your own familiarity with a tool is a constraint.</li>
<li><strong>Tips for finding novel insights.</strong> Some of my favourite tricks, including hunting for analogues in other fields and pushing them to their extreme.</li>
</ol>
<p>There’s also a short further-reading list at the end, covering the books I’d point you to once you’ve picked your modelling approach.</p>
</section>
<section id="how-it-came-together" class="level2">
<h2 class="anchored" data-anchor-id="how-it-came-together">How it came together</h2>
<p>I dictated the original version on a long drive, Claude Code cleaned up the transcript into a first written draft and set up the Quarto book site, and I edited it from there.</p>


</section>

 
<div style="border: 1px solid; background: none repeat scroll 0 0 #EDEDED; margin: 1px; font-size: 13px;">
<div style="text-align: center;">To <strong>leave a comment</strong> for the author, please follow the link and comment on their blog: <strong><a href="https://www.seascapemodels.org/posts/2026-08-03-how-do-i-build-a-model/"> Seascapemodels</a></strong>.</div>
<hr />
<a href="https://www.r-bloggers.com/" rel="nofollow">R-bloggers.com</a> offers <strong><a href="https://feedburner.google.com/fb/a/mailverify?uri=RBloggers" rel="nofollow">daily e-mail updates</a></strong> about <a title="The R Project for Statistical Computing" href="https://www.r-project.org/" rel="nofollow">R</a> news and tutorials about <a title="R tutorials" href="https://www.r-bloggers.com/how-to-learn-r-2/" rel="nofollow">learning R</a> and many other topics. <a title="Data science jobs" href="https://www.r-users.com/" rel="nofollow">Click here if you're looking to post or find an R/data-science job</a>.

<hr>Want to share your content on R-bloggers?<a href="https://www.r-bloggers.com/add-your-blog/" rel="nofollow"> click here</a> if you have a blog, or <a href="http://r-posts.com/" rel="nofollow"> here</a> if you don't.
</div><strong>Continue reading</strong>: <a href="https://www.r-bloggers.com/2026/08/how-do-i-build-a-model-a-starting-guide-for-new-modellers/">How Do I Build a Model? A Starting Guide for New Modellers</a>]]></content:encoded>
					
		
		<enclosure url="" length="0" type="" />

		<post-id xmlns="com-wordpress:feed-additions:1">402938</post-id>	</item>
		<item>
		<title>Analyzing Financial Trends: Kalman Filtering for Gold vs Bitcoin</title>
		<link>https://www.r-bloggers.com/2026/08/analyzing-financial-trends-kalman-filtering-for-gold-vs-bitcoin/</link>
		
		<dc:creator><![CDATA[Selcuk Disci]]></dc:creator>
		<pubDate>Sun, 02 Aug 2026 12:45:19 +0000</pubDate>
				<category><![CDATA[R bloggers]]></category>
		<guid isPermaLink="false">http://datageeek.com/?p=12417</guid>

					<description><![CDATA[<div style = "width:60%; display: inline-block; float:left; "> In their paper “A Synchronized Multi‑IMU Wearable System for Tracking of Joint‑Angles in Sports Motion Analysis” (arXiv:2607.26027v1), Samarasekera and colleagues set out to solve a very practical problem: how to reliably measure joint angles in dynamic sports movements using wearable IMUs. Their goal was to design a ...</div>
<div style = "width: 40%; display: inline-block; float:right;"></div>
<div style="clear: both;"></div>
<strong>Continue reading</strong>: <a href="https://www.r-bloggers.com/2026/08/analyzing-financial-trends-kalman-filtering-for-gold-vs-bitcoin/">Analyzing Financial Trends: Kalman Filtering for Gold vs Bitcoin</a>]]></description>
										<content:encoded><![CDATA[<!-- 
<div style="min-height: 30px;">
[social4i size="small" align="align-left"]
</div>
-->

<div style="border: 1px solid; background: none repeat scroll 0 0 #EDEDED; margin: 1px; font-size: 12px;">
[This article was first published on  <strong><a href="https://datageeek.com/2026/08/02/analyzing-financial-trends-kalman-filtering-for-gold-vs-bitcoin/"> DataGeeek</a></strong>, and kindly contributed to <a href="https://www.r-bloggers.com/" rel="nofollow">R-bloggers</a>].  (You can report issue about the content on this page <a href="https://www.r-bloggers.com/contact-us/">here</a>)
<hr>Want to share your content on R-bloggers?<a href="https://www.r-bloggers.com/add-your-blog/" rel="nofollow"> click here</a> if you have a blog, or <a href="http://r-posts.com/" rel="nofollow"> here</a> if you don't.
</div>

<p class="wp-block-paragraph">In their paper <em>“A Synchronized Multi‑IMU Wearable System for Tracking of Joint‑Angles in Sports Motion Analysis”</em> (<a href="https://arxiv.org/html/2607.26027v1" rel="nofollow" target="_blank">arXiv:2607.26027v1</a>), Samarasekera and colleagues set out to solve a very practical problem: <strong>how to reliably measure joint angles in dynamic sports movements using wearable IMUs</strong>. Their goal was to design a synchronized pipeline that could filter out noise, correct drift, and normalize ranges so that biomechanical signals could be trusted in real‑world conditions.</p>



<p class="wp-block-paragraph">Our goal is different but conceptually parallel: <strong>to apply the same pipeline logic to financial time‑series data</strong>. Instead of knee flexion angles, we analyze the comparative dynamics of Gold and Bitcoin. The challenge is similar — financial returns are noisy, prone to drift, and difficult to compare directly. By adapting their pipeline, we aim to extract latent trends, mitigate drift, normalize ranges, and highlight relative divergence between assets.</p>



<p class="wp-block-paragraph">The pipeline consists of four sequential stages:</p>



<ol start="1" class="wp-block-list">
<li><strong>Indirect Kalman Filtering (IKF)</strong> – extracting latent trends from noisy log returns.
<ul class="wp-block-list">
<li>State equation:</li>
</ul>
</li>
</ol>



<p class="wp-block-paragraph"><math display="block"><mrow><msub><mi>x</mi><mi>t</mi></msub><mo>=</mo><mi>F</mi><mo>⋅</mo><msub><mi>x</mi><mrow><mi>t</mi><mo>−</mo><mn>1</mn></mrow></msub><mo>+</mo><msub><mi>w</mi><mi>t</mi></msub><mo separator="true">,</mo><mspace width="1em"></mspace><msub><mi>w</mi><mi>t</mi></msub><mo>∼</mo><mi>N</mi><mo stretchy="false">(</mo><mn>0</mn><mo separator="true">,</mo><mi>Q</mi><mo stretchy="false">)</mo></mrow></math></p>



<ul class="wp-block-list">
<li>Observation equation:</li>
</ul>



<p class="wp-block-paragraph"><math display="block"><mrow><msub><mi>y</mi><mi>t</mi></msub><mo>=</mo><mi>H</mi><mo>⋅</mo><msub><mi>x</mi><mi>t</mi></msub><mo>+</mo><msub><mi>v</mi><mi>t</mi></msub><mo separator="true">,</mo><mspace width="1em"></mspace><msub><mi>v</mi><mi>t</mi></msub><mo>∼</mo><mi>N</mi><mo stretchy="false">(</mo><mn>0</mn><mo separator="true">,</mo><mi>R</mi><mo stretchy="false">)</mo></mrow></math></p>



<ul class="wp-block-list">
<li>IKF separates signal from noise, with <math><mrow><mi>Q</mi></mrow></math> and <math><mrow><mi>R</mi></mrow></math> learned via maximum likelihood.</li>
</ul>



<ol start="2" class="wp-block-list">
<li><strong>Drift Mitigation via High‑Pass Filtering</strong> – removing low‑frequency bias.
<ul class="wp-block-list">
<li>High‑pass operator:</li>
</ul>
</li>
</ol>



<p class="wp-block-paragraph"><math display="block"><mrow><msubsup><mi>x</mi><mi>t</mi><mrow><mi>H</mi><mi>P</mi></mrow></msubsup><mo>=</mo><msub><mi>x</mi><mi>t</mi></msub><mo>−</mo><mfrac><mn>1</mn><mi>N</mi></mfrac><munderover><mo>∑</mo><mrow><mi>i</mi><mo>=</mo><mn>1</mn></mrow><mi>N</mi></munderover><msub><mi>x</mi><mrow><mi>t</mi><mo>−</mo><mi>i</mi></mrow></msub></mrow></math></p>



<ul class="wp-block-list">
<li>This ensures long‑term drift does not dominate short‑term dynamics.</li>
</ul>



<ol start="3" class="wp-block-list">
<li><strong>Range Normalization</strong> – mapping filtered values into a comparable scale.
<ul class="wp-block-list">
<li>Normalization function:</li>
</ul>
</li>
</ol>



<p class="wp-block-paragraph"><math display="block"><mrow><msub><mi>z</mi><mi>t</mi></msub><mo>=</mo><mfrac><mrow><msubsup><mi>x</mi><mi>t</mi><mrow><mi>H</mi><mi>P</mi></mrow></msubsup><mo>−</mo><mi>min</mi><mo>⁡</mo><mo stretchy="false">(</mo><msup><mi>x</mi><mrow><mi>H</mi><mi>P</mi></mrow></msup><mo stretchy="false">)</mo></mrow><mrow><mi>max</mi><mo>⁡</mo><mo stretchy="false">(</mo><msup><mi>x</mi><mrow><mi>H</mi><mi>P</mi></mrow></msup><mo stretchy="false">)</mo><mo>−</mo><mi>min</mi><mo>⁡</mo><mo stretchy="false">(</mo><msup><mi>x</mi><mrow><mi>H</mi><mi>P</mi></mrow></msup><mo stretchy="false">)</mo></mrow></mfrac><mo>⋅</mo><mn>100</mn></mrow></math></p>



<ul class="wp-block-list">
<li>This allows Gold and Bitcoin to be compared on the same 0–100 scale.</li>
</ul>



<ol start="4" class="wp-block-list">
<li><strong>Relative Notation (Directional Divergence)</strong> – highlighting when assets move in opposite directions.
<ul class="wp-block-list">
<li>Divergence indicator:</li>
</ul>
</li>
</ol>



<p class="wp-block-paragraph"><math display="block"><mrow><msub><mi>D</mi><mi>t</mi></msub><mo>=</mo><mtext>sign</mtext><mo stretchy="false">(</mo><msubsup><mi>r</mi><mi>t</mi><mrow><mi>G</mi><mi>o</mi><mi>l</mi><mi>d</mi></mrow></msubsup><mo stretchy="false">)</mo><mo>≠</mo><mtext>sign</mtext><mo stretchy="false">(</mo><msubsup><mi>r</mi><mi>t</mi><mrow><mi>B</mi><mi>T</mi><mi>C</mi></mrow></msubsup><mo stretchy="false">)</mo></mrow></math></p>



<ul class="wp-block-list">
<li>If true, shaded regions show divergence; if false, alignment.</li>
</ul>



<h3 class="wp-block-heading">Why This Matters</h3>



<ul class="wp-block-list">
<li>For the biomechanics researchers, the pipeline meant <strong>trustworthy joint‑angle tracking</strong>.</li>



<li>For us, the same architecture means <strong>trustworthy comparative trend analysis</strong> between financial assets.</li>



<li>In both cases, the pipeline’s strength lies in its modularity: IKF for latent signal extraction, high‑pass filtering for drift control, normalization for comparability, and relative notation for divergence detection.</li>
</ul>



<h2 class="wp-block-heading">✦ R Packages in Our Pipeline</h2>



<p class="wp-block-paragraph">To make this pipeline reproducible and transparent, we rely on a set of R packages. Each package plays a specific role in the architecture:</p>



<ol start="1" class="wp-block-list">
<li><strong>tidyverse</strong>
<ul class="wp-block-list">
<li>Purpose: Data manipulation and wrangling.</li>



<li>Functions: <code>mutate</code>, <code>rename</code>, <code>inner_join</code>, <code>drop_na</code>.</li>



<li>Why: Provides a clean grammar for transforming raw financial data into structured time‑series.</li>
</ul>
</li>



<li><strong>tidyquant</strong>
<ul class="wp-block-list">
<li>Purpose: Financial data acquisition and transformation.</li>



<li>Functions: <code>tq_get</code> (download asset prices), <code>tq_transmute</code> (compute log returns).</li>



<li>Why: Bridges tidyverse with financial APIs, enabling reproducible market data pipelines.</li>
</ul>
</li>



<li><strong>KFAS</strong>
<ul class="wp-block-list">
<li>Purpose: State‑space modeling and Kalman filtering.</li>



<li>Functions: <code>SSModel</code> (define state‑space model), <code>fitSSM</code> (MLE parameter estimation), <code>KFS</code> (Kalman smoothing).</li>



<li>Why: Implements the mathematical backbone of IKF, separating latent trends from noise.</li>
</ul>
</li>



<li><strong>zoo</strong>
<ul class="wp-block-list">
<li>Purpose: Rolling window operations.</li>



<li>Functions: <code>rollmean</code>.</li>



<li>Why: Used for high‑pass filtering by subtracting rolling averages, mitigating drift.</li>
</ul>
</li>



<li><strong>scales</strong>
<ul class="wp-block-list">
<li>Purpose: Normalization and rescaling.</li>



<li>Functions: <code>rescale</code>.</li>



<li>Why: Maps filtered trends into a 0–100 range, enabling comparability across assets.</li>
</ul>
</li>



<li><strong>ggbraid</strong>
<ul class="wp-block-list">
<li>Purpose: Divergence visualization.</li>



<li>Functions: <code>geom_braid</code>.</li>



<li>Why: Highlights periods of divergence between Gold and Bitcoin with shaded regions.</li>
</ul>
</li>



<li><strong>ggplot2 (via tidyverse)</strong>
<ul class="wp-block-list">
<li>Purpose: Visualization.</li>



<li>Functions: <code>geom_line</code>, <code>labs</code>, <code>theme_classic</code>.</li>



<li>Why: Provides the plotting framework for presenting normalized high‑pass Kalman trends.</li>
</ul>
</li>
</ol>


<pre>
library(tidyverse)
library(tidyquant)
library(KFAS)
library(ggbraid)

# --- Step 1: Log returns ---
gold &lt;- tq_get(&quot;GC=F&quot;, from = &quot;2024-01-01&quot;) %&gt;%
  tq_transmute(select = close,
               mutate_fun = periodReturn,
               period = &quot;daily&quot;,
               type = &quot;log&quot;)

btc &lt;- tq_get(&quot;BTC-USD&quot;, from = &quot;2024-01-01&quot;) %&gt;%
  tq_transmute(select = close,
               mutate_fun = periodReturn,
               period = &quot;daily&quot;,
               type = &quot;log&quot;)

df &lt;- gold %&gt;%
  rename(ret_gold = daily.returns) %&gt;%
  inner_join(btc %&gt;% rename(ret_btc = daily.returns), by=&quot;date&quot;) %&gt;%
  drop_na()

# --- Step 2: IKF (Kalman filter) ---
model_gold &lt;- SSModel(df$ret_gold ~ SSMtrend(1, Q = list(NA)), H = NA)
model_btc  &lt;- SSModel(df$ret_btc  ~ SSMtrend(1, Q = list(NA)), H = NA)

fit_gold &lt;- fitSSM(model_gold, inits = c(log(var(df$ret_gold)), log(var(df$ret_gold))))
fit_btc  &lt;- fitSSM(model_btc,  inits = c(log(var(df$ret_btc)),  log(var(df$ret_btc))))

kf_gold &lt;- KFS(fit_gold$model, smoothing = c(&quot;state&quot;))
kf_btc  &lt;- KFS(fit_btc$model,  smoothing = c(&quot;state&quot;))

trend_gold &lt;- as.numeric(kf_gold$alphahat)
trend_btc  &lt;- as.numeric(kf_btc$alphahat)

# --- Step 3: High-pass filter (remove low-frequency drift) ---
hp_gold &lt;- trend_gold - zoo::rollmean(trend_gold, k=30, fill=NA, align=&quot;right&quot;)
hp_btc  &lt;- trend_btc  - zoo::rollmean(trend_btc,  k=30, fill=NA, align=&quot;right&quot;)

# --- Step 4: Range normalization ---
gold_norm &lt;- scales::rescale(hp_gold, to=c(0,100))
btc_norm  &lt;- scales::rescale(hp_btc,  to=c(0,100))

# --- Step 5: Relative notation (directional divergence) ---
df_norm &lt;- df %&gt;%
  mutate(
    gold_norm = gold_norm,
    btc_norm  = btc_norm,
    sign_gold = sign(ret_gold),
    sign_btc  = sign(ret_btc),
    divergence = sign_gold != sign_btc
  )

# --- Plot ---
ggplot(df_norm, aes(x=date)) +
  geom_line(aes(y=gold_norm, color=&quot;Gold&quot;), linewidth=1.2) +
  geom_line(aes(y=btc_norm, color=&quot;Bitcoin&quot;), linewidth=1.2) +
  geom_braid(aes(ymin=gold_norm, ymax=btc_norm, fill=divergence), alpha=0.3) +
  scale_color_manual(values=c(&quot;Gold&quot;=&quot;#FFD700&quot;, &quot;Bitcoin&quot;=&quot;#1E3A8A&quot;),
                     name = &quot;&quot;) +
  scale_fill_manual(values=c(&quot;TRUE&quot;=&quot;#FF4C4C&quot;, &quot;FALSE&quot;=&quot;#87CEFA&quot;),
                    name = &quot;Divergence&quot;) +
  scale_y_continuous(limits=c(0,100)) +
  labs(title=&quot;Gold vs Bitcoin: Kalman-Filtered High-Pass Trends&quot;,
       subtitle=&quot;Directional divergence highlighted with shaded regions&quot;,
       x=&quot;&quot;, y=&quot;Normalized High-Pass Kalman Trend&quot;) +
  theme_classic(base_family = &quot;Roboto Slab&quot;) +
  theme(
    legend.position=&quot;bottom&quot;,
    legend.title=element_text(size=12, face=&quot;bold&quot;),
    legend.text=element_text(size=10),
    plot.title=element_text(size=16, face=&quot;bold&quot;),
    plot.subtitle=element_text(size=12),
    axis.title=element_text(size=12, face=&quot;bold&quot;),
    axis.text=element_text(size=10),
    panel.grid.minor=element_blank()
  )

</pre>


<figure data-wp-context="{"imageId":"6a6f3e4d5975b"}" data-wp-interactive="core/image" data-wp-key="6a6f3e4d5975b" class="wp-block-image size-full wp-lightbox-container"><img data-attachment-id="12432" data-permalink="https://datageeek.com/2026/08/02/analyzing-financial-trends-kalman-filtering-for-gold-vs-bitcoin/kalman/" data-orig-file="https://i1.wp.com/datageeek.com/wp-content/uploads/2026/08/kalman-1.png?w=578&#038;ssl=1" data-orig-size="948,683" data-comments-opened="1" data-image-meta="{"aperture":"0","credit":"","camera":"","caption":"","created_timestamp":"0","copyright":"","focal_length":"0","iso":"0","shutter_speed":"0","title":"","orientation":"0","alt":""}" data-image-title="kalman" data-image-description="" data-image-caption="" data-large-file="https://i1.wp.com/datageeek.com/wp-content/uploads/2026/08/kalman-1.png?w=578&#038;ssl=1?w=948" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on--pointerdown="actions.preloadImage" data-wp-on--pointerenter="actions.preloadImageWithDelay" data-wp-on--pointerleave="actions.cancelPreload" data-wp-on-window--resize="callbacks.setButtonStyles" src="https://i1.wp.com/datageeek.com/wp-content/uploads/2026/08/kalman-1.png?w=578&#038;ssl=1" alt="" class="wp-image-12432" data-recalc-dims="1" /><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			data-wp-bind--aria-label="state.thisImage.triggerButtonAriaLabel"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.thisImage.buttonRight"
			data-wp-style--top="state.thisImage.buttonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button></figure>



<h2 class="wp-block-heading"><img src="https://i2.wp.com/s0.wp.com/wp-content/mu-plugins/wpcom-smileys/twemoji/2/72x72/1f539.png?w=578&#038;ssl=1" alt="&#x1f539;" class="wp-smiley" style="height: 1em; max-height: 1em;" data-recalc-dims="1" /> Conclusion</h2>



<p class="wp-block-paragraph">By adapting the IKF pipeline from the sports biomechanics paper, we demonstrate how <strong>state‑space filtering</strong>, drift mitigation, and normalization can reveal comparative dynamics among financial assets. This modular approach is reproducible and extensible to other domains where latent trends and divergence matter.</p>



<p class="wp-block-paragraph"></p>

<div style="border: 1px solid; background: none repeat scroll 0 0 #EDEDED; margin: 1px; font-size: 13px;">
<div style="text-align: center;">To <strong>leave a comment</strong> for the author, please follow the link and comment on their blog: <strong><a href="https://datageeek.com/2026/08/02/analyzing-financial-trends-kalman-filtering-for-gold-vs-bitcoin/"> DataGeeek</a></strong>.</div>
<hr />
<a href="https://www.r-bloggers.com/" rel="nofollow">R-bloggers.com</a> offers <strong><a href="https://feedburner.google.com/fb/a/mailverify?uri=RBloggers" rel="nofollow">daily e-mail updates</a></strong> about <a title="The R Project for Statistical Computing" href="https://www.r-project.org/" rel="nofollow">R</a> news and tutorials about <a title="R tutorials" href="https://www.r-bloggers.com/how-to-learn-r-2/" rel="nofollow">learning R</a> and many other topics. <a title="Data science jobs" href="https://www.r-users.com/" rel="nofollow">Click here if you're looking to post or find an R/data-science job</a>.

<hr>Want to share your content on R-bloggers?<a href="https://www.r-bloggers.com/add-your-blog/" rel="nofollow"> click here</a> if you have a blog, or <a href="http://r-posts.com/" rel="nofollow"> here</a> if you don't.
</div><strong>Continue reading</strong>: <a href="https://www.r-bloggers.com/2026/08/analyzing-financial-trends-kalman-filtering-for-gold-vs-bitcoin/">Analyzing Financial Trends: Kalman Filtering for Gold vs Bitcoin</a>]]></content:encoded>
					
		
		<enclosure url="https://datageeek.com/wp-content/uploads/2026/08/kalman_featured-3.png" length="0" type="" />
<enclosure url="https://1.gravatar.com/avatar/db5e3f9ef188ea98fe38ab05c5a3fad9fb52fe3472715a8fc02f7ea41731f77c?s=96&#038;d=identicon&#038;r=G" length="0" type="" />
<enclosure url="https://datageeek.com/wp-content/uploads/2026/08/kalman-1.png" length="0" type="" />

		<post-id xmlns="com-wordpress:feed-additions:1">402923</post-id>	</item>
		<item>
		<title>The Future of Programming Looks Like Its Past or Why I build T</title>
		<link>https://www.r-bloggers.com/2026/08/the-future-of-programming-looks-like-its-past-or-why-i-build-t/</link>
		
		<dc:creator><![CDATA[Econometrics and Free Software]]></dc:creator>
		<pubDate>Sun, 02 Aug 2026 00:00:00 +0000</pubDate>
				<category><![CDATA[R bloggers]]></category>
		<guid isPermaLink="false">https://b-rodrigues.github.io/posts/2026-08-02-t_devlog.html</guid>

					<description><![CDATA[<div style = "width:60%; display: inline-block; float:left; ">
<p>This is a post based on two other posts I wrote for LinkedIn. It has become quite long.</p>
<p>AI Won’t Save People From Work They Never Thought to Automate<br />
I’m a fairly optimistic person, but when it comes to AI adoption and how it will be gene...</p></div>
<div style = "width: 40%; display: inline-block; float:right;"></div>
<div style="clear: both;"></div>
<strong>Continue reading</strong>: <a href="https://www.r-bloggers.com/2026/08/the-future-of-programming-looks-like-its-past-or-why-i-build-t/">The Future of Programming Looks Like Its Past or Why I build T</a>]]></description>
										<content:encoded><![CDATA[<!-- 
<div style="min-height: 30px;">
[social4i size="small" align="align-left"]
</div>
-->

<div style="border: 1px solid; background: none repeat scroll 0 0 #EDEDED; margin: 1px; font-size: 12px;">
[This article was first published on  <strong><a href="https://b-rodrigues.github.io/posts/2026-08-02-t_devlog.html"> Econometrics and Free Software</a></strong>, and kindly contributed to <a href="https://www.r-bloggers.com/" rel="nofollow">R-bloggers</a>].  (You can report issue about the content on this page <a href="https://www.r-bloggers.com/contact-us/">here</a>)
<hr>Want to share your content on R-bloggers?<a href="https://www.r-bloggers.com/add-your-blog/" rel="nofollow"> click here</a> if you have a blog, or <a href="http://r-posts.com/" rel="nofollow"> here</a> if you don't.
</div>
 




<div style="text-align: center;">
<p>
<a> <img src="https://i0.wp.com/b-rodrigues.github.io/assets/img/tlogo.png?w=578&#038;ssl=1" style="width: 50%; height: auto;" data-recalc-dims="1"> </a>
</p>
</div>
<p><em>This is a post based on two other posts I wrote for LinkedIn. It has become quite long.</em></p>
<section id="ai-wont-save-people-from-work-they-never-thought-to-automate" class="level2">
<h2 class="anchored" data-anchor-id="ai-wont-save-people-from-work-they-never-thought-to-automate">AI Won’t Save People From Work They Never Thought to Automate</h2>
<p>I’m a fairly optimistic person, but when it comes to AI adoption and how it will be generating billions in increased GDP I’m more skeptical. Not that AI is not capable: on the contrary, I think that for all intents and purposes, even the models from 6 months ago are more than capable enough to perform a majority of white collar tasks, including programming. No, I think the issue is the same I’ve observed many times over my years on this God’s green earth, and that is that there are people who see computers as tools for doing tasks and people who see computers as systems that can be taught to do tasks.</p>
<p>Consider two people using Excel. Both have used it for ten years.</p>
<p>Jim receives a monthly report and manually copies data between sheets, formats cells, and updates numbers. He’s learned the workflow and can execute it efficiently. He’s essentially performing the task using a computer as he would with a pen and paper. He’s doing procedural work. That’s his job, and he’s good at it.</p>
<p>Bill, on the other hand, asks himself the question: “Why am I doing this every month? Is my job actually about moving data around? Or is it something else? What is my purpose?” Now this may seem overly philosophical when the topic at hand is moving data around in Excel to increase shareholder value, but nonetheless, these questions are the right ones to ask. So Bill starts seeing his computer not as a tool that simply replaced pen and paper, but as something he can teach to perform tasks.</p>
<p>Bill learns about formulas. Bill learns about pivot tables. Using the free tier of an LLM he makes it write macros. He then even creates styles for Word instead of changing the headers manually each time.</p>
<p>The difference is not technical ability. Both Jim and Bill can operate Excel and Word. But the difference is the mental model. Jim sees the computer as a digital version of pen and paper. It is a place where work happens. Bill sees the computer as a machine that can execute rules. It is a place where work can be transformed into a repeatable system.</p>
<p>Bill has an automation mindset. People with an automation mindset naturally ask different questions. Instead of:</p>
<p>“How do I complete this task?”</p>
<p>they ask:</p>
<ul>
<li>“This fucking sucks and surely there’s a better way of doing it?”</li>
</ul>
<p>Instead of:</p>
<ul>
<li>“How do I make this report?”</li>
</ul>
<p>they ask:</p>
<ul>
<li>“How can this report generate itself and fuck off?”</li>
</ul>
<p>Instead of:</p>
<ul>
<li>“How do I process these 1000 files?”</li>
</ul>
<p>they ask:</p>
<ul>
<li>“How can I write a process that handles any number of files?”</li>
</ul>
<p>The key shift is recognizing that anything you do is required to follow rules, and these rules are mostly implicit and invisible. It is moving from thinking about individual actions to thinking about the underlying rules that matters.</p>
<p>Computers are powerful because they are not just faster versions of humans. Their real advantage is that they can execute instructions that follow rules repeatedly, consistently, and at scale, but you gotta provide them with the rules.</p>
</section>
<section id="the-real-barrier-to-ai-automation-mindset-tools-and-culture" class="level2">
<h2 class="anchored" data-anchor-id="the-real-barrier-to-ai-automation-mindset-tools-and-culture">The Real Barrier to AI Automation: Mindset, Tools, and Culture</h2>
<p>A common assumption is that AI will democratize automation because people no longer need to know how to program, which is certainly true (to some extent). AI dramatically lowers the technical barrier. Someone can now describe a workflow in natural language and get help creating scripts, automations, or processes.</p>
<p>But there is a more fundamental barrier: people have to imagine that automation is possible in the first place!</p>
<p>Someone who has never thought about programming will not suddenly become an automation architect just because they have access to an AI assistant.</p>
<ul>
<li>Jim may use AI to write an email faster.</li>
<li>Jim may use AI to summarize a document.</li>
<li>Jim may use AI to answer a question.</li>
</ul>
<p>Those are useful improvements.</p>
<p>But Bill is playing another game entirely. He’s thinking about implicit rules, and how to make them explicit (which, by the way, can also be done with AI!). So he’s rubber ducking with Claude and asking it:</p>
<ul>
<li>“Why does this task exist at all?”</li>
<li>“Could this entire workflow disappear?”</li>
<li>“Could you (Claude) write a Python script/Excel Macro to run this every week?”</li>
</ul>
<p>While certainly AI lowers the cost of building systems, it does not automatically teach people to think in systems.</p>
<p>It is not Jim’s fault though. This difference in mindset can even be seen in operating systems. Historically, Windows has emphasized graphical workflows. The philosophy is often: “There is a tool or button for every task. This Word document just looks like an actual sheet of paper, so treat it as such. This Excel workbook just looks like an actual ledger your grandpa used to use, so treat it as such.” Linux and Unix come from a different tradition: “Everything is a program. Programs can be combined. You pass data from program to program by streams of text. Text is the fundamental unit of information.”</p>
<p>A Linux user solving a repetitive problem often starts with a command, then turns that command into a script, then schedules that script to run automatically.</p>
<p>The progression is natural:</p>
<p>Manual action → command → script → automated system.</p>
<p>Windows has powerful automation capabilities too. PowerShell is an extremely capable scripting environment. But for too long, Windows’ main target audience was (and still is) the white collar office drone. Even though it is absolutely possible to automate tasks on Windows, the culture now is not one of automation. And technology alone does not create culture.</p>
<p>There are many such examples. Consider using a regular text editor like VS Code versus something like Vim. With regular text editors, you essentially use your computer as a fancy pen and paper. With Vim, you manipulate text and think about ranges and how to operate on them using macros. Very different mental models. In fact, they’re so different that trying to explain Vim to someone not familiar with it is practically impossible. People can only truly get it if they try it and keep using it for some time. And it’s the same thing with data analysis: using Excel vs R for example. The surrounding culture matters. If users grow up thinking:</p>
<ul>
<li>“The computer is a place where I click through tasks,”</li>
</ul>
<p>they will rarely ask:</p>
<ul>
<li>“How can the computer do this task for me?”</li>
</ul>
<p>The tool exists. The mindset does not.</p>
</section>
<section id="transforming-organizations-rewarding-work-elimination" class="level2">
<h2 class="anchored" data-anchor-id="transforming-organizations-rewarding-work-elimination">Transforming Organizations: Rewarding Work Elimination</h2>
<p>Many companies are approaching AI transformation as a training problem: teach employees how to use AI tools. But the deeper challenge is a thinking problem: teach employees how to identify opportunities for automation. The most valuable AI employees will not necessarily be the people who write the cleverest prompts. They will be the people who notice:</p>
<ul>
<li>“Everyone spends two hours every week doing this repetitive process.”</li>
<li>“This information is copied manually between systems.”</li>
<li>“This decision follows a predictable set of rules. These rules are not written down anywhere, but they exist.”</li>
<li>“This workflow exists only because nobody questioned it.”</li>
</ul>
<p>Those people are the ones who will transform organizations, and organizations need to create an incentive structure where people are rewarded for eliminating work, not for performing more work. The irony is that many organizations say they want efficiency but reward visible effort. True AI transformation requires rewarding people who make themselves unnecessary.</p>
<p>The biggest advantage of AI will not come from people who use it as a faster assistant. It will come from people who use it as a way to redesign work. The question that separates the old way of working from the new one is simple:</p>
<ul>
<li>“Why am I doing this manually at all?”</li>
</ul>
<p>AI is powerful because it makes accessing automation easier than ever before. But the greatest gains will go to those who already understand the fundamental idea behind computers:</p>
<p><strong>A computer is not just a tool for performing tasks!</strong></p>
<p>It is a machine for turning ideas, rules, and processes into systems that run.</p>
</section>
<section id="jupyter-notebooks-and-interactive-data-analysis-are-dead-one-can-hope" class="level2">
<h2 class="anchored" data-anchor-id="jupyter-notebooks-and-interactive-data-analysis-are-dead-one-can-hope">Jupyter Notebooks (and Interactive Data Analysis) Are Dead (one can hope)</h2>
<p>Now how do these observations translate to our work as data scientists?</p>
<p>I’ve spent years watching data science workflows evolve, and I keep coming back to the same conclusion:</p>
<p>Jupyter notebooks are making data science and statistics worse. I’d even go so far as to argue that interactive data analysis may be the wrong mental model altogether.</p>
<p>Let’s start with notebooks. If you’ve been reading my work these past years, you know I’m not fond of them.</p>
<p>They encourage messy, non-reproducible “spaghetti” code. They mix data, business logic, and results into a single file (something most of us would never accept in an Excel spreadsheet, yet somehow tolerate in an .ipynb). They’re also not plain text, which makes version control, code review, and collaboration unnecessarily painful, often requiring dedicated tooling just to work around the format.</p>
<p>Joel Grus said it best years ago in his classic <em>I Don’t Like Notebooks</em> talk (go watch it on youtube, it’s great). Very little has changed since then.</p>
<p>So why did notebooks become so dominant?</p>
<p>Because Python’s scientific computing tooling was simply that bad for a long time. Spyder wasn’t great. Installing Python packages was (and, to some extent, still is) an absolute clown show. <code>uv</code> has dramatically improved the experience, but it can’t solve the deeper structural issues of PyPI.</p>
<p>From the mid-2000s through the early 2010s, spinning up a Jupyter server with a curated set of pre-installed packages was often the only practical way for institutions to provide working Python environments to their users. Unlike R, which had RStudio, Python never had a truly first-class IDE built specifically for scientific computing. So a whole generation of data scientists grew up on Jupyter and now teach on Jupyter and force their juniors to use Jupyter. Big mistake! Even without AI, there’s no reason to keep using notebooks. Positron is excellent, and VS Code can be configured into a capable data science environment. But AI may end up making the entire IDE debate irrelevant (of course, us Emacs or Vim chads have solved this since decades).</p>
<p>AI agents thrive on plain text, which also happens to be the simplest and most enduring interface in computing, especially in the Unix/Linux world.</p>
<p>Jupyter notebooks, by contrast, are JSON documents rather than plain text (and the json format itself would actually not be an issue for agents, to be fair). But notebooks have many longstanding problems (hidden state, side effects, and non-linear execution) which are exactly the kinds of things that make life difficult for AI agents. AI systems struggle with implicit state and unpredictable execution. Tools and interfaces that deliberately minimize these issues (like plain-text scripts, explicit pipelines, immutable workflows) don’t just make life easier for humans; they make it easier for AI as well.</p>
<p>If AI becomes central to software development (which it will), I think we’ll see a resurgence of simple text-based workflows.</p>
<p>A notebook is essentially a recording of a conversation between a human and a computer:</p>
<pre>Run cell.
Inspect output.
Modify.
Run again.
Oops.
Restart kernel.
Run all.</pre>
<p>It’s procedural and interactive, and it’s completely pointless when the coding is being done by an AI agent. Just think about it: imagine we’re back in 2010, and you hire some data science consultants to analyse some data. Do you care to see which tools they used for the analysis? You might be interested in the source code of the analysis itself, but why would you care if they used notebooks or plain text scripts? This is essentially the same here. People might say “well I care because I want to collaborate with AI”, and that may be true, but I’m willing to bet that we’re going to move more towards what makes AI efficient (plain text) and move away from what humans like (notebooks if you have shit taste). We start to see it already in the tooling that is being developed and offered to developers: we’ve started with AI agents embedded in text editors doing auto-complete to “harnesses” that edit the code for you and show you the diffs.</p>
<p>That brings me back to the idea of interactive data analysis. Increasingly, I think the workflow itself may be flawed.</p>
<p>To be clear, there is real value in exploring data: filtering, slicing, visualizing, trying different models, testing hypotheses, tweaking graphs. The problem is that this exploratory process usually produces a chaotic script that eventually has to be rewritten before it can be put into production. We accept this rewrite as part of the job, but ideally we shouldn’t have to.</p>
<p>AI changes that equation.</p>
<p>Humans can continue exploring data in messy, experimental code while AI agents continuously refactor that exploration into clean, modular, production-ready pipelines. Instead of treating exploration and production as two separate phases, we can have AI bridge the gap in real time.</p>
</section>
<section id="introducing-t-describing-systems-constraints-and-intent" class="level2">
<h2 class="anchored" data-anchor-id="introducing-t-describing-systems-constraints-and-intent">Introducing T: Describing Systems, Constraints, and Intent</h2>
<p>Those two ideas (that plain text is still the best interface we have, and that human-agent collaboration will fundamentally reshape how we build software) are the foundation of the domain-specific language I’m working on, T.</p>
<p>Also, I’m betting that the history of computing will keep on repeating itself, and this history as always about raising the level of abstraction. In the 1980s and 1990s, everyone wanted programming to become <em>more interactive</em>. We got IDEs, GUIs, notebooks, drag-and-drop workflows, visual programming, WYSIWYG editors. The assumption was that making computers more like humans was the future. We went from describing exactly what the CPU should do to describing data transformations with modern functional programming.</p>
<p>With AI, we are increasingly focusing on describing <strong>systems</strong>, <strong>constraints</strong>, and <strong>intent</strong>.</p>
<p>We’re rediscovering that plain text, explicit representations, and declarative specifications are incredibly powerful: not because humans suddenly prefer them (some nerds do, see NixOS), but because <em>both humans and AI can reason about them</em>. Git can diff them. Compilers can analyze them. LLMs can transform them. They compose naturally.</p>
<p>So the future may look surprisingly like the past: not because we’ve failed to innovate, but because we’ve rediscovered that the oldest Unix philosophy was pointing in the right direction all along:</p>
<blockquote class="blockquote">
<p>Everything should have an explicit, textual representation that can be composed into larger systems.</p>
</blockquote>
<p>For example, instead of writing:</p>
<pre>for ...
    ...</pre>
<p>you tell some AI-agent in voice mode:</p>
<blockquote class="blockquote">
<p>Here’s my data. These transformations must happen. These invariants must hold. This pipeline should be reproducible.</p>
</blockquote>
<p>Let’s go back to the intro: Jim thinks in <strong>tasks</strong>.</p>
<blockquote class="blockquote">
<p>“I need to copy these numbers.”</p>
</blockquote>
<p>Bill thinks in <strong>rules</strong>.</p>
<blockquote class="blockquote">
<p>“These numbers are generated according to these rules.”</p>
</blockquote>
<p>When using an AI, you need to go one step further and think about systems and design. Once the system or the design of your project is explicit, generating Python, R, SQL, Bash, DuckDB, Polars, Spark, or whatever becomes almost an implementation detail.</p>
<p>This is the main design principle behind T.</p>
<p>T is an experimental, reproducibility-by-design DSL for polyglot data science. It provides a functional, immutable language for constructing composable micropipelines: first-class, introspectable computation graphs that coordinate R, Python, Julia, Quarto, and Shell execution within a unified system. Pipelines in T are not configuration artifacts but executable program structures with explicit dataflow, typed nodes, and content-addressed outputs. I’ve talked about it already <a href="https://brodrigues.co/posts/2026-04-03-tproject.html" rel="nofollow" target="_blank">here</a>.</p>
<p>The main idea is that you <strong>will not</strong> write any T code. An AI agent should do it. And to achieve this, everything humans can do with T (running code, running tests, looking at error messages, etc) can also be done by AI agents. Agents can run the code and get feedback in json format. Error messages can also be surfaced using json. There is a whole “agentic” way of using T that is first-class.</p>
<p>Built on Nix, T integrates declarative environment management and deterministic builds at the language level. Every node runs in its own hermetic sandbox. Reproducibility isn’t something you configure; it’s something you can’t opt out of. Data moves via Apache Arrow. The actual data analysis code is still written in R, Python or Julia. T “merely” owns the data boundaries and efficiently coordinates the different nodes written in different languages seamlessly. Models can be trained in R or Python and evaluated natively in T via PMML or ONNX. The language is strictly functional: no mutable state, errors as values, tidyverse-inspired verbs for exploration in the REPL, then promotion into production pipelines.</p>
<p>Its source is 100% AI-generated and thoroughly tested. Starting a T project will ship an <code>AGENTS.md</code> and tiered language references so LLMs get the exact context they need. Intent blocks let you embed the “why.” <code>t check</code> is milliseconds and checks the structural correctness of the pipeline; builds are cached and content-addressed.</p>
<p>If T succeeds, I don’t think it should be framed as “another programming language.” It should be framed as <strong>a language for describing data science pipelines</strong>. Check it out <a href="https://github.com/b-rodrigues/tlang" rel="nofollow" target="_blank">here</a> or the <a href="https://tstats-project.org/" rel="nofollow" target="_blank">website</a>.</p>
<p>AI won’t eliminate the need to think computationally; it will make computational thinking more valuable than ever. The syntax is becoming cheaper. The implementation is becoming easier. What remains scarce is the ability to recognize systems where others only see tasks. That’s why I think the future of programming looks so much like its past: explicit representations, declarative descriptions, and composable systems remain the best way to communicate intent.</p>


</section>

 
<div style="border: 1px solid; background: none repeat scroll 0 0 #EDEDED; margin: 1px; font-size: 13px;">
<div style="text-align: center;">To <strong>leave a comment</strong> for the author, please follow the link and comment on their blog: <strong><a href="https://b-rodrigues.github.io/posts/2026-08-02-t_devlog.html"> Econometrics and Free Software</a></strong>.</div>
<hr />
<a href="https://www.r-bloggers.com/" rel="nofollow">R-bloggers.com</a> offers <strong><a href="https://feedburner.google.com/fb/a/mailverify?uri=RBloggers" rel="nofollow">daily e-mail updates</a></strong> about <a title="The R Project for Statistical Computing" href="https://www.r-project.org/" rel="nofollow">R</a> news and tutorials about <a title="R tutorials" href="https://www.r-bloggers.com/how-to-learn-r-2/" rel="nofollow">learning R</a> and many other topics. <a title="Data science jobs" href="https://www.r-users.com/" rel="nofollow">Click here if you're looking to post or find an R/data-science job</a>.

<hr>Want to share your content on R-bloggers?<a href="https://www.r-bloggers.com/add-your-blog/" rel="nofollow"> click here</a> if you have a blog, or <a href="http://r-posts.com/" rel="nofollow"> here</a> if you don't.
</div><strong>Continue reading</strong>: <a href="https://www.r-bloggers.com/2026/08/the-future-of-programming-looks-like-its-past-or-why-i-build-t/">The Future of Programming Looks Like Its Past or Why I build T</a>]]></content:encoded>
					
		
		<enclosure url="" length="0" type="" />

		<post-id xmlns="com-wordpress:feed-additions:1">402948</post-id>	</item>
		<item>
		<title>Little useless-useful R functions – Honest geographical location signposts</title>
		<link>https://www.r-bloggers.com/2026/08/little-useless-useful-r-functions-honest-geographical-location-signposts/</link>
		
		<dc:creator><![CDATA[tomaztsql]]></dc:creator>
		<pubDate>Sat, 01 Aug 2026 16:09:59 +0000</pubDate>
				<category><![CDATA[R bloggers]]></category>
		<guid isPermaLink="false">http://tomaztsql.wordpress.com/?p=11201</guid>

					<description><![CDATA[<div style = "width:60%; display: inline-block; float:left; "> We have all seen colourful signposts with great cities and their distances – how far each is from this current standpoint. And fundamental question is, how correct these distances are? Or even, one should ask, how honest a particular signpost…Read more ›</div>
<div style = "width: 40%; display: inline-block; float:right;"></div>
<div style="clear: both;"></div>
<strong>Continue reading</strong>: <a href="https://www.r-bloggers.com/2026/08/little-useless-useful-r-functions-honest-geographical-location-signposts/">Little useless-useful R functions – Honest geographical location signposts</a>]]></description>
										<content:encoded><![CDATA[<!-- 
<div style="min-height: 30px;">
[social4i size="small" align="align-left"]
</div>
-->

<div style="border: 1px solid; background: none repeat scroll 0 0 #EDEDED; margin: 1px; font-size: 12px;">
[This article was first published on  <strong><a href="https://tomaztsql.wordpress.com/2026/08/01/little-useless-useful-r-functions-honest-geographical-location-signposts/"> R – TomazTsql</a></strong>, and kindly contributed to <a href="https://www.r-bloggers.com/" rel="nofollow">R-bloggers</a>].  (You can report issue about the content on this page <a href="https://www.r-bloggers.com/contact-us/">here</a>)
<hr>Want to share your content on R-bloggers?<a href="https://www.r-bloggers.com/add-your-blog/" rel="nofollow"> click here</a> if you have a blog, or <a href="http://r-posts.com/" rel="nofollow"> here</a> if you don't.
</div>

<p class="wp-block-paragraph">We have all seen colourful signposts with great cities and their distances –  how far each is from this current standpoint.</p>



<figure class="wp-block-image size-large"><a href="https://i1.wp.com/tomaztsql.wordpress.com/wp-content/uploads/2026/08/image.png?ssl=1" rel="nofollow" target="_blank"><img loading="lazy" data-attachment-id="11205" data-permalink="https://tomaztsql.wordpress.com/2026/08/01/little-useless-useful-r-functions-honest-geographical-location-signposts/image-348/" data-orig-file="https://tomaztsql.wordpress.com/wp-content/uploads/2026/08/image.png" data-orig-size="877,801" data-comments-opened="1" data-image-meta="{"aperture":"0","credit":"","camera":"","caption":"","created_timestamp":"0","copyright":"","focal_length":"0","iso":"0","shutter_speed":"0","title":"","orientation":"0","alt":""}" data-image-title="image" data-image-description="" data-image-caption="" data-large-file="https://tomaztsql.wordpress.com/wp-content/uploads/2026/08/image.png?w=605" src="https://i1.wp.com/tomaztsql.wordpress.com/wp-content/uploads/2026/08/image.png?w=450&#038;ssl=1" alt="" class="wp-image-11205" srcset_temp="https://tomaztsql.wordpress.com/wp-content/uploads/2026/08/image.png 877w, https://tomaztsql.wordpress.com/wp-content/uploads/2026/08/image.png?w=150 150w, https://tomaztsql.wordpress.com/wp-content/uploads/2026/08/image.png?w=300 300w, https://tomaztsql.wordpress.com/wp-content/uploads/2026/08/image.png?w=768 768w" sizes="(max-width: 877px) 100vw, 877px" data-recalc-dims="1" /></a></figure>



<p class="wp-block-paragraph">And fundamental question is, how correct these distances are? Or even, one should ask, how honest a particular signpost is, regarding the current standpoint.</p>



<p class="wp-block-paragraph">So let’s put this utterly most fundamental question to the test <img src="https://i1.wp.com/s0.wp.com/wp-content/mu-plugins/wpcom-smileys/twemoji/2/72x72/1f642.png?w=578&#038;ssl=1" alt="&#x1f642;" class="wp-smiley" style="height: 1em; max-height: 1em;" data-recalc-dims="1" /> And since it is vacation time, you can grab the R code and check it yourself <img src="https://i1.wp.com/s0.wp.com/wp-content/mu-plugins/wpcom-smileys/twemoji/2/72x72/1f642.png?w=578&#038;ssl=1" alt="&#x1f642;" class="wp-smiley" style="height: 1em; max-height: 1em;" data-recalc-dims="1" /></p>



<p class="wp-block-paragraph">Image stumbling upon the post and wanted to check if this post is really relevant for this location. It can be a photo from other side of the world, hanging in the lobby of your holiday hotel <img src="https://i1.wp.com/s0.wp.com/wp-content/mu-plugins/wpcom-smileys/twemoji/2/72x72/1f642.png?w=578&#038;ssl=1" alt="&#x1f642;" class="wp-smiley" style="height: 1em; max-height: 1em;" data-recalc-dims="1" /> And this sure ain’t honest signpost <img src="https://i1.wp.com/s0.wp.com/wp-content/mu-plugins/wpcom-smileys/twemoji/2/72x72/1f642.png?w=578&#038;ssl=1" alt="&#x1f642;" class="wp-smiley" style="height: 1em; max-height: 1em;" data-recalc-dims="1" /></p>



<p class="wp-block-paragraph">The R code iterates through each city, finds matching points (where all circles meet) and searches for the nearest location. It uses <a href="https://www.openstreetmap.org/" rel="nofollow" target="_blank">OpenStreetMap</a> (short: OSM) to extract all the geolocations and looks for possible intersections of all points</p>



<pre>
geocode_city &lt;- function(city_name) {
 
  url &lt;- modify_url(
    &quot;https://nominatim.openstreetmap.org/search&quot;,
    query = list(
      q       = city_name,
      format  = &quot;json&quot;,
      limit   = 1
    )
  )
  
  resp &lt;- tryCatch(
    GET(url, user_agent(&quot;PointingSignFinder/1.0 (R script)&quot;)),
     error = function(e) {
       cat(&quot; Error on endpoint&quot;)
       return(NULL)
     }
  )
  
  if (is.null(resp) || http_error(resp)) {
    cat(&quot; Error on http\n&quot;)
    return(NULL)
  }
  
  result &lt;- fromJSON(content(resp, as = &quot;text&quot;, encoding = &quot;UTF-8&quot;))
  
  if (length(result) == 0) {
    cat(&quot;Error on result&quot;)
    return(NULL)
  }
  
  lat &lt;- as.numeric(result$lat[1])
  lon &lt;- as.numeric(result$lon[1])
  cat(sprintf(&quot; found: %.4f°, %.4f°\n&quot;, lat, lon))
  
  Sys.sleep(1.1)
  
  list(lat = lat, lon = lon, display_name = result$display_name[1])
}


sign_location_finder &lt;- function(cities,
                                 distances,
                                 tolerance = 50,
                                 coarse_res = 0.2,
                                 fine_res   = 0.02,
                                 nearby_radius = 200,
                                 nearby_min_pop = 100000) {
  
  stopifnot(length(cities) == length(distances))
  stopifnot(length(cities) &gt;= 2)
  
  cat(&quot;Step 1: Geocoding cities\n&quot;)
  coords &lt;- lapply(cities, geocode_city)
  
  failed &lt;- which(sapply(coords, is.null))
  if (length(failed) &gt; 0) {
    stop(sprintf(&quot;Location not founc: %s&quot;, paste(cities[failed], collapse = &quot;, &quot;)))
  }
  
  sign_data &lt;- data.frame(
    city    = cities,
    lat     = sapply(coords, `[[`, &quot;lat&quot;),
    lon     = sapply(coords, `[[`, &quot;lon&quot;),
    dist_km = distances
  )


print(sign_data[, c(&quot;city&quot;, &quot;lat&quot;, &quot;lon&quot;, &quot;dist_km&quot;)])
  
max_dist_deg &lt;- max(sign_data$dist_km) / 111
lat_min &lt;- min(sign_data$lat) - max_dist_deg - 5
lat_max &lt;- max(sign_data$lat) + max_dist_deg + 5
lon_min &lt;- min(sign_data$lon) - max_dist_deg * 2 - 5
lon_max &lt;- max(sign_data$lon) + max_dist_deg * 2 + 5
  
 
lat_min &lt;- max(lat_min, -85)
lat_max &lt;- min(lat_max,  85)
lon_min &lt;- max(lon_min, -180)
lon_max &lt;- min(lon_max,  180)
  
cat(sprintf(&quot;\nStep 2: Search bounding box: lat [%.1f, %.1f], lon [%.1f, %.1f]\n&quot;,
              lat_min, lat_max, lon_min, lon_max))
  
  
  score_point &lt;- function(plat, plon) {
    diffs &lt;- sapply(seq_len(nrow(sign_data)), function(i) {
      d &lt;- distHaversine(
        c(plon, plat),
        c(sign_data$lon[i], sign_data$lat[i])
      ) / 1000
      abs(d - sign_data$dist_km[i])
    })
    max(diffs)
  }
  
  
  cat(sprintf(&quot;\nStep 3: Search the grid (%.2f° resolution)...\n&quot;, coarse_res))
  grid &lt;- expand.grid(
    lat = seq(lat_min, lat_max, by = coarse_res),
    lon = seq(lon_min, lon_max, by = coarse_res)
  )
  cat(sprintf(&quot;Checking %d grid points...\n&quot;, nrow(grid)))
  grid$score &lt;- mapply(score_point, grid$lat, grid$lon)
  
  candidates &lt;- grid[grid$score &lt;= tolerance, ]
  cat(sprintf(&quot; Found %d candidate cells within ±%d km tolerance.\n&quot;,
              nrow(candidates), tolerance))
  
  coarse_best &lt;- grid[which.min(grid$score), ]
  
  fine_grid &lt;- expand.grid(
    lat = seq(coarse_best$lat - 1, coarse_best$lat + 1, by = fine_res),
    lon = seq(coarse_best$lon - 1, coarse_best$lon + 1, by = fine_res)
  )
  fine_grid$score &lt;- mapply(score_point, fine_grid$lat, fine_grid$lon)
  best &lt;- fine_grid[which.min(fine_grid$score), ]
  
  cat(sprintf(&quot;\n&gt;&gt;&gt; Estimated  locations:\n&quot;))
  cat(sprintf(&quot;    Latitude  : %.4f°\n&quot;, best$lat))
  cat(sprintf(&quot;    Longitude : %.4f°\n&quot;, best$lon))
  cat(sprintf(&quot;    Max error : ±%.1f km\n&quot;, best$score))
  cat(sprintf(&quot;    Google Maps: https://www.google.com/maps?q=%.4f,%.4f\n&quot;, best$lat, best$lon))
  
  cat(sprintf(&quot;\nStep 5: Nearby cities (within %d km, pop &gt; %s)...\n&quot;,
              nearby_radius, format(nearby_min_pop, big.mark = &quot;,&quot;)))
  
  world_cities &lt;- world.cities
  nearby &lt;- world_cities |&gt;
    filter(pop &gt; nearby_min_pop) |&gt;
    mutate(
      dist_to_sign = distHaversine(
        cbind(long, lat),
        c(best$lon, best$lat)
      ) / 1000
    ) |&gt;
    filter(dist_to_sign &lt;= nearby_radius) |&gt;
    arrange(dist_to_sign) |&gt;
    select(name, country.etc, lat, long, pop, dist_to_sign) |&gt;
    head(10)
  
  if (nrow(nearby) &gt; 0) {
    cat(&quot;\n  Cities found:\n&quot;)
    print(nearby, digits = 4)
    cat(sprintf(&quot;\n  Nearest: %s, %s (%.1f km away)\n&quot;,
                nearby$name[1], nearby$country.etc[1], nearby$dist_to_sign[1]))
  } else {
    cat(&quot;No major locations found in vicinity!&quot;)
  }
  

}</pre>



<p class="wp-block-paragraph">So now, that we understand the useless problem, we can put this to the test <img src="https://i1.wp.com/s0.wp.com/wp-content/mu-plugins/wpcom-smileys/twemoji/2/72x72/1f642.png?w=578&#038;ssl=1" alt="&#x1f642;" class="wp-smiley" style="height: 1em; max-height: 1em;" data-recalc-dims="1" /></p>



<p class="wp-block-paragraph"></p>


<div class="wp-block-code">
	<div class="cm-editor">
		<div class="cm-scroller">
			
<pre>
# sample 2 - real with correct distances calculater from#  https://www.distancefromto.net/  &quot;air distance&quot;# result must be Ljubljana, Sloveniaresult &lt;- sign_location_finder(  cities    = c(&quot;Koper&quot;, &quot;Celje&quot;, &quot;Maribor&quot;, &quot;Kranj&quot;),  distances = c(83, 61, 104, 24),  tolerance = 20) </pre>
		</div>
	</div>
</div>


<p class="wp-block-paragraph">In this case I have entered the correct air distances and there should be a location present – which is capital of Slovenia – Ljubljana.</p>


<div class="wp-block-image">
<figure class="aligncenter size-large is-resized"><a href="https://i2.wp.com/tomaztsql.wordpress.com/wp-content/uploads/2026/08/image-1.png?ssl=1" rel="nofollow" target="_blank"><img loading="lazy" data-attachment-id="11209" data-permalink="https://tomaztsql.wordpress.com/2026/08/01/little-useless-useful-r-functions-honest-geographical-location-signposts/image-349/" data-orig-file="https://tomaztsql.wordpress.com/wp-content/uploads/2026/08/image-1.png" data-orig-size="548,678" data-comments-opened="1" data-image-meta="{"aperture":"0","credit":"","camera":"","caption":"","created_timestamp":"0","copyright":"","focal_length":"0","iso":"0","shutter_speed":"0","title":"","orientation":"0","alt":""}" data-image-title="image" data-image-description="" data-image-caption="" data-large-file="https://i2.wp.com/tomaztsql.wordpress.com/wp-content/uploads/2026/08/image-1.png?w=450&#038;ssl=1" src="https://i2.wp.com/tomaztsql.wordpress.com/wp-content/uploads/2026/08/image-1.png?w=450&#038;ssl=1" alt="" class="wp-image-11209" style="aspect-ratio:0.8082737958054851;width:383px;height:auto" srcset_temp="https://tomaztsql.wordpress.com/wp-content/uploads/2026/08/image-1.png 548w, https://tomaztsql.wordpress.com/wp-content/uploads/2026/08/image-1.png?w=121 121w, https://tomaztsql.wordpress.com/wp-content/uploads/2026/08/image-1.png?w=242 242w" sizes="(max-width: 548px) 100vw, 548px" data-recalc-dims="1" /></a></figure>
</div>


<p class="wp-block-paragraph">I have inserted the real values of air distances between Ljubljana all all four cities: Koper, Celje, Maribor, Kranj using <a href="https://www.distancefromto.net/" rel="nofollow" target="_blank">air distance calculator.</a></p>



<p class="wp-block-paragraph">And this where the circles should meet <img src="https://i1.wp.com/s0.wp.com/wp-content/mu-plugins/wpcom-smileys/twemoji/2/72x72/1f642.png?w=578&#038;ssl=1" alt="&#x1f642;" class="wp-smiley" style="height: 1em; max-height: 1em;" data-recalc-dims="1" /></p>


<div class="wp-block-image">
<figure class="aligncenter size-large is-resized"><a href="https://i2.wp.com/tomaztsql.wordpress.com/wp-content/uploads/2026/08/where_we_meet.png?ssl=1" rel="nofollow" target="_blank"><img loading="lazy" data-attachment-id="11211" data-permalink="https://tomaztsql.wordpress.com/2026/08/01/little-useless-useful-r-functions-honest-geographical-location-signposts/where_we_meet/" data-orig-file="https://tomaztsql.wordpress.com/wp-content/uploads/2026/08/where_we_meet.png" data-orig-size="1800,1800" data-comments-opened="1" data-image-meta="{"aperture":"0","credit":"","camera":"","caption":"","created_timestamp":"0","copyright":"","focal_length":"0","iso":"0","shutter_speed":"0","title":"","orientation":"0","alt":""}" data-image-title="where_we_meet" data-image-description="" data-image-caption="" data-large-file="https://tomaztsql.wordpress.com/wp-content/uploads/2026/08/where_we_meet.png?w=605" src="https://i2.wp.com/tomaztsql.wordpress.com/wp-content/uploads/2026/08/where_we_meet.png?w=450&#038;ssl=1" alt="" class="wp-image-11211" style="width:623px;height:auto" srcset_temp="https://i2.wp.com/tomaztsql.wordpress.com/wp-content/uploads/2026/08/where_we_meet.png?w=450&#038;ssl=1 1024w, https://tomaztsql.wordpress.com/wp-content/uploads/2026/08/where_we_meet.png?w=150 150w, https://tomaztsql.wordpress.com/wp-content/uploads/2026/08/where_we_meet.png?w=300 300w, https://tomaztsql.wordpress.com/wp-content/uploads/2026/08/where_we_meet.png?w=768 768w, https://tomaztsql.wordpress.com/wp-content/uploads/2026/08/where_we_meet.png?w=1440 1440w, https://tomaztsql.wordpress.com/wp-content/uploads/2026/08/where_we_meet.png 1800w" sizes="(max-width: 1024px) 100vw, 1024px" data-recalc-dims="1" /></a></figure>
</div>


<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph">So if you are enjoying your vacation and you stumble upon a sign, check it and let me know, if it corresponds to your location of not <img src="https://i1.wp.com/s0.wp.com/wp-content/mu-plugins/wpcom-smileys/twemoji/2/72x72/1f642.png?w=578&#038;ssl=1" alt="&#x1f642;" class="wp-smiley" style="height: 1em; max-height: 1em;" data-recalc-dims="1" /></p>



<p class="wp-block-paragraph">As always, the complete code is available on GitHub in  <a href="https://github.com/tomaztk/Useless_R_functions" rel="nofollow" target="_blank">Useless_R_function repository</a>  and the file  Honest_geographical_location_signposts.R is  <a href="https://github.com/tomaztk/Useless_R_functions/blob/main/functions/Honest_geographical_location_signposts.R" rel="nofollow" target="_blank">here</a>.</p>



<p class="wp-block-paragraph">Check the repository for future updates!</p>



<p class="wp-block-paragraph">Stay healthy, hydrated and happy R-coding!</p>

<div style="border: 1px solid; background: none repeat scroll 0 0 #EDEDED; margin: 1px; font-size: 13px;">
<div style="text-align: center;">To <strong>leave a comment</strong> for the author, please follow the link and comment on their blog: <strong><a href="https://tomaztsql.wordpress.com/2026/08/01/little-useless-useful-r-functions-honest-geographical-location-signposts/"> R – TomazTsql</a></strong>.</div>
<hr />
<a href="https://www.r-bloggers.com/" rel="nofollow">R-bloggers.com</a> offers <strong><a href="https://feedburner.google.com/fb/a/mailverify?uri=RBloggers" rel="nofollow">daily e-mail updates</a></strong> about <a title="The R Project for Statistical Computing" href="https://www.r-project.org/" rel="nofollow">R</a> news and tutorials about <a title="R tutorials" href="https://www.r-bloggers.com/how-to-learn-r-2/" rel="nofollow">learning R</a> and many other topics. <a title="Data science jobs" href="https://www.r-users.com/" rel="nofollow">Click here if you're looking to post or find an R/data-science job</a>.

<hr>Want to share your content on R-bloggers?<a href="https://www.r-bloggers.com/add-your-blog/" rel="nofollow"> click here</a> if you have a blog, or <a href="http://r-posts.com/" rel="nofollow"> here</a> if you don't.
</div><strong>Continue reading</strong>: <a href="https://www.r-bloggers.com/2026/08/little-useless-useful-r-functions-honest-geographical-location-signposts/">Little useless-useful R functions – Honest geographical location signposts</a>]]></content:encoded>
					
		
		<enclosure url="https://2.gravatar.com/avatar/84af3d4db7552aa6f0fc3db37b65871290b5174af7d5b84c3f185ca92ccfb237?s=96&#038;d=identicon&#038;r=G" length="0" type="" />
<enclosure url="https://tomaztsql.wordpress.com/wp-content/uploads/2026/08/image.png?w=877" length="0" type="" />
<enclosure url="https://tomaztsql.wordpress.com/wp-content/uploads/2026/08/image-1.png?w=548" length="0" type="" />
<enclosure url="https://tomaztsql.wordpress.com/wp-content/uploads/2026/08/where_we_meet.png?w=1024" length="0" type="" />

		<post-id xmlns="com-wordpress:feed-additions:1">402905</post-id>	</item>
		<item>
		<title>&#8216;garchf&#8217;: GARCH probabilistic forecasting with package &#8216;forecast&#8217;-style interface (and &#8216;rugarch&#8217; under the hood)</title>
		<link>https://www.r-bloggers.com/2026/07/garchf-garch-probabilistic-forecasting-with-package-forecast-style-interface-and-rugarch-under-the-hood/</link>
		
		<dc:creator><![CDATA[T. Moudiki]]></dc:creator>
		<pubDate>Sat, 01 Aug 2026 00:00:00 +0000</pubDate>
				<category><![CDATA[R bloggers]]></category>
		<guid isPermaLink="false">https://thierrymoudiki.github.io//blog/2026/08/01/r/xgarchf</guid>

					<description><![CDATA[<div style = "width:60%; display: inline-block; float:left; "> The package garchf wraps<br />
the extensive GARCH modeling machinery in<br />
rugarch<br />
behind a<br />
forecast-style<br />
interface, so that GARCH-based forecasts can be produced, plotted, and<br />
evaluated with the same conventions used throughout the forecast<br />
ecosystem (in the...</div>
<div style = "width: 40%; display: inline-block; float:right;"></div>
<div style="clear: both;"></div>
<strong>Continue reading</strong>: <a href="https://www.r-bloggers.com/2026/07/garchf-garch-probabilistic-forecasting-with-package-forecast-style-interface-and-rugarch-under-the-hood/">‘garchf’: GARCH probabilistic forecasting with package ‘forecast’-style interface (and ‘rugarch’ under the hood)</a>]]></description>
										<content:encoded><![CDATA[<!-- 
<div style="min-height: 30px;">
[social4i size="small" align="align-left"]
</div>
-->

<div style="border: 1px solid; background: none repeat scroll 0 0 #EDEDED; margin: 1px; font-size: 12px;">
[This article was first published on  <strong><a href="https://thierrymoudiki.github.io//blog/2026/08/01/r/xgarchf"> T. Moudiki's Webpage - R</a></strong>, and kindly contributed to <a href="https://www.r-bloggers.com/" rel="nofollow">R-bloggers</a>].  (You can report issue about the content on this page <a href="https://www.r-bloggers.com/contact-us/">here</a>)
<hr>Want to share your content on R-bloggers?<a href="https://www.r-bloggers.com/add-your-blog/" rel="nofollow"> click here</a> if you have a blog, or <a href="http://r-posts.com/" rel="nofollow"> here</a> if you don't.
</div>
<p>The package <a href="https://techtonique.r-universe.dev/garchf" rel="nofollow" target="_blank"><code>garchf</code></a> wraps
the extensive GARCH modeling machinery in
<a href="https://cran.r-project.org/web/packages/rugarch/index.html" rel="nofollow" target="_blank"><code>rugarch</code></a>
behind a
<a href="https://cran.r-project.org/web/packages/forecast/index.html" rel="nofollow" target="_blank"><code>forecast</code></a>-style
interface, so that GARCH-based forecasts can be produced, plotted, and
evaluated with the same conventions used throughout the <code>forecast</code>
ecosystem (in the spirit of functions like <code>forecast::thetaf()</code>). The
workhorse function, <code>xgarchf()</code>, fits a GARCH model to a univariate time
series – with a choice of variance model (<code>sGARCH</code>, <code>eGARCH</code>,
<code>gjrGARCH</code>, <code>apARCH</code>, <code>iGARCH</code>, …), ARMA order for the conditional mean,
GARCH order, and conditional distribution – and returns a standard
<code>forecast</code> object containing point forecasts, prediction intervals, and
simulated paths. Because the output integrates with <code>forecast</code>’s S3
methods, <code>plot()</code> and other generics work out of the box, and the
simulated paths (<code>sims</code>) make it straightforward to compute richer
probabilistic forecasting metrics (CRPS, pinball loss, Winkler scores,
etc.) via cross-validation. Below, we illustrate <code>xgarchf()</code> on Google’s
daily closing stock price returns, and then run a small cross-validation
exercise comparing a few GARCH variants using the
<a href="https://github.com/Techtonique/crossvalidation" rel="nofollow" target="_blank"><code>crossvalidation</code></a>
package.</p>

<pre>library(garchf)

Registered S3 method overwritten by 'quantmod':
  method            from
  as.zoo.data.frame zoo 
</pre>

<h1 id="1---graphs">1 &#8211; Graphs</h1>

<pre>y &lt;- diff(log(fpp2::goog200))

fit1 &lt;- xgarchf(y, h = 20, model = &quot;eGARCH&quot;)
fit2 &lt;- xgarchf(y, h = 20, model = &quot;sGARCH&quot;)
fit3 &lt;- xgarchf(y, h = 20, model = &quot;gjrGARCH&quot;)
fit4 &lt;- xgarchf(y, h = 20, model = &quot;iGARCH&quot;)

print(summary(fitted(fit1)))

    Min.  1st Qu.   Median     Mean  3rd Qu.     Max. 
0.001504 0.001504 0.001504 0.001504 0.001504 0.001504     
    Min.  1st Qu.   Median     Mean  3rd Qu.     Max. 
0.002783 0.002783 0.002783 0.002783 0.002783 0.002783     
    Min.  1st Qu.   Median     Mean  3rd Qu.     Max. 
0.001233 0.001233 0.001233 0.001233 0.001233 0.001233     
    Min.  1st Qu.   Median     Mean  3rd Qu.     Max. 
0.001485 0.001485 0.001485 0.001485 0.001485 0.001485 
</pre>

<p><img src="https://i0.wp.com/thierrymoudiki.github.io/images/2026-08-01/2026-08-01-xgarchf_3_1.png?w=578&#038;ssl=1" alt="image-title-here" class="img-responsive" data-recalc-dims="1" /></p>

<pre>    Ljung-Box test

data:  Residuals
Q* = 10.341, df = 10, p-value = 0.4111

Model df: 0.   Total lags used: 10
</pre>

<p><img src="https://i1.wp.com/thierrymoudiki.github.io/images/2026-08-01/2026-08-01-xgarchf_3_3.png?w=578&#038;ssl=1" alt="image-title-here" class="img-responsive" data-recalc-dims="1" /></p>

<pre>    Ljung-Box test

data:  Residuals
Q* = 10.341, df = 10, p-value = 0.4111

Model df: 0.   Total lags used: 10
</pre>

<p><img src="https://i2.wp.com/thierrymoudiki.github.io/images/2026-08-01/2026-08-01-xgarchf_3_5.png?w=578&#038;ssl=1" alt="image-title-here" class="img-responsive" data-recalc-dims="1" /></p>

<pre>    Ljung-Box test

data:  Residuals
Q* = 10.341, df = 10, p-value = 0.4111

Model df: 0.   Total lags used: 10
</pre>

<p><img src="https://i1.wp.com/thierrymoudiki.github.io/images/2026-08-01/2026-08-01-xgarchf_3_7.png?w=578&#038;ssl=1" alt="image-title-here" class="img-responsive" data-recalc-dims="1" /></p>

<pre>    Ljung-Box test

data:  Residuals
Q* = 10.341, df = 10, p-value = 0.4111

Model df: 0.   Total lags used: 10
</pre>

<p><img src="https://i2.wp.com/thierrymoudiki.github.io/images/2026-08-01/2026-08-01-xgarchf_3_9.png?w=578&#038;ssl=1" alt="image-title-here" class="img-responsive" data-recalc-dims="1" /></p>

<h1 id="2---cross-validation-with-the-package-crossvalidation">2 - Cross-validation with the package <a href="https://github.com/Techtonique/crossvalidation" rel="nofollow" target="_blank"><code>crossvalidation</code></a></h1>

<p>For <code>crossvalidation</code>, see
<a href="https://github.com/Techtonique/crossvalidation" rel="nofollow" target="_blank">https://github.com/Techtonique/crossvalidation</a>.</p>

<pre>spl_m5 &lt;- function(predicted,
                   observed,
                   probs = c(0.005, 0.025, 0.165, 0.25,
                             0.5,
                             0.75, 0.835, 0.975, 0.995))
{
  if (is.null(predicted$sims)) {
    stop(&quot;predicted$sims is required&quot;)
  }

  # training series from forecast object
  train &lt;- as.numeric(predicted$x)

  # M5 scaling denominator
  scale_denom &lt;- mean(abs(diff(train)), na.rm = TRUE)

  if (scale_denom &lt;= 0 || !is.finite(scale_denom)) {
    scale_denom &lt;- 1
  }

  sims &lt;- predicted$sims

  # quantile forecasts: rows = horizons, cols = probs
  qhat &lt;- sapply(
    probs,
    function(p) apply(sims, 1, stats::quantile, probs = p, na.rm = TRUE)
  )

  observed &lt;- as.numeric(observed)

  # pinball loss
  pinball_vec &lt;- numeric(length(probs))

  for (j in seq_along(probs)) {

    u &lt;- probs[j]
    q &lt;- qhat[, j]

    pinball_vec[j] &lt;- mean(
      ifelse(
        observed &gt;= q,
        u * (observed - q),
        (1 - u) * (q - observed)
      ),
      na.rm = TRUE
    )
  }

  # scaled pinball loss for each quantile
  spl_vec &lt;- pinball_vec / scale_denom

  # average scaled pinball loss
  mean_spl &lt;- mean(spl_vec)

  out &lt;- c(
    mean_SPL = mean_spl
  )

  names(spl_vec) &lt;- paste0(&quot;SPL_&quot;, probs)

  c(out, spl_vec)
}

eval_metric95 &lt;- function(predicted, observed)
{
  error &lt;- observed - predicted$mean

  rmse &lt;- sqrt(mean(error^2))
  mae &lt;- mean(abs(error))

  # Only one interval returned
  lower &lt;- predicted$lower
  upper &lt;- predicted$upper

  coverage &lt;- mean(
    observed &gt;= lower & observed &lt;= upper
  )

  alpha &lt;- 0.05

  winkler &lt;- ifelse(
    observed &lt; lower,
    (upper - lower) + (2 / alpha) * (lower - observed),
    ifelse(
      observed &gt; upper,
      (upper - lower) + (2 / alpha) * (observed - upper),
      (upper - lower)
    )
  )

  spl &lt;- spl_m5(predicted, observed)

  c(
    RMSE = rmse,
    MAE = mae,
    Coverage95 = coverage,
    Winkler95 = mean(winkler),
    CRPS = mean(scoringRules::crps_sample(observed, predicted$sims)),
    mean_SPL = as.numeric(spl[&quot;mean_SPL&quot;])
  )
}

eval_metric80 &lt;- function(predicted, observed)
{
  error &lt;- observed - predicted$mean

  me &lt;- mean(error)
  rmse &lt;- sqrt(mean(error^2))
  mae &lt;- mean(abs(error))

  # Only one interval returned
  lower &lt;- predicted$lower
  upper &lt;- predicted$upper

  coverage &lt;- mean(
    observed &gt;= lower & observed &lt;= upper
  )

  alpha &lt;- 0.2

  winkler &lt;- ifelse(
    observed &lt; lower,
    (upper - lower) + (2 / alpha) * (lower - observed),
    ifelse(
      observed &gt; upper,
      (upper - lower) + (2 / alpha) * (observed - upper),
      (upper - lower)
    )
  )

  spl &lt;- spl_m5(predicted, observed)

  c(
    ME = me,
    RMSE = rmse,
    MAE = mae,
    Coverage80 = coverage,
    Winkler80 = mean(winkler),
    CRPS = mean(scoringRules::crps_sample(observed, predicted$sims)),
    mean_SPL = as.numeric(spl[&quot;mean_SPL&quot;])
  )
}

res &lt;- crossvalidation::crossval_ts(
  y = y,
  initial_window = 150,
  horizon = 10,
  fixed_window = FALSE,
  fcast_func = garchf::xgarchf,
  eval_metric = eval_metric95,
  fit_params = list(arma_order=c(0, 0), 
                    garch_order = c(1, 1),
                    model = &quot;eGARCH&quot;,
                    level=95),
  show_progress = FALSE
)
print(summary(res))

res &lt;- crossvalidation::crossval_ts(
  y = y,
  initial_window = 150,
  horizon = 10,
  fixed_window = FALSE,
  fcast_func = garchf::xgarchf,
  eval_metric = eval_metric95,
  fit_params = list(arma_order=c(0, 0), 
                    garch_order = c(1, 1),
                    model = &quot;sGARCH&quot;,
                    level=95),
  show_progress = FALSE
)
print(summary(res))

res &lt;- crossvalidation::crossval_ts(
  y = y,
  initial_window = 150,
  horizon = 10,
  fixed_window = FALSE,
  fcast_func = garchf::xgarchf,
  eval_metric = eval_metric95,
  fit_params = list(arma_order=c(0, 0), 
                    garch_order = c(1, 1),
                    model = &quot;iGARCH&quot;,
                    level=95),
  show_progress = FALSE
)
print(summary(res))

      RMSE               MAE             Coverage95       Winkler95      
 Min.   :0.006459   Min.   :0.004896   Min.   :0.7000   Min.   :0.03441  
 1st Qu.:0.008001   1st Qu.:0.006266   1st Qu.:0.9000   1st Qu.:0.06153  
 Median :0.009135   Median :0.007061   Median :1.0000   Median :0.06466  
 Mean   :0.017189   Mean   :0.010613   Mean   :0.9475   Mean   :0.20090  
 3rd Qu.:0.022415   3rd Qu.:0.015066   3rd Qu.:1.0000   3rd Qu.:0.47706  
 Max.   :0.042741   Max.   :0.023054   Max.   :1.0000   Max.   :0.96625  
      CRPS             mean_SPL     
 Min.   :0.004154   Min.   :0.1170  
 1st Qu.:0.004922   1st Qu.:0.1362  
 Median :0.005311   Median :0.1481  
 Mean   :0.010039   Mean   :0.3380  
 3rd Qu.:0.017800   3rd Qu.:0.6763  
 Max.   :0.051416   Max.   :1.6607        

      RMSE               MAE             Coverage95       Winkler95      
 Min.   :0.006554   Min.   :0.005380   Min.   :0.7000   Min.   :0.03856  
 1st Qu.:0.008424   1st Qu.:0.006561   1st Qu.:0.9750   1st Qu.:0.06261  
 Median :0.009314   Median :0.007401   Median :1.0000   Median :0.07277  
 Mean   :0.017155   Mean   :0.010741   Mean   :0.9525   Mean   :0.17716  
 3rd Qu.:0.020081   3rd Qu.:0.013012   3rd Qu.:1.0000   3rd Qu.:0.34988  
 Max.   :0.042568   Max.   :0.022999   Max.   :1.0000   Max.   :0.49756  
      CRPS             mean_SPL     
 Min.   :0.004634   Min.   :0.1349  
 1st Qu.:0.005383   1st Qu.:0.1516  
 Median :0.005695   Median :0.1606  
 Mean   :0.008842   Mean   :0.2986  
 3rd Qu.:0.012903   3rd Qu.:0.4725  
 Max.   :0.019442   Max.   :0.7436        

    RMSE               MAE             Coverage95       Winkler95      
 Min.   :0.006556   Min.   :0.005514   Min.   :0.7000   Min.   :0.03580  
 1st Qu.:0.008306   1st Qu.:0.006239   1st Qu.:0.9750   1st Qu.:0.06307  
 Median :0.009119   Median :0.007007   Median :1.0000   Median :0.06478  
 Mean   :0.017029   Mean   :0.010484   Mean   :0.9525   Mean   :0.16725  
 3rd Qu.:0.018881   3rd Qu.:0.011711   3rd Qu.:1.0000   3rd Qu.:0.16760  
 Max.   :0.042713   Max.   :0.023064   Max.   :1.0000   Max.   :0.51546  
      CRPS             mean_SPL     
 Min.   :0.004851   Min.   :0.1363  
 1st Qu.:0.005317   1st Qu.:0.1510  
 Median :0.005700   Median :0.1591  
 Mean   :0.008720   Mean   :0.2928  
 3rd Qu.:0.009316   3rd Qu.:0.3126  
 Max.   :0.019649   Max.   :0.7586  
</pre>

<div style="border: 1px solid; background: none repeat scroll 0 0 #EDEDED; margin: 1px; font-size: 13px;">
<div style="text-align: center;">To <strong>leave a comment</strong> for the author, please follow the link and comment on their blog: <strong><a href="https://thierrymoudiki.github.io//blog/2026/08/01/r/xgarchf"> T. Moudiki's Webpage - R</a></strong>.</div>
<hr />
<a href="https://www.r-bloggers.com/" rel="nofollow">R-bloggers.com</a> offers <strong><a href="https://feedburner.google.com/fb/a/mailverify?uri=RBloggers" rel="nofollow">daily e-mail updates</a></strong> about <a title="The R Project for Statistical Computing" href="https://www.r-project.org/" rel="nofollow">R</a> news and tutorials about <a title="R tutorials" href="https://www.r-bloggers.com/how-to-learn-r-2/" rel="nofollow">learning R</a> and many other topics. <a title="Data science jobs" href="https://www.r-users.com/" rel="nofollow">Click here if you're looking to post or find an R/data-science job</a>.

<hr>Want to share your content on R-bloggers?<a href="https://www.r-bloggers.com/add-your-blog/" rel="nofollow"> click here</a> if you have a blog, or <a href="http://r-posts.com/" rel="nofollow"> here</a> if you don't.
</div><strong>Continue reading</strong>: <a href="https://www.r-bloggers.com/2026/07/garchf-garch-probabilistic-forecasting-with-package-forecast-style-interface-and-rugarch-under-the-hood/">‘garchf’: GARCH probabilistic forecasting with package ‘forecast’-style interface (and ‘rugarch’ under the hood)</a>]]></content:encoded>
					
		
		<enclosure url="" length="0" type="" />

		<post-id xmlns="com-wordpress:feed-additions:1">402913</post-id>	</item>
		<item>
		<title>Evaluating LLMs/AI for Media Planning in R</title>
		<link>https://www.r-bloggers.com/2026/07/evaluating-llms-ai-for-media-planning-in-r/</link>
		
		<dc:creator><![CDATA[Florian Teschner]]></dc:creator>
		<pubDate>Sat, 01 Aug 2026 00:00:00 +0000</pubDate>
				<category><![CDATA[R bloggers]]></category>
		<guid isPermaLink="false">http://flovv.github.io/llm-media-evals-in-r/</guid>

					<description><![CDATA[<p>LLMs can produce a convincing media recommendation in a few seconds. The more useful question is whether the recommendation is correct: are the reach calculations right, are the assumptions visible, and does the plan fit the brief?</p>
<p>I work at Havas Med...</p>
<strong>Continue reading</strong>: <a href="https://www.r-bloggers.com/2026/07/evaluating-llms-ai-for-media-planning-in-r/">Evaluating LLMs/AI for Media Planning in R</a>]]></description>
										<content:encoded><![CDATA[<!-- 
<div style="min-height: 30px;">
[social4i size="small" align="align-left"]
</div>
-->

<div style="border: 1px solid; background: none repeat scroll 0 0 #EDEDED; margin: 1px; font-size: 12px;">
[This article was first published on  <strong><a href="http://flovv.github.io/llm-media-evals-in-r/"> Florian Teschner</a></strong>, and kindly contributed to <a href="https://www.r-bloggers.com/" rel="nofollow">R-bloggers</a>].  (You can report issue about the content on this page <a href="https://www.r-bloggers.com/contact-us/">here</a>)
<hr>Want to share your content on R-bloggers?<a href="https://www.r-bloggers.com/add-your-blog/" rel="nofollow"> click here</a> if you have a blog, or <a href="http://r-posts.com/" rel="nofollow"> here</a> if you don't.
</div>
<p>LLMs can produce a convincing media recommendation in a few seconds. The more useful question is whether the recommendation is correct: are the reach calculations right, are the assumptions visible, and does the plan fit the brief?</p>

<p>I work at Havas Media and I am the author of the <a href="https://havasmedia.de/hqai/#benchmark" rel="nofollow" target="_blank">Havas AI Media Quality Index (HAI-Q)</a>, a benchmark for media planning in the German market. I built it because generic knowledge tests are not enough for professional AI applications. A model can write a plausible paragraph about media strategy and still get a budget allocation, a target group definition, or a GRP calculation wrong.</p>

<p>This post has three parts. First, I will build a small media-planning evaluation in R using the <a href="https://vitals.tidyverse.org/" rel="nofollow" target="_blank">vitals package</a>. Then I will discuss why media-planning questions are unusually difficult to evaluate. Finally, I will focus on what the HAI-Q results tell us about general-purpose LLMs.</p>

<h2 id="1-a-small-eval-in-r">1. A small eval in R</h2>

<p>At its simplest, an LLM eval has three components:</p>

<ol>
  <li>A dataset containing questions and targets.</li>
  <li>A solver that answers the questions.</li>
  <li>A scorer that evaluates the answers.</li>
</ol>

<p>This is the basic structure used by <a href="https://vitals.tidyverse.org/articles/vitals.html" rel="nofollow" target="_blank">vitals</a>. The <code>target</code> column does not always need to contain one exact answer. For open-ended questions, it can contain grading guidance: what a good answer must include, which assumptions must be stated, and which errors should lose credit.</p>

<p>This is useful for testing the final answer of an LLM. It is less useful as a complete test of an AI agent. An agent consists of a harness and one or more models: it may retrieve data, call tools, run calculations, retry a failed step, maintain state, and decide when to ask for help. <code>vitals</code> mainly gives us a dataset, a solver, and a scorer. It does not automatically tell us whether the agent used the right tool, passed the right arguments, or recovered safely from an intermediate failure. It can be extended with custom solvers, but then the agent harness and trajectory checks still have to be built separately.</p>

<h3 id="the-questions">The questions</h3>

<p>Here is a deliberately small evaluation set. The questions cover calculation, planning, and interpretation. The targets are written as instructions for a grader rather than as model answers.</p>

<figure class="highlight"><pre>library(dplyr)
library(tibble)

media_questions &lt;- tribble(
  ~id, ~input, ~target, ~domain, ~task,

  &quot;grp-calculation&quot;,
  &quot;A campaign delivers 60% reach at an average frequency of 3. What is the campaign's GRP? State the assumption behind the calculation.&quot;,
  &quot;A full-credit answer calculates 60 * 3 = 180 GRP. It explains that this is the standard simplified relationship GRP = reach (in percent) * average frequency. It must not describe GRP as the number of unique people reached.&quot;,
  &quot;Reach and GRP&quot;, &quot;Calculation&quot;,

  &quot;budget-allocation&quot;,
  &quot;A client has EUR 100,000 to reach adults aged 25-49 in Germany. There is no historical channel performance data. Propose a first-pass media allocation and explain how you would improve it after launch.&quot;,
  &quot;There is no single correct allocation. A strong answer makes the uncertainty explicit, explains the role of each channel, avoids inventing CPMs or reach figures, and proposes a measurement and test-and-learn plan. It should distinguish a planning hypothesis from an observed result.&quot;,
  &quot;Media strategy&quot;, &quot;Recommendation&quot;,

  &quot;reach-frequency-tradeoff&quot;,
  &quot;Two plans have the same budget. Plan A has higher reach and lower frequency; Plan B has lower reach and higher frequency. How would you decide between them?&quot;,
  &quot;A full-credit answer says that the choice depends on the communication objective, the selected channesls, the overall attention, audience size, purchase cycle, creative strength, and expected response. It should explain the reach-frequency trade-off and ask for missing information instead of declaring one plan universally better.&quot;,
  &quot;Media strategy&quot;, &quot;Reasoning&quot;
)

media_questions</pre></figure>

<p>The questions are intentionally specific. “Create a good media plan” is difficult to score because almost any fluent answer can sound reasonable. A question about GRP, in contrast, gives us a concrete numerical check. The budget question tests something different: whether the model knows when it does not have enough information to justify a precise allocation.</p>

<p>In a real eval, I would expand this table with questions about channel roles, target-group definitions, reach curves, media costs, campaign objectives, and German market data. I would also add metadata such as difficulty, source, market, and the date on which the underlying data was valid.</p>

<h3 id="the-solver-and-scorer">The solver and scorer</h3>

<p>The <a href="https://vitals.tidyverse.org/articles/vitals.html" rel="nofollow" target="_blank">vitals introduction</a> uses <code>Task$new()</code> to combine the dataset, a solver, and a scorer. The following example uses Claude as the solver and an LLM-based grader. An API key for the selected provider is required.</p>

<figure class="highlight"><pre>library(vitals)
library(ellmer)

media_task &lt;- Task$new(
  dataset = media_questions,
  solver = generate(
    chat_openrouter(model = &quot;claude-sonnet-4.6&quot;)
  ),
  scorer = model_graded_qa(partial_credit = TRUE),
  name = &quot;A small media-planning eval&quot;
)

# Run the solver and scorer.
media_task$eval()

# Bind the results into a tibble for analysis.
media_scores &lt;- vitals_bind(media_task)
media_scores

media_scores |&gt;
  count(score)</pre></figure>

<p>With <code>partial_credit = TRUE</code>, the scorer can return <code>C</code> for correct, <code>P</code> for partially correct, or <code>I</code> for incorrect. This is more useful than a single binary score for media planning. A response may use the right calculation but fail to explain its assumptions. Another answer may be directionally useful but invent a media cost. Those are different failures and should not be hidden in one number.</p>

<p>The result is not the end of the evaluation. I would inspect the individual answers and the grading decisions, especially on the first few runs. If the grader repeatedly gives full credit to a response that I consider unsafe, the problem may be the grading guidance rather than the model.</p>

<h3 id="comparing-models">Comparing models</h3>

<p>Once the task exists, comparing solvers is straightforward. For example, the same questions can be evaluated with an OpenAI model and then combined with the first run.</p>

<figure class="highlight"><pre>media_task_openai &lt;- media_task$clone()

media_task_openai$eval(
  solver_chat = chat_openrouter(model = &quot;gpt-5.4&quot;)
)

comparison &lt;- vitals_bind(
  claude = media_task,
  openai = media_task_openai
) |&gt;
  mutate(model = recode(
    task,
    claude = &quot;Claude&quot;,
    openai = &quot;OpenAI&quot;
  ))

comparison |&gt;
  count(model, score)</pre></figure>

<p>The exact model names will change over time. The important part is to keep the questions and scoring rules stable while changing one component at a time. Otherwise, a score difference is difficult to interpret.</p>

<p>This example is an LLM eval, not an agent eval. It compares the text returned at the end of the solver. For an agent, I would additionally log the tool calls, retrieved documents, intermediate calculations, retries, latency, cost, and final answer. The test should then assert properties of the whole trajectory, not only the final prose.</p>

<h2 id="2-why-media-planning-evals-are-hard">2. Why media-planning evals are hard</h2>

<p>Media planning looks like a natural use case for LLMs. The work involves briefs, audience descriptions, channel recommendations, calculations, and written rationales. But the same combination makes the evaluation difficult.</p>

<h3 id="there-is-rarely-one-correct-plan">There is rarely one correct plan</h3>

<p>Many planning questions are underdetermined. A sensible allocation depends on the objective, budget, campaign length, audience size, creative assets, buying conditions, historical performance, and measurement setup. Two experienced planners can recommend different channel mixes and both be right.</p>

<p>This means that a target should often describe required properties rather than prescribe one number. For example, a full-credit answer might need to:</p>

<ul>
  <li>state its assumptions;</li>
  <li>stay within the budget;</li>
  <li>connect channel choices to the objective;</li>
  <li>distinguish facts from hypotheses; and</li>
  <li>explain how the plan would be measured and revised.</li>
</ul>

<p>The evaluator has to reward sound reasoning without turning one planner’s preference into a false ground truth.</p>

<h3 id="media-facts-are-local-and-time-dependent">Media facts are local and time-dependent</h3>

<p>A media answer can be correct in one market and wrong in another. Reach, costs, inventory, audience definitions, platform availability, and panel methodology all vary by country and by date. A model that has learned general media vocabulary does not automatically have access to the latest German market data.</p>

<p>This is why a useful eval should record the market and the data vintage. It should also test whether the model provides a source or clearly labels an assumption when a current figure is unavailable. “The average CPM is X” is not a safe answer if the model cannot explain where X came from.</p>

<h3 id="definitions-matter-more-than-fluent-prose">Definitions matter more than fluent prose</h3>

<p>Media planning has many terms that are close enough to sound interchangeable but are not interchangeable in a calculation. Reach can mean gross or net reach. Frequency can be average or effective frequency. GRP is not the same as the number of unique people reached. Target-group percentages need a denominator.</p>

<p>These distinctions create easy failure modes. A response can contain the right formula but apply it to the wrong quantity. It can also produce a tidy table whose totals do not add up. Numerical checks and constraint checks therefore need to be part of the eval, not just a general assessment of writing quality.</p>

<h3 id="llm-as-a-judge-is-useful-but-not-sufficient">LLM-as-a-judge is useful but not sufficient</h3>

<p>The <code>model_graded_qa()</code> scorer in <code>vitals</code> makes open-ended evaluation scalable. It is also a model judging another model’s answer, which introduces its own errors. A grader may prefer confident language, overlook a subtle numerical mistake, or accept an answer because it resembles the supplied guidance.</p>

<p>For a serious benchmark, I would calibrate the grader against human-labelled examples and keep a sample for manual review. I would also separate different dimensions where possible:</p>

<ul>
  <li>factual accuracy;</li>
  <li>numerical accuracy;</li>
  <li>constraint satisfaction;</li>
  <li>quality of reasoning; and</li>
  <li>usefulness of the recommendation.</li>
</ul>

<p>One overall score is convenient, but it can hide which part of the planning process is failing.</p>

<h3 id="vitals-is-not-an-agent-harness"><code>vitals</code> is not an agent harness</h3>

<p>The distinction matters in practice. <code>vitals</code> is a useful way to ask an LLM a fixed set of questions and score the answers. It is not, by itself, a test harness for an AI agent. If an agent has access to a reach database, a calculator, or a planning API, the evaluation needs to check the interaction with those components as well.</p>

<p>For an end-to-end agent eval, I would test at least four layers: whether the harness selects the right tool, whether the tool call is valid, whether the intermediate result is interpreted correctly, and whether the final answer communicates uncertainty. A final response can look reasonable even when one of those earlier steps failed.</p>

<h2 id="3-results-from-the-havas-hai-q">3. Results from the Havas HAI-Q</h2>

<p>The <a href="https://havasmedia.de/hqai/#benchmark" rel="nofollow" target="_blank">Havas HAI-Q page</a> describes a benchmark built for media planning in the German market. It contains 35 practical tasks across five areas:</p>

<ol>
  <li>Media strategy</li>
  <li>Channel and budget allocation</li>
  <li>Target-group evaluation</li>
  <li>Reach and GRP</li>
  <li>Media and effectiveness metrics</li>
</ol>

<p>In this post I focus on the general-purpose LLM results:</p>

<table>
  <thead>
    <tr>
      <th>Model</th>
      <th style="text-align: right">Correct answers</th>
      <th style="text-align: right">Share correct</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>GPT-5</td>
      <td style="text-align: right">16 / 35</td>
      <td style="text-align: right">45.7%</td>
    </tr>
    <tr>
      <td>Claude Sonnet 4.5</td>
      <td style="text-align: right">6 / 35</td>
      <td style="text-align: right">17.1%</td>
    </tr>
    <tr>
      <td>GPT-4o</td>
      <td style="text-align: right">4 / 35</td>
      <td style="text-align: right">11.4%</td>
    </tr>
  </tbody>
</table>

<p>The headline is uncomfortable: even GPT-5, the strongest general-purpose model in this comparison, is correct on fewer than half of the questions. It answers 16 of 35 questions correctly, leaving 19 answers that are not counted as correct. For practical media-planning work, that is not a safe error rate.</p>

<p>When I look at the individual HAI-Q questions, the errors are not evenly distributed. The models particularly struggle with numeric questions involving reach figures and audience sizes. They can produce a fluent explanation of a planning idea and still make a basic mistake in a denominator, a percentage, or the interpretation of a reach number. This is exactly the type of failure that is easy to miss if evaluation is based on plausibility rather than calculation.</p>

<p>There is also a clear improvement between the older and newer models. GPT-4o answers 4 of 35 questions correctly, compared with 16 of 35 for GPT-5. That is 12 additional correct answers and an improvement from 11.4% to 45.7%, or 34.3 percentage points. GPT-5 gets four times as many questions correct as GPT-4o on this benchmark. The improvement is substantial, even though the newer model is still not reliable enough for unsupervised media decisions.</p>

<p>Claude Sonnet 4.5 scores lower in this test, with 6 of 35 correct answers. This does not mean that the model is generally poor. It means that a general language benchmark and a domain-specific media-planning benchmark answer different questions. The HAI-Q is designed around the German market and a specific definition of correctness, including the numerical details that matter in planning.</p>

<p>The aggregate scores should still be read with care. They do not show the difficulty of every question, the variance across repeated runs, or the exact scoring decision for every answer. But the pattern is clear enough to be useful: current general-purpose LLMs are good at sounding like media planners, while still struggling to answer roughly half of these practical questions correctly.</p>

<h2 id="takeaways">Takeaways</h2>

<p>An LLM eval for media planning should start with real questions from the workflow, not generic prompts about marketing. In R, a tibble with <code>input</code> and <code>target</code> is enough to get started, and <code>vitals</code> provides a practical way to connect questions, solvers, scorers, and result inspection.</p>

<p>The difficult part is not running the model. It is defining what “correct” means when several plans can be reasonable, data changes by market and date, and a plausible answer can contain a subtle but consequential error. For agents, the evaluation also needs to cover the harness, tools, intermediate steps, and failure handling. A final answer score is not enough.</p>

<p>The HAI-Q results show that the latest general-purpose LLMs still answer more than half of these media-planning questions incorrectly. The largest weaknesses appear in numerical reasoning around reach and audience sizes. At the same time, the jump from GPT-4o to GPT-5 shows that model development is moving in the right direction.</p>

<p>For me, the practical conclusion is simple: use LLMs to accelerate media work, but test every numerical recommendation before relying on it. The next step is to combine model evals such as HAI-Q with end-to-end agent tests that measure tool use and the full planning workflow.</p>

<h3 id="resources">Resources</h3>

<ul>
  <li><a href="https://vitals.tidyverse.org/articles/vitals.html" rel="nofollow" target="_blank">Getting started with vitals</a></li>
  <li><a href="https://vitals.tidyverse.org/" rel="nofollow" target="_blank">vitals documentation</a></li>
  <li><a href="https://havasmedia.de/hqai/#benchmark" rel="nofollow" target="_blank">HAI-Q: Havas AI Media Quality Index</a></li>
  <li><a href="https://ellmer.tidyverse.org/" rel="nofollow" target="_blank">ellmer documentation</a></li>
</ul>

<div style="border: 1px solid; background: none repeat scroll 0 0 #EDEDED; margin: 1px; font-size: 13px;">
<div style="text-align: center;">To <strong>leave a comment</strong> for the author, please follow the link and comment on their blog: <strong><a href="http://flovv.github.io/llm-media-evals-in-r/"> Florian Teschner</a></strong>.</div>
<hr />
<a href="https://www.r-bloggers.com/" rel="nofollow">R-bloggers.com</a> offers <strong><a href="https://feedburner.google.com/fb/a/mailverify?uri=RBloggers" rel="nofollow">daily e-mail updates</a></strong> about <a title="The R Project for Statistical Computing" href="https://www.r-project.org/" rel="nofollow">R</a> news and tutorials about <a title="R tutorials" href="https://www.r-bloggers.com/how-to-learn-r-2/" rel="nofollow">learning R</a> and many other topics. <a title="Data science jobs" href="https://www.r-users.com/" rel="nofollow">Click here if you're looking to post or find an R/data-science job</a>.

<hr>Want to share your content on R-bloggers?<a href="https://www.r-bloggers.com/add-your-blog/" rel="nofollow"> click here</a> if you have a blog, or <a href="http://r-posts.com/" rel="nofollow"> here</a> if you don't.
</div><strong>Continue reading</strong>: <a href="https://www.r-bloggers.com/2026/07/evaluating-llms-ai-for-media-planning-in-r/">Evaluating LLMs/AI for Media Planning in R</a>]]></content:encoded>
					
		
		<enclosure url="" length="0" type="" />

		<post-id xmlns="com-wordpress:feed-additions:1">402903</post-id>	</item>
		<item>
		<title>US oil stocks by @ellis2013nz</title>
		<link>https://www.r-bloggers.com/2026/07/us-oil-stocks-by-ellis2013nz/</link>
		
		<dc:creator><![CDATA[free range statistics - R]]></dc:creator>
		<pubDate>Fri, 31 Jul 2026 13:00:00 +0000</pubDate>
				<category><![CDATA[R bloggers]]></category>
		<guid isPermaLink="false">https://freerangestats.info/blog/2026/08/01/fuel-crisis</guid>

					<description><![CDATA[<div style = "width:60%; display: inline-block; float:left; "> Like many people I have been keeping track of the slow-burn fuel crisis arising from the war in Iran, its possible expansion to the Red Sea, and exacerbation from the ongoing war between Russia and Ukraine. The latter seems to have reached a stage wher...</div>
<div style = "width: 40%; display: inline-block; float:right;"></div>
<div style="clear: both;"></div>
<strong>Continue reading</strong>: <a href="https://www.r-bloggers.com/2026/07/us-oil-stocks-by-ellis2013nz/">US oil stocks by @ellis2013nz</a>]]></description>
										<content:encoded><![CDATA[<!-- 
<div style="min-height: 30px;">
[social4i size="small" align="align-left"]
</div>
-->

<div style="border: 1px solid; background: none repeat scroll 0 0 #EDEDED; margin: 1px; font-size: 12px;">
[This article was first published on  <strong><a href="https://freerangestats.info/blog/2026/08/01/fuel-crisis"> free range statistics - R</a></strong>, and kindly contributed to <a href="https://www.r-bloggers.com/" rel="nofollow">R-bloggers</a>].  (You can report issue about the content on this page <a href="https://www.r-bloggers.com/contact-us/">here</a>)
<hr>Want to share your content on R-bloggers?<a href="https://www.r-bloggers.com/add-your-blog/" rel="nofollow"> click here</a> if you have a blog, or <a href="http://r-posts.com/" rel="nofollow"> here</a> if you don't.
</div>
<p>Like many people I have been keeping track of the slow-burn fuel crisis arising from the war in Iran, its possible expansion to the Red Sea, and exacerbation from the ongoing war between Russia and Ukraine. The latter seems to have reached a stage where serious damage is being done to Russia’s refining capacity and petro products’ exports.</p>

<p>I’ve now started a page on this website with <a href="https://freerangestats.info/fuel-crisis/index.html" rel="nofollow" target="_blank">a few charts on the fuel crisis</a> that I’m going to be keeping up to date.</p>

<h2 id="stocks-of-crude-are-going-down-but-how-much-is-left">Stocks of crude are going down, but “how much is left”?</h2>

<p>The motivation for today’s post was that I’d been seeing many news and opinion articles about how the US crude oil stocks—in total, and in the Strategic Petroleum Reserve in particular—have declined to modern record lows. But expert commentators are reluctant to show this decline in relation to the absolute amount left, as opposed to comparisons to seasonal or historic lows. This is understandable because no-one really knows (or perhaps tells) what the real “tank bottoms” are in a big complex system like the USA. A certain amount of oil, of uncertain volume but certainly in the tens (and possibly hundreds) of millions of barrels, is needed just to keep various bits of plumbing or storage from seizing up or collapsing.</p>

<p>So it’s hard to get a chart like this one, and I had to make it myself:</p>

<object type="image/svg+xml" data="https://freerangestats.info/img/0327-us-crude-from2000-01-01.svg" width="450"><img src="https://i2.wp.com/freerangestats.info/img/0327-us-crude-from2000-01-01.png?w=450&#038;ssl=1" data-recalc-dims="1" /></object>

<p>I’ve got no reputation as an oil expert to worry about, so I can safely draw those lines at a fairly arbitrary 24 (or 30) days of refinery throughput, and calculate the time it will take to get to those low levels “at the current rate”. It’s simplistic, but it’s an important reality check to see that there might be about 19 weeks left.</p>

<p>Fast as the stocks are being used up, the USA has a <em>lot</em> of oil available to it. But 19 weeks isn’t that many. Markets are betting that good things will happen in the weeks or months before the blue line reaches the red line. Because of that, oil is currently selling for around $90 per barrel instead of the $110+ that would be justified if people thought we had lost the traffic through the Strait of Hormuz indefinitely.</p>

<p>Not that I think 19 weeks is a realistic forecast. Long before US stocks reached that red line, there would be economic and political chaos. Efforts to keep retail prices artificially low would probably be overwhelmed and there would be material demand destruction. There would also be huge incentives for the US to give away anything to restore Persian Gulf and Red Sea transit routes. 19 weeks gives us a time frame within which <em>something</em> will have to change.</p>

<p>The value-add for me from this chart is showing the total oil available for the US in the event this becomes a real emergency for them; the comparison of that to a meaningful if arbitrary threshold in terms of days of refinery cover; and the calculation of weeks left at current draw-down rates to reach that high stress threshold.</p>

<h2 id="break-out-the-spr-and-also-look-at-gasoline-distillates">Break out the SPR and also look at gasoline, distillates</h2>

<p>The same data source has a lot of other detailed information, most of it far too detailed for me, but I’m interested enough in four key headline variables that are more detailed than “total stocks of crude oil”. In this chart I break down the total stocks into those in the Strategic Petroleum Reserve, and those in more normally accessed stocks. I also show the amounts held of two key refined products:</p>

<object type="image/svg+xml" data="https://freerangestats.info/img/0327-facet-us-stocks.svg" width="450"><img src="https://i1.wp.com/freerangestats.info/img/0327-facet-us-stocks.png?w=450&#038;ssl=1" data-recalc-dims="1" /></object>

<h2 id="code">Code</h2>

<p>Here’s the code that grabs the data from the US Energy Information Administration and draws that second plot:</p>

<figure class="highlight"><pre>library(tidyverse)
library(readxl)
library(scales)
library(glue)

fn &lt;- &quot;us-petrol-status-weekly.xls&quot;

download.file(
  &quot;https://ir.eia.gov/wpsr/psw01.xls&quot;,
  fn,
  mode = &quot;wb&quot;
)

us_stocks &lt;- read_excel(fn, sheet = &quot;Data 1&quot;, skip = 2) |&gt;
  rename(
    crude = `Weekly U.S. Ending Stocks of Crude Oil  (Thousand Barrels)`,
    crude_spr = `Weekly U.S. Ending Stocks of Crude Oil in SPR  (Thousand Barrels)`,
    gasoline = `Weekly U.S. Ending Stocks of Total Gasoline  (Thousand Barrels)`,
    diesel = `Weekly U.S. Ending Stocks of Distillate Fuel Oil  (Thousand Barrels)`,
    date = Date
  )

#------------------plotting------------------

eia_caption &lt;- glue(&quot;Source: Energy Information Administration (EIA). Accessed {format(Sys.Date(), '%d %B %Y')}&quot;)

# an annotation rectangle we can use in multiple charts
war_rect &lt;- annotate(
  &quot;rect&quot;,
  xmin = as.Date(&quot;2026-02-28&quot;),
  xmax = Inf,
  ymin = -Inf,
  ymax = Inf,
  alpha = 0.5,
  fill = &quot;grey80&quot;
)

# Facet plot of total crude, SPR crude, diesel and gasoline stocks
us_stocks |&gt;
  mutate(com_crude = crude - crude_spr) |&gt;
  select(
    date,
    `Non-SPR crude oil` = com_crude,
    `Crude oil in SPR` = crude_spr,
    `Gasoline` = gasoline,
    `Distillate (mostly diesel)` = diesel
  ) |&gt;
  gather(variable, value, -date) |&gt;
  mutate(variable = fct_reorder(variable, value)) |&gt;
  ggplot(aes(x = date, y = value / 1000)) +
  war_rect +
  facet_wrap(~variable, scales = &quot;free_y&quot;) +
  geom_line(colour = &quot;blue&quot;) +
  expand_limits(y = 0) +
  scale_y_continuous(label = comma) +
  labs(
    x = &quot;&quot;,
    y = &quot;Thousands of barrels&quot;,
    title = &quot;US stocks of crude oil, gasoline, and distillate fuel oil (effectively diesel)&quot;,
    subtitle = &quot;Showing both total crude oil stocks (crude) and those in the Strategic Petroleum Reserve (crude_spr)&quot;,
    caption = eia_caption
  )</pre></figure>

<p>As I side point, I’ve started using <a href="https://tidyverse.org/blog/2025/02/air/" rel="nofollow" target="_blank"><code>air</code></a> to format my code. Nearly always it comes out looking better and easier to read than my manual formatting, and it’s certainly more consistent. Thanks to D. Vaughan and L. Henry and the tidyverse.org project.</p>

<p>And here’s the code to draw my highly polished main plot, the one of total crude oil stocks with the annotations. I’ve tried to do this in a way that it will keep working in the months ahead with minimal maintenance, we’ll see how that goes.</p>

<figure class="highlight"><pre>refinery_throughput &lt;- 17.3 # as at 24 July, operating at 97% of US capacity. Daily refinery use.
plausible_stress &lt;- 30 * refinery_throughput
plausible_high_stress &lt;- 24 * refinery_throughput

crude_growth_summary &lt;- us_stocks |&gt;
  summarise(
    latest_crude = crude[date == max(date)],
    weeks = as.numeric(as.Date(max(date)) - as.Date(&quot;2026-04-03&quot;)) / 7,
    difference = (latest_crude -
      crude[date == as.Date(&quot;2026-04-03&quot;)]) /
      1000,
    ratio = latest_crude / crude[date == as.Date(&quot;2026-04-03&quot;)],
    # growth/decline per week in million barrels e.g. 10m barrels per week:
    difference_rate = difference / weeks,
    # growth/declien rate per week:
    growth_rate = 1 - exp(log(ratio) / weeks)
  ) |&gt;
  mutate(
    weeks_at_this_rate = (plausible_stress - latest_crude / 1000) /
      difference_rate
  )

plot_us_stocks &lt;- function(min_date = &quot;2020-01-01&quot;, lab_x_diff = NULL) {
  if (!&quot;Date&quot; %in% class(min_date)) {
    min_date &lt;- as.Date(min_date)
  }

  if (is.null(lab_x_diff)) {
    days_shown &lt;- as.numeric(as.Date(max(us_stocks$date))) -
      as.numeric(min_date)
    lab_x_diff &lt;- days_shown / 50
  }

  lv &lt;- tail(us_stocks, 1)$crude / 1000

  p2 &lt;- us_stocks |&gt;
    filter(date &gt;= min_date) |&gt;
    ggplot(aes(x = date, y = crude / 1000)) +
    war_rect +
    geom_hline(yintercept = plausible_stress, colour = &quot;darkred&quot;) +
    geom_hline(yintercept = plausible_high_stress, colour = &quot;red&quot;) +
    annotate(
      &quot;text&quot;,
      x = min_date + lab_x_diff,
      y = plausible_stress + 50,
      label = &quot;Illustrative stress threshold:\n30 days of refinery cover&quot;,
      colour = &quot;darkred&quot;,
      hjust = 0
    ) +
    annotate(
      &quot;text&quot;,
      x = min_date + lab_x_diff,
      y = plausible_high_stress - 30,
      label = &quot;Illustrative high stress threshold:\n24 days of refinery cover&quot;,
      colour = &quot;red&quot;,
      hjust = 0,
      vjust = 1
    ) +
    annotate(
      &quot;text&quot;,
      x = max(us_stocks$date) - 5e6,
      y = lv,
      label = glue(
        &quot;{round(lv)} million barrels;\n{round(lv / refinery_throughput)} days of cover&quot;
      ),
      size = 2.9,
      hjust = 1,
      vjust = 1,
      colour = &quot;blue&quot;
    ) +
    geom_line(colour = &quot;blue&quot;) +
    expand_limits(y = 0) +
    scale_y_continuous(
      label = comma,
      sec.axis = sec_axis(
        ~ . / refinery_throughput,
        name = &quot;Days of refinery throughput&quot;
      )
    ) +
    labs(
      x = &quot;&quot;,
      y = &quot;Millions of barrels&quot;,
      title = &quot;U.S. Total Crude Oil Stocks, including Strategic Petroleum Reserve&quot;,
      subtitle = glue(
        &quot;Comparison of existing inventories with refinery throughput as at July 2026.
Decline since peak on 3 April 2026 is at {abs(round(crude_growth_summary$difference_rate, 1))} million barrels per week; {round(crude_growth_summary$weeks_at_this_rate)} weeks from stress threshold at this (hypothetical and linear) rate.&quot;
      ),
      caption = eia_caption
    ) +
    theme(axis.line.y = element_line(colour = &quot;grey50&quot;))

    svglite(
      glue(&quot;all-us-crude-from{min_date}.svg&quot;),
      width = 10,
      height = 7
    )
    print(p2)
    dev.off()
}

plot_us_stocks(&quot;2000-01-01&quot;)
plot_us_stocks(&quot;2020-01-01&quot;)
plot_us_stocks(&quot;2025-01-01&quot;)</pre></figure>

<p>Because I did this plot in the form of a function, I have a couple of variants of the plot. One starting in 2020:</p>

<object type="image/svg+xml" data="https://freerangestats.info/img/0327-us-crude-from2020-01-01.svg" width="450"><img src="https://i2.wp.com/freerangestats.info/img/0327-us-crude-from2020-01-01.png?w=450&#038;ssl=1" data-recalc-dims="1" /></object>

<p>And the other zoomed right in to just January 2025 and onwards:</p>
<object type="image/svg+xml" data="https://freerangestats.info/img/0327-us-crude-from2025-01-01.svg" width="450"><img src="https://i0.wp.com/freerangestats.info/img/0327-us-crude-from2025-01-01.png?w=450&#038;ssl=1" data-recalc-dims="1" /></object>

<p>On the whole I prefer the plot I started with, showing the situation from 2000 and onwards. I’m trying to get some big picture perspective after all.</p>

<p>That’s all for today. The images on this page will stay the same as at the time of writing; but those on <a href="https://freerangestats.info/fuel-crisis/index.html" rel="nofollow" target="_blank">the fuel crisis monitoring page</a> will be updated each week.</p>


<div style="border: 1px solid; background: none repeat scroll 0 0 #EDEDED; margin: 1px; font-size: 13px;">
<div style="text-align: center;">To <strong>leave a comment</strong> for the author, please follow the link and comment on their blog: <strong><a href="https://freerangestats.info/blog/2026/08/01/fuel-crisis"> free range statistics - R</a></strong>.</div>
<hr />
<a href="https://www.r-bloggers.com/" rel="nofollow">R-bloggers.com</a> offers <strong><a href="https://feedburner.google.com/fb/a/mailverify?uri=RBloggers" rel="nofollow">daily e-mail updates</a></strong> about <a title="The R Project for Statistical Computing" href="https://www.r-project.org/" rel="nofollow">R</a> news and tutorials about <a title="R tutorials" href="https://www.r-bloggers.com/how-to-learn-r-2/" rel="nofollow">learning R</a> and many other topics. <a title="Data science jobs" href="https://www.r-users.com/" rel="nofollow">Click here if you're looking to post or find an R/data-science job</a>.

<hr>Want to share your content on R-bloggers?<a href="https://www.r-bloggers.com/add-your-blog/" rel="nofollow"> click here</a> if you have a blog, or <a href="http://r-posts.com/" rel="nofollow"> here</a> if you don't.
</div><strong>Continue reading</strong>: <a href="https://www.r-bloggers.com/2026/07/us-oil-stocks-by-ellis2013nz/">US oil stocks by @ellis2013nz</a>]]></content:encoded>
					
		
		<enclosure url="" length="0" type="" />

		<post-id xmlns="com-wordpress:feed-additions:1">402911</post-id>	</item>
		<item>
		<title>era 0.6.0: chronological comparison and difference</title>
		<link>https://www.r-bloggers.com/2026/07/era-0-6-0-chronological-comparison-and-difference/</link>
		
		<dc:creator><![CDATA[Joe Roe]]></dc:creator>
		<pubDate>Thu, 30 Jul 2026 00:00:00 +0000</pubDate>
				<category><![CDATA[R bloggers]]></category>
		<guid isPermaLink="false">https://joeroe.io/2026/07/30/era-0.6.0</guid>

					<description><![CDATA[<p>era v0.6.0 is now available on CRAN:</p>
<p>install.packages("era")<br />
library(era)</p>
<p>This minor release adds functions for chronological comparison of year vectors:</p>
<p>x  # BCE years &#038;lt...</p>
<strong>Continue reading</strong>: <a href="https://www.r-bloggers.com/2026/07/era-0-6-0-chronological-comparison-and-difference/">era 0.6.0: chronological comparison and difference</a>]]></description>
										<content:encoded><![CDATA[<!-- 
<div style="min-height: 30px;">
[social4i size="small" align="align-left"]
</div>
-->

<div style="border: 1px solid; background: none repeat scroll 0 0 #EDEDED; margin: 1px; font-size: 12px;">
[This article was first published on  <strong><a href="https://joeroe.io/2026/07/30/era-0.6.0.html"> Joe Roe</a></strong>, and kindly contributed to <a href="https://www.r-bloggers.com/" rel="nofollow">R-bloggers</a>].  (You can report issue about the content on this page <a href="https://www.r-bloggers.com/contact-us/">here</a>)
<hr>Want to share your content on R-bloggers?<a href="https://www.r-bloggers.com/add-your-blog/" rel="nofollow"> click here</a> if you have a blog, or <a href="http://r-posts.com/" rel="nofollow"> here</a> if you don't.
</div>
<p><strong><a href="https://era.joeroe.io/" rel="nofollow" target="_blank">era</a></strong> v0.6.0 is now available <a href="https://cran.r-project.org/package=era" rel="nofollow" target="_blank">on CRAN</a>:</p>

<span id="more-402881"></span>

<pre>install.packages(&quot;era&quot;)
library(era)
</pre>

<p>This minor release adds functions for <a href="https://era.joeroe.io/reference/yr_earlier_than.html" rel="nofollow" target="_blank">chronological comparison</a> of year vectors:</p>

<pre>x &lt;- yr(c(200, 100, 300), &quot;BCE&quot;)
yr_earlier_than(x, yr(150, &quot;BCE&quot;))
#&gt; # BCE years &lt;yr_lgl[3]&gt;:
#&gt; [1] FALSE FALSE  TRUE
#&gt; # Era: Before Common Era (BCE): Gregorian years (365.2425 days), counted backwards from 1

yr_later_than(x, yr(150, &quot;BCE&quot;))
#&gt; # BCE years &lt;yr_lgl[3]&gt;:
#&gt; [1]  TRUE FALSE FALSE
#&gt; # Era: Before Common Era (BCE): Gregorian years (365.2425 days), counted backwards from 1
</pre>

<p>And for <a href="https://era.joeroe.io/reference/yr_difference.html" rel="nofollow" target="_blank">calculating chronological differences</a> between year vectors:</p>

<pre>yr_difference(yr(300, &quot;BCE&quot;), yr(100, &quot;BCE&quot;))
#&gt; # years &lt;yr[1]&gt;:
#&gt; [1] 200
#&gt; # Era: Gregorian years (365.2425 days)
</pre>

<p>These functions are aware of era directionality: “BCE” years count backwards, so 300 BCE is earlier than 100 BCE. They support work on <a href="https://tempo.joeroe.io/" rel="nofollow" target="_blank">tempo</a>, a new package I am working on that represents chronological intervals and the temporal relations between them.</p>

<h2 id="links">Links</h2>

<ul>
  <li><a href="https://cran.r-project.org/package=era" rel="nofollow" target="_blank">era on CRAN</a></li>
  <li><a href="https://era.joeroe.io/" rel="nofollow" target="_blank">era package documentation</a></li>
  <li><a href="https://era.joeroe.io/articles/era.html" rel="nofollow" target="_blank">Introductory vignette</a></li>
  <li><a href="https://github.com/joeroe/era" rel="nofollow" target="_blank">Source code</a> (GitHub)</li>
</ul>
<div style="border: 1px solid; background: none repeat scroll 0 0 #EDEDED; margin: 1px; font-size: 13px;">
<div style="text-align: center;">To <strong>leave a comment</strong> for the author, please follow the link and comment on their blog: <strong><a href="https://joeroe.io/2026/07/30/era-0.6.0.html"> Joe Roe</a></strong>.</div>
<hr />
<a href="https://www.r-bloggers.com/" rel="nofollow">R-bloggers.com</a> offers <strong><a href="https://feedburner.google.com/fb/a/mailverify?uri=RBloggers" rel="nofollow">daily e-mail updates</a></strong> about <a title="The R Project for Statistical Computing" href="https://www.r-project.org/" rel="nofollow">R</a> news and tutorials about <a title="R tutorials" href="https://www.r-bloggers.com/how-to-learn-r-2/" rel="nofollow">learning R</a> and many other topics. <a title="Data science jobs" href="https://www.r-users.com/" rel="nofollow">Click here if you're looking to post or find an R/data-science job</a>.

<hr>Want to share your content on R-bloggers?<a href="https://www.r-bloggers.com/add-your-blog/" rel="nofollow"> click here</a> if you have a blog, or <a href="http://r-posts.com/" rel="nofollow"> here</a> if you don't.
</div><strong>Continue reading</strong>: <a href="https://www.r-bloggers.com/2026/07/era-0-6-0-chronological-comparison-and-difference/">era 0.6.0: chronological comparison and difference</a>]]></content:encoded>
					
		
		<enclosure url="" length="0" type="" />

		<post-id xmlns="com-wordpress:feed-additions:1">402881</post-id>	</item>
		<item>
		<title>Spurious correlations 0.2 is on CRAN!</title>
		<link>https://www.r-bloggers.com/2026/07/spurious-correlations-0-2-is-on-cran/</link>
		
		<dc:creator><![CDATA[https://pacha.dev/blog]]></dc:creator>
		<pubDate>Wed, 29 Jul 2026 23:00:00 +0000</pubDate>
				<category><![CDATA[R bloggers]]></category>
		<guid isPermaLink="false">https://pacha.dev/blog/2026/07/30/spuriouscorrelations/index.html</guid>

					<description><![CDATA[<div style = "width:60%; display: inline-block; float:left; "> This release adds feedback from students and instructors</div>
<div style = "width: 40%; display: inline-block; float:right;"></div>
<div style="clear: both;"></div>
<strong>Continue reading</strong>: <a href="https://www.r-bloggers.com/2026/07/spurious-correlations-0-2-is-on-cran/">Spurious correlations 0.2 is on CRAN!</a>]]></description>
										<content:encoded><![CDATA[<!-- 
<div style="min-height: 30px;">
[social4i size="small" align="align-left"]
</div>
-->

<div style="border: 1px solid; background: none repeat scroll 0 0 #EDEDED; margin: 1px; font-size: 12px;">
[This article was first published on  <strong><a href="https://pacha.dev/blog/2026/07/30/spuriouscorrelations/index.html"> https://pacha.dev/blog</a></strong>, and kindly contributed to <a href="https://www.r-bloggers.com/" rel="nofollow">R-bloggers</a>].  (You can report issue about the content on this page <a href="https://www.r-bloggers.com/contact-us/">here</a>)
<hr>Want to share your content on R-bloggers?<a href="https://www.r-bloggers.com/add-your-blog/" rel="nofollow"> click here</a> if you have a blog, or <a href="http://r-posts.com/" rel="nofollow"> here</a> if you don't.
</div>
<p>The goal of spuriouscorrelations is to keep alive the amazing examples from <a href="https://web.archive.org/web/20230607181247/https://tylervigen.com/spurious-correlations" rel="nofollow" target="_blank">Tyler Vigen</a>. Unfortunately, as of 2023-10-09, the website is down as my students noticed. Therefore, I decided to use the snapshot from the Internet Wayback Machine to save the datasets from 2023-06-07.</p>

<h2>Installation</h2>
<p>You can install the CRAN version of spuriouscorrelations with:</p>
<pre>install.packages(&quot;spuriouscorrelations&quot;)</pre>
<p>You can install the development version of spuriouscorrelations with:</p>
<pre>remotes::install_github(&quot;pachadotdev/spuriouscorrelations&quot;)</pre>

<h2>Example</h2>
<p>The package covers multiple examples for different spurious (and curious) correlations.</p>
<p>Here is a basic example which shows you how to plot a spurious correlation for the variables</p>
<ul>
<li>x: Number of people who drowned by falling into a pool</li>
<li>y: Films Nicolas Cage appeared in</li>
</ul>

<pre>library(spuriouscorrelations)
library(tinyplot)

pool_drownings
   year   x y
1  1999 109 2
2  2000 102 2
3  2001 102 2
4  2002  98 3
5  2003  85 1
6  2004  95 1
7  2005  96 2
8  2006  98 3
9  2007 123 4
10 2008  94 1
11 2009 102 4
cor(pool_drownings$x, pool_drownings$y)
[1] 0.6660043
tinyplot(
  y ~ x,
  data = pool_drownings,
  main = sprintf(&quot;Correlation %s&quot;, round(cor(pool_drownings$x, pool_drownings$y), 3)),
  xlab = &quot;Number of people who drowned by falling into a pool&quot;,
  ylab = &quot;Films Nicolas Cage appeared in&quot;
)</pre>

<p><img src="https://i1.wp.com/pacha.dev/blog/2026/07/30/spuriouscorrelations/unnamed-chunk-1-1.png?w=450&#038;ssl=1" class="img-fluid figure-img"  data-recalc-dims="1"></p>

<p>Converting the data to long format simplifies plotting both variables per year:</p>

<pre>pool_drownings_2 &lt;- reshape(
  pool_drownings, 
  varying = c(&quot;x&quot;, &quot;y&quot;),  # columns to collapse
  v.names = &quot;value&quot;,      # name of the new value column
  timevar = &quot;variable&quot;,   # name of the new ID column
  times = c(&quot;x&quot;, &quot;y&quot;),    # values to populate the ID column
  direction = &quot;long&quot;      # target format
)

pool_drownings_2
     year variable value id
1.x  1999        x   109  1
2.x  2000        x   102  2
3.x  2001        x   102  3
4.x  2002        x    98  4
5.x  2003        x    85  5
6.x  2004        x    95  6
7.x  2005        x    96  7
8.x  2006        x    98  8
9.x  2007        x   123  9
10.x 2008        x    94 10
11.x 2009        x   102 11
1.y  1999        y     2  1
2.y  2000        y     2  2
3.y  2001        y     2  3
4.y  2002        y     3  4
5.y  2003        y     1  5
6.y  2004        y     1  6
7.y  2005        y     2  7
8.y  2006        y     3  8
9.y  2007        y     4  9
10.y 2008        y     1 10
11.y 2009        y     4 11
tinyplot(
  value ~ year | variable, # &quot;|&quot; indicates the groping variable for the legend
  data = pool_drownings_2,
  main = sprintf(&quot;Correlation %s&quot;, round(cor(pool_drownings$x, pool_drownings$y), 3)),
  xlab = &quot;Year&quot;,
  ylab = &quot;Pooled observations&quot;,
  pch = 19 # solid dot shape
)</pre>

<p><img src="https://i2.wp.com/pacha.dev/blog/2026/07/30/spuriouscorrelations/unnamed-chunk-2-1.png?w=450&#038;ssl=1" class="img-fluid figure-img"  data-recalc-dims="1"></p>

<p>How about standarzing the variables to avoid the different scale visibility issue?</p>

<pre>pool_drownings_3 &lt;- pool_drownings

pool_drownings_3$x &lt;- (pool_drownings_3$x - mean(pool_drownings_3$x)) / sd(pool_drownings_3$x)
pool_drownings_3$y &lt;- (pool_drownings_3$y - mean(pool_drownings_3$y)) / sd(pool_drownings_3$y)

pool_drownings_3 &lt;- reshape(
  pool_drownings_3, 
  varying = c(&quot;x&quot;, &quot;y&quot;),  # columns to collapse
  v.names = &quot;value&quot;,      # name of the new value column
  timevar = &quot;variable&quot;,   # name of the new ID column
  times = c(&quot;x&quot;, &quot;y&quot;),    # values to populate the ID column
  direction = &quot;long&quot;      # target format
)

pool_drownings_3
     year variable      value id
1.x  1999        x  0.8952867  1
2.x  2000        x  0.1696333  2
3.x  2001        x  0.1696333  3
4.x  2002        x -0.2450258  4
5.x  2003        x -1.5926679  5
6.x  2004        x -0.5560201  6
7.x  2005        x -0.4523554  7
8.x  2006        x -0.2450258  8
9.x  2007        x  2.3465935  9
10.x 2008        x -0.6596849 10
11.x 2009        x  0.1696333 11
1.y  1999        y -0.2470999  1
2.y  2000        y -0.2470999  2
3.y  2001        y -0.2470999  3
4.y  2002        y  0.6589330  4
5.y  2003        y -1.1531327  5
6.y  2004        y -1.1531327  6
7.y  2005        y -0.2470999  7
8.y  2006        y  0.6589330  8
9.y  2007        y  1.5649658  9
10.y 2008        y -1.1531327 10
11.y 2009        y  1.5649658 11
tinyplot(
  value ~ year | variable, # &quot;|&quot; indicates the groping variable for the legend
  data = pool_drownings_3,
  main = sprintf(&quot;Correlation %s&quot;, round(cor(pool_drownings$x, pool_drownings$y), 3)),
  xlab = &quot;Year&quot;,
  ylab = &quot;Pooled standardized observations&quot;,
  pch = 19, # solid dot shape
  type = &quot;b&quot; # add line to see the trend clearly
)</pre>

<p><img src="https://i1.wp.com/pacha.dev/blog/2026/07/30/spuriouscorrelations/unnamed-chunk-3-1.png?w=450&#038;ssl=1" class="img-fluid figure-img"  data-recalc-dims="1"></p>
<div style="border: 1px solid; background: none repeat scroll 0 0 #EDEDED; margin: 1px; font-size: 13px;">
<div style="text-align: center;">To <strong>leave a comment</strong> for the author, please follow the link and comment on their blog: <strong><a href="https://pacha.dev/blog/2026/07/30/spuriouscorrelations/index.html"> https://pacha.dev/blog</a></strong>.</div>
<hr />
<a href="https://www.r-bloggers.com/" rel="nofollow">R-bloggers.com</a> offers <strong><a href="https://feedburner.google.com/fb/a/mailverify?uri=RBloggers" rel="nofollow">daily e-mail updates</a></strong> about <a title="The R Project for Statistical Computing" href="https://www.r-project.org/" rel="nofollow">R</a> news and tutorials about <a title="R tutorials" href="https://www.r-bloggers.com/how-to-learn-r-2/" rel="nofollow">learning R</a> and many other topics. <a title="Data science jobs" href="https://www.r-users.com/" rel="nofollow">Click here if you're looking to post or find an R/data-science job</a>.

<hr>Want to share your content on R-bloggers?<a href="https://www.r-bloggers.com/add-your-blog/" rel="nofollow"> click here</a> if you have a blog, or <a href="http://r-posts.com/" rel="nofollow"> here</a> if you don't.
</div><strong>Continue reading</strong>: <a href="https://www.r-bloggers.com/2026/07/spurious-correlations-0-2-is-on-cran/">Spurious correlations 0.2 is on CRAN!</a>]]></content:encoded>
					
		
		<enclosure url="" length="0" type="" />

		<post-id xmlns="com-wordpress:feed-additions:1">402883</post-id>	</item>
		<item>
		<title>ntroduction to All Things About bpvars, the R package for Forecasting with Bayesian Panel Vector Autoregressions workshop</title>
		<link>https://www.r-bloggers.com/2026/07/ntroduction-to-all-things-about-bpvars-the-r-package-for-forecasting-with-bayesian-panel-vector-autoregressions-workshop/</link>
		
		<dc:creator><![CDATA[Dariia Mykhailyshyna]]></dc:creator>
		<pubDate>Wed, 29 Jul 2026 12:43:07 +0000</pubDate>
				<category><![CDATA[R bloggers]]></category>
		<guid isPermaLink="false">https://r-posts.com/?p=19376</guid>

					<description><![CDATA[<p>Join our workshop on Introduction to All Things About bpvars, the R package for Forecasting with Bayesian Panel Vector Autoregressions,  which is a part of our workshops for Ukraine series!  Here’s some more info:  Title: All Things About bpvars, the R package for Forecasting with Bayesian Panel Vector Autoregressions ...</p>
<strong>Continue reading</strong>: <a href="https://www.r-bloggers.com/2026/07/ntroduction-to-all-things-about-bpvars-the-r-package-for-forecasting-with-bayesian-panel-vector-autoregressions-workshop/">ntroduction to All Things About bpvars, the R package for Forecasting with Bayesian Panel Vector Autoregressions workshop</a>]]></description>
										<content:encoded><![CDATA[<!-- 
<div style="min-height: 30px;">
[social4i size="small" align="align-left"]
</div>
-->

<div style="border: 1px solid; background: none repeat scroll 0 0 #EDEDED; margin: 1px; font-size: 12px;">
[This article was first published on  <strong><a href="http://r-posts.com/ntroduction-to-all-things-about-bpvars-the-r-package-for-forecasting-with-bayesian-panel-vector-autoregressions-workshop/"> R-posts.com</a></strong>, and kindly contributed to <a href="https://www.r-bloggers.com/" rel="nofollow">R-bloggers</a>].  (You can report issue about the content on this page <a href="https://www.r-bloggers.com/contact-us/">here</a>)
<hr>Want to share your content on R-bloggers?<a href="https://www.r-bloggers.com/add-your-blog/" rel="nofollow"> click here</a> if you have a blog, or <a href="http://r-posts.com/" rel="nofollow"> here</a> if you don't.
</div>
<p><span style="font-weight: 400">Join our workshop on Introduction to All Things About bpvars, the R package for Forecasting with Bayesian Panel Vector Autoregressions,</span> <span style="font-weight: 400"> which is a part of our workshops for Ukraine series! </span></p>
<br />
<p><b>Here’s some more info: </b></p>
<br />
<br />
<p><b>Title</b><span style="font-weight: 400">: All Things About bpvars, the R package for Forecasting with Bayesian Panel Vector Autoregressions</span></p>
<p><b>Date</b><span style="font-weight: 400">: Thursday, September 10th, 18:00 – 20:00 CEST (Rome, Berlin, Paris timezone) </span></p>
<p><b>Speaker</b><span style="font-weight: 400">: Tomasz Woźniak is a Bayesian econometrician developing new econometric methods for applied macroeconomic research. He has been a specialised R user for eighteen years, and has recently joined The R Journal as an Associate Editor. He is the author of several R packages, available at https://bsvars.org/, that combine blazingly fast algorithms written in C++ with the convenience of data analysis in R. He works as a senior lecturer at the University of Melbourne, where he has an extensive research, teaching, and engagement portfolio. Tomasz supports Ukraine. Slava Ukrainie!</span></p>
<p><b>Description: </b><span style="font-weight: 400">This session is a unique opportunity to learn to use the bpvars package for forecasting with Bayesian panel vector autoregressions in a wide range of applications spanning:</span></p>
<br />
<p><span style="font-weight: 400">* data preparation,</span></p>
<p><span style="font-weight: 400">* specification of panel vector autoregressions,</span></p>
<p><span style="font-weight: 400">* estimation of the models,</span></p>
<p><span style="font-weight: 400">* estimation with missing observations,</span></p>
<p><span style="font-weight: 400">* forecasting labour market outcomes globally,</span></p>
<p><span style="font-weight: 400">* plotting and reporting predictions of different qualities, including point and density forecasts, marginal, conditional, or restricted forecasts,</span></p>
<p><span style="font-weight: 400">* performing recursive expanding window forecasting,</span></p>
<p><span style="font-weight: 400">* generating forecasting performance reports.</span></p>
<br />
<p><span style="font-weight: 400">A sequence of hands-on exercises that fully prepares attendees to work with the package supports all of this. You are welcome to browse existing resources, including:</span></p>
<br />
<p><span style="font-weight: 400">* bpvars website: https://bsvars.org/bpvars/</span></p>
<p><span style="font-weight: 400">* bpvars CRAN profile: https://cran.r-project.org/package=bpvars</span></p>
<p><span style="font-weight: 400">* package vignette: https://doi.org/10.48550/arXiv.2606.14143</span></p>
<p><span style="font-weight: 400">* other materials: https://bsvars.org/bpvars/#resources</span></p>
<p><span style="font-weight: 400">See you soon!</span></p>
<br />
<p><span style="font-weight: 400">Preparation:</span></p>
<br />
<p><span style="font-weight: 400">This session assumes the attendees know the basics of time series analysis. Install and load the bpvars package, then check the documentation by running the code below. Run the example you will find there in R. If it works, you’re ready to go. Thanks!</span></p>
<p><span style="font-weight: 400">“`</span></p>
<p><span style="font-weight: 400">install.packages(“bpvars”)</span></p>
<p><span style="font-weight: 400">library(bpvars)</span></p>
<p><span style="font-weight: 400">?bpvars</span></p>
<p><b>Minimal registration fee:</b><span style="font-weight: 400"> 20 euro (or 20 USD or 800 UAH)</span></p>
<br />
<br />
<p><span style="font-weight: 400">Please note that the registration confirmation is sent 1 day before the workshop to all registered participants rather than immediately after registration</span></p>
<br />
<p><b>How can I register?</b></p>
<br />
<ul>
	<li style="font-weight: 400"><span style="font-weight: 400">Go to </span><a href="https://bit.ly/3wvwMA6" rel="nofollow" target="_blank"><span style="font-weight: 400">https://bit.ly/3wvwMA6</span></a><span style="font-weight: 400"> or </span><a href="https://bit.ly/4aD5LMC" rel="nofollow" target="_blank"><span style="font-weight: 400">https://bit.ly/4aD5LMC</span></a><span style="font-weight: 400">  or  </span><a href="https://bit.ly/3PFxtNA" rel="nofollow" target="_blank"><span style="font-weight: 400">https://bit.ly/3PFxtNA</span></a><span style="font-weight: 400"> and donate</span><b> at least 20 euro</b><span style="font-weight: 400">. </span><span style="font-weight: 400">Feel free to donate more if you can, all proceeds go directly to support Ukraine.</span></li>
</ul>
<br />
<ul>
	<li style="font-weight: 400"><span style="font-weight: 400">Save your donation receipt (after the donation is processed, there is an option to enter your email address on the website to which the donation receipt is sent)</span></li>
</ul>
<br />
<ul>
	<li style="font-weight: 400"><span style="font-weight: 400">Fill in the</span><a href="https://forms.gle/x1Xc2aPsa1YDD1dD9" rel="nofollow" target="_blank"><span style="font-weight: 400"> registration form</span></a><span style="font-weight: 400">, attaching a screenshot of a donation receipt (please attach the screenshot of the donation receipt that was emailed to you rather than the page you see after donation).</span></li>
</ul>
<br />
<p><span style="font-weight: 400">If you are not personally interested in attending, you can also contribute by sponsoring a participation of a student, who will then be able to participate for free. If you choose to sponsor a student, all proceeds will also go directly to organisations working in Ukraine. You can either sponsor a particular student or you can leave it up to us so that we can allocate the sponsored place to students who have signed up for the waiting list.</span></p>
<br />
<p><b>How can I sponsor a student?</b></p>
<ul>
	<li style="font-weight: 400"><span style="font-weight: 400">Go to </span><a href="https://bit.ly/3wvwMA6" rel="nofollow" target="_blank"><span style="font-weight: 400">https://bit.ly/3wvwMA6</span></a><span style="font-weight: 400"> or </span><a href="https://bit.ly/4aD5LMC" rel="nofollow" target="_blank"><span style="font-weight: 400">https://bit.ly/4aD5LMC</span></a><span style="font-weight: 400">  or </span><a href="https://bit.ly/3PFxtNA" rel="nofollow" target="_blank"><span style="font-weight: 400">https://bit.ly/3PFxtNA</span></a><span style="font-weight: 400"> and donate </span><b>at least 20 euro </b><span style="font-weight: 400">(or 17 GBP or 20 USD or 800 UAH). </span><span style="font-weight: 400">Feel free to donate more if you can, all proceeds go to support Ukraine!</span></li>
</ul>
<br />
<ul>
	<li style="font-weight: 400"><span style="font-weight: 400">Save your donation receipt (after the donation is processed, there is an option to enter your email address on the website to which the donation receipt is sent)</span></li>
</ul>
<br />
<ul>
	<li style="font-weight: 400"><span style="font-weight: 400">Fill in the </span><a href="https://forms.gle/VdAkKshBjicvnrWq5" rel="nofollow" target="_blank"><span style="font-weight: 400">sponsorship form</span></a><span style="font-weight: 400">, attaching the screenshot of the donation receipt (please attach the screenshot of the donation receipt that was emailed to you rather than the page you see after the donation). You can indicate whether you want to sponsor a particular student or we can allocate this spot ourselves to the students from the waiting list. You can also indicate whether you prefer us to prioritize students from developing countries when assigning place(s) that you sponsored.</span></li>
</ul>
<br />
<br />
<p><span style="font-weight: 400">If you are a university student and cannot afford the registration fee, you can also sign up for the </span><b>waiting list</b> <a href="https://forms.gle/sokQuowKYLx4AQdg9" rel="nofollow" target="_blank"><span style="font-weight: 400">here</span></a><span style="font-weight: 400">. (Note that you are not guaranteed to participate by signing up for the waiting list).</span></p>
<br />
<br />
<p><span style="font-weight: 400">You can also find more information about this workshop series,  a schedule of our future workshops as well as a list of our past workshops which you can get the recordings &#038; materials </span><a href="http://bit.ly/3wBeY4S" rel="nofollow" target="_blank"><span style="font-weight: 400">here</span></a><span style="font-weight: 400">.</span></p>
<br />
<p><span style="font-weight: 400">Looking forward to seeing you during the workshop!</span></p>
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<p><span style="font-weight: 400"> </span></p>
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br /><hr style="border-top: black solid 1px" /><a href="http://r-posts.com/ntroduction-to-all-things-about-bpvars-the-r-package-for-forecasting-with-bayesian-panel-vector-autoregressions-workshop/" rel="nofollow" target="_blank">ntroduction to All Things About bpvars, the R package for Forecasting with Bayesian Panel Vector Autoregressions workshop</a> was first posted on July 29, 2026 at 12:43 pm.<br />
<div style="border: 1px solid; background: none repeat scroll 0 0 #EDEDED; margin: 1px; font-size: 13px;">
<div style="text-align: center;">To <strong>leave a comment</strong> for the author, please follow the link and comment on their blog: <strong><a href="http://r-posts.com/ntroduction-to-all-things-about-bpvars-the-r-package-for-forecasting-with-bayesian-panel-vector-autoregressions-workshop/"> R-posts.com</a></strong>.</div>
<hr />
<a href="https://www.r-bloggers.com/" rel="nofollow">R-bloggers.com</a> offers <strong><a href="https://feedburner.google.com/fb/a/mailverify?uri=RBloggers" rel="nofollow">daily e-mail updates</a></strong> about <a title="The R Project for Statistical Computing" href="https://www.r-project.org/" rel="nofollow">R</a> news and tutorials about <a title="R tutorials" href="https://www.r-bloggers.com/how-to-learn-r-2/" rel="nofollow">learning R</a> and many other topics. <a title="Data science jobs" href="https://www.r-users.com/" rel="nofollow">Click here if you're looking to post or find an R/data-science job</a>.

<hr>Want to share your content on R-bloggers?<a href="https://www.r-bloggers.com/add-your-blog/" rel="nofollow"> click here</a> if you have a blog, or <a href="http://r-posts.com/" rel="nofollow"> here</a> if you don't.
</div><strong>Continue reading</strong>: <a href="https://www.r-bloggers.com/2026/07/ntroduction-to-all-things-about-bpvars-the-r-package-for-forecasting-with-bayesian-panel-vector-autoregressions-workshop/">ntroduction to All Things About bpvars, the R package for Forecasting with Bayesian Panel Vector Autoregressions workshop</a>]]></content:encoded>
					
		
		<enclosure url="" length="0" type="" />

		<post-id xmlns="com-wordpress:feed-additions:1">402867</post-id>	</item>
		<item>
		<title>Using ghost text and next edit suggestions to learn agentic coding</title>
		<link>https://www.r-bloggers.com/2026/07/using-ghost-text-and-next-edit-suggestions-to-learn-agentic-coding/</link>
		
		<dc:creator><![CDATA[Seascapemodels]]></dc:creator>
		<pubDate>Mon, 27 Jul 2026 14:00:00 +0000</pubDate>
				<category><![CDATA[R bloggers]]></category>
		<guid isPermaLink="false">https://www.seascapemodels.org/posts/2026-07-28-next-edit-suggestions/</guid>

					<description><![CDATA[<div style = "width:60%; display: inline-block; float:left; ">
<p>I’m a big fan of Github Copilots ghost text and next edit suggestions. As a data analyst they give you much more control over the pace and direction of analysis code than a full AI agent. They also let you practice the core skill an agent needs ...</p></div>
<div style = "width: 40%; display: inline-block; float:right;"></div>
<div style="clear: both;"></div>
<strong>Continue reading</strong>: <a href="https://www.r-bloggers.com/2026/07/using-ghost-text-and-next-edit-suggestions-to-learn-agentic-coding/">Using ghost text and next edit suggestions to learn agentic coding</a>]]></description>
										<content:encoded><![CDATA[<!-- 
<div style="min-height: 30px;">
[social4i size="small" align="align-left"]
</div>
-->

<div style="border: 1px solid; background: none repeat scroll 0 0 #EDEDED; margin: 1px; font-size: 12px;">
[This article was first published on  <strong><a href="https://www.seascapemodels.org/posts/2026-07-28-next-edit-suggestions/"> Seascapemodels</a></strong>, and kindly contributed to <a href="https://www.r-bloggers.com/" rel="nofollow">R-bloggers</a>].  (You can report issue about the content on this page <a href="https://www.r-bloggers.com/contact-us/">here</a>)
<hr>Want to share your content on R-bloggers?<a href="https://www.r-bloggers.com/add-your-blog/" rel="nofollow"> click here</a> if you have a blog, or <a href="http://r-posts.com/" rel="nofollow"> here</a> if you don't.
</div>
 





<p>I’m a big fan of Github Copilots ghost text and next edit suggestions. As a data analyst they give you much more control over the pace and direction of analysis code than a full AI agent. They also let you practice the core skill an agent needs from you: writing a clear specification.</p>
<p>I’ll walk through it in R, but the same ideas apply in any language. I’m assuming you’re on VScode with the Copilot extension installed. This should work with the free or paid plans (though I haven’t checked free myself).</p>
<section id="start-with-ghost-text" class="level2">
<h2 class="anchored" data-anchor-id="start-with-ghost-text">Start with ghost text</h2>
<p>Ghost text is the greyed-out completion that appears as you type. Say you have a long-format dataset with timeseries for three species:</p>
<pre>library(dplyr)
library(ggplot2)
dat &lt;- data.frame(
    time = rep(1:10, 3),
    species = rep(c(&quot;A&quot;, &quot;B&quot;, &quot;C&quot;), each = 10),
    value = c(rnorm(10, mean = 5), rnorm(10, mean = 10), rnorm(10, mean = 15))
)</pre>
<p>You want to filter to one species, fit a linear model to its timeseries, pull out the slope, and make a labelled plot. Start typing the code for a single species and ghost text fills in the rest of the line. Here I’ve typed <code>m1 &lt;- lm(value ~</code> and Copilot offers the completion in transparent text (note change in image after the <code>~</code>):</p>
<p><img src="https://i2.wp.com/www.seascapemodels.org/posts/2026-07-28-next-edit-suggestions/1_ghost-text-example.png?w=578&#038;ssl=1" class="img-fluid" data-recalc-dims="1"></p>
<p>Press tab to accept. Working one line at a time, you end up with the code for species A:</p>
<pre>datA &lt;- dat |&gt; filter(species == &quot;A&quot;)
m1 &lt;- lm(value ~ time, data = datA)
coef(m1)[&quot;time&quot;]

ggplot(datA, aes(x = time, y = value)) +
    geom_point() +
    geom_smooth(method = &quot;lm&quot;, se = FALSE) +
    labs(
        title = &quot;Species A Time Series&quot;,
        x = &quot;Time&quot;,
        y = &quot;Value&quot;
    )</pre>
<p>Notice we’re not trying to be general yet. We’re developing our ideas for a single case, species A. We know we’ll want to generalise later, but we’re not worrying about it now. This is the same discipline that makes agents work well: get one concrete case right first, then automate it.</p>
</section>
<section id="turn-on-next-edit-suggestions" class="level2">
<h2 class="anchored" data-anchor-id="turn-on-next-edit-suggestions">Turn on next edit suggestions</h2>
<p>Next edit suggestions go a step further than ghost text. Instead of completing the line you’re on, Copilot predicts the <em>next change you’ll want to make elsewhere</em> and points you to it.</p>
<p>Click the octocat icon in the bottom right of the VScode window and turn on <strong>Next Edit Suggestions</strong>. I recommend leaving this off most of the time — it’s distracting when it suggests edits you don’t want — and switching it on for jobs like this one.</p>
<p>Now click above the species A code and start typing the name of a function to wrap it in. As soon as I write the <code>fit_fun &lt;- function(species_name)</code> header, Copilot spots that the hardcoded <code>&quot;A&quot;</code> needs to change, and flags it with an arrow in the gutter:</p>
<p><img src="https://i2.wp.com/www.seascapemodels.org/posts/2026-07-28-next-edit-suggestions/2_next-edit-suggestion-part1.png?w=578&#038;ssl=1" class="img-fluid" data-recalc-dims="1"></p>
<p>Press tab and it walks you through the edits needed to generalise. It replaces <code>species == &quot;A&quot;</code> with <code>species == species_name</code>, and further down it rewrites the plot title from the literal <code>&quot;Species A Time Series&quot;</code> to a <code>paste()</code> call that builds the title from <code>species_name</code>:</p>
<p><img src="https://i2.wp.com/www.seascapemodels.org/posts/2026-07-28-next-edit-suggestions/3_next-edit-suggestion-part2.png?w=578&#038;ssl=1" class="img-fluid" data-recalc-dims="1"></p>
<p>Tab through each suggestion and you land on a working, generalised function:</p>
<pre>fit_fun &lt;- function(species_name) {
    datA &lt;- dat |&gt; filter(species == species_name)
    m1 &lt;- lm(value ~ time, data = datA)
    coef(m1)[&quot;time&quot;]

    ggplot(datA, aes(x = time, y = value)) +
        geom_point() +
        geom_smooth(method = &quot;lm&quot;, se = FALSE) +
        labs(
            title = paste(&quot;Species&quot;, species_name, &quot;Time Series&quot;),
            x = &quot;Time&quot;,
            y = &quot;Value&quot;
        )
}

fit_fun(&quot;A&quot;)</pre>
<p>The single-species code was the specification and then Copilot did the mechanical work of generalising it. This is a good scaffold for thinking about agentic programming, where you write a clear spec and the agent does the automation.</p>
<p>The big difference from a true agent is that ghost text and next edit don’t run your R code and iterate to fix errors. They just predict edits. But that makes them a safe place to build the skills.</p>
</section>
<section id="drive-it-with-comments" class="level2">
<h2 class="anchored" data-anchor-id="drive-it-with-comments">Drive it with comments</h2>
<p>You can run the same next-edit approach with text only. Write out a recipe for what you want as comments, then start typing under the first step. Ghost text and next edit take over and help you write the rest.</p>
<p>Here’s a simple recipe:</p>
<pre># Simulate a new dataset of abundance at x-y coordinates

# plot a 2D map

# fit a model with interaction between x and y</pre>
<p>With just the comments in place and the cursor after the simulation, Copilot reads the recipe ahead of it:</p>
<p><img src="https://i1.wp.com/www.seascapemodels.org/posts/2026-07-28-next-edit-suggestions/4.png?w=578&#038;ssl=1" class="img-fluid" data-recalc-dims="1"></p>
<p>Then suggests a next edit suggestion after the following comment:</p>
<p><img src="https://i2.wp.com/www.seascapemodels.org/posts/2026-07-28-next-edit-suggestions/5.png?w=578&#038;ssl=1" class="img-fluid" data-recalc-dims="1"></p>
<p>Keep going and it writes the model for the final step, picking up the interaction from the comment <code># fit a model with interaction between x and y</code>:</p>
<p><img src="https://i2.wp.com/www.seascapemodels.org/posts/2026-07-28-next-edit-suggestions/6.png?w=578&#038;ssl=1" class="img-fluid" data-recalc-dims="1"></p>
<p>The finished block writes itself from the recipe:</p>
<p>A few tips. I set Copilot’s eagerness to <strong>High</strong> so suggestions come up quickly. Sometimes you need to type the first few characters of a line to kickstart the ghost text.</p>
<p>The clearer and more specific your comments, the closer the suggestions will be to what you actually wanted.</p>


</section>

 
<div style="border: 1px solid; background: none repeat scroll 0 0 #EDEDED; margin: 1px; font-size: 13px;">
<div style="text-align: center;">To <strong>leave a comment</strong> for the author, please follow the link and comment on their blog: <strong><a href="https://www.seascapemodels.org/posts/2026-07-28-next-edit-suggestions/"> Seascapemodels</a></strong>.</div>
<hr />
<a href="https://www.r-bloggers.com/" rel="nofollow">R-bloggers.com</a> offers <strong><a href="https://feedburner.google.com/fb/a/mailverify?uri=RBloggers" rel="nofollow">daily e-mail updates</a></strong> about <a title="The R Project for Statistical Computing" href="https://www.r-project.org/" rel="nofollow">R</a> news and tutorials about <a title="R tutorials" href="https://www.r-bloggers.com/how-to-learn-r-2/" rel="nofollow">learning R</a> and many other topics. <a title="Data science jobs" href="https://www.r-users.com/" rel="nofollow">Click here if you're looking to post or find an R/data-science job</a>.

<hr>Want to share your content on R-bloggers?<a href="https://www.r-bloggers.com/add-your-blog/" rel="nofollow"> click here</a> if you have a blog, or <a href="http://r-posts.com/" rel="nofollow"> here</a> if you don't.
</div><strong>Continue reading</strong>: <a href="https://www.r-bloggers.com/2026/07/using-ghost-text-and-next-edit-suggestions-to-learn-agentic-coding/">Using ghost text and next edit suggestions to learn agentic coding</a>]]></content:encoded>
					
		
		<enclosure url="" length="0" type="" />

		<post-id xmlns="com-wordpress:feed-additions:1">402854</post-id>	</item>
		<item>
		<title>June 2026 Top 40 New CRAN Packages</title>
		<link>https://www.r-bloggers.com/2026/07/june-2026-top-40-new-cran-packages/</link>
		
		<dc:creator><![CDATA[Joseph Rickert]]></dc:creator>
		<pubDate>Mon, 27 Jul 2026 00:00:00 +0000</pubDate>
				<category><![CDATA[R bloggers]]></category>
		<guid isPermaLink="false">https://rworks.dev/posts/june-2026-top-40-new-cran-packages/</guid>

					<description><![CDATA[<div style = "width:60%; display: inline-block; float:left; ">
<p>Four hundred twelve new packages were submitted to CRAN in June. Here are my Top 40 picks in nineteen categories: Bioarchaeology, Biology, Climate Studies, Computational Methods, Ecology, Epidemiology, Finance, Functional Data Analysis, Machine ...</p></div>
<div style = "width: 40%; display: inline-block; float:right;"></div>
<div style="clear: both;"></div>
<strong>Continue reading</strong>: <a href="https://www.r-bloggers.com/2026/07/june-2026-top-40-new-cran-packages/">June 2026 Top 40 New CRAN Packages</a>]]></description>
										<content:encoded><![CDATA[<!-- 
<div style="min-height: 30px;">
[social4i size="small" align="align-left"]
</div>
-->

<div style="border: 1px solid; background: none repeat scroll 0 0 #EDEDED; margin: 1px; font-size: 12px;">
[This article was first published on  <strong><a href="https://rworks.dev/posts/june-2026-top-40-new-cran-packages/"> R Works</a></strong>, and kindly contributed to <a href="https://www.r-bloggers.com/" rel="nofollow">R-bloggers</a>].  (You can report issue about the content on this page <a href="https://www.r-bloggers.com/contact-us/">here</a>)
<hr>Want to share your content on R-bloggers?<a href="https://www.r-bloggers.com/add-your-blog/" rel="nofollow"> click here</a> if you have a blog, or <a href="http://r-posts.com/" rel="nofollow"> here</a> if you don't.
</div>
 





<p>Four hundred twelve new packages were submitted to CRAN in June. Here are my Top 40 picks in nineteen categories: Bioarchaeology, Biology, Climate Studies, Computational Methods, Ecology, Epidemiology, Finance, Functional Data Analysis, Machine Learning, Medical Statistics, Networks, Pharmacokinetics, Probability, Programming, Psychometrics, Risk Analysis, Statistics, Time Series, and Utilities.</p>
<div class="columns">
<div class="column" style="width:45%;">
<section id="bioarchaeology" class="level3">
<h3 class="anchored" data-anchor-id="bioarchaeology">Bioarchaeology</h3>
<p><a href="https://cran.r-project.org/package=baytaAAR" rel="nofollow" target="_blank">baytaAAR</a> v1.0.3: Provides Bayesian age estimation for bioarchaeological skeletal data using ordinal probit regression models implemented in <code>JAGS</code> and <code>NIMBLE</code>. The package is designed to handle multiple ordinal traits of adult individuals and incorporates a Gompertz prior on age to reflect population-level mortality. It accounts for estimation uncertainties and supports full customization of model parameters and Markov Chain Monte Carlo settings. For more details, see <a href="https://onlinelibrary.wiley.com/doi/10.1002/ajpa.70289" rel="nofollow" target="_blank">Müller-Scheeßel et al. (2026)</a>. There are five vignettes including <a href="https://cran.r-project.org/web/packages/baytaAAR/vignettes/baytaAAR.html" rel="nofollow" target="_blank">Introduction</a> and <a href="https://cran.r-project.org/web/packages/baytaAAR/vignettes/mathematical_background.html" rel="nofollow" target="_blank">Mathematical background</a>.</p>
<p><a href="https://i0.wp.com/rworks.dev/posts/june-2026-top-40-new-cran-packages/baytoAAR.png?ssl=1" class="lightbox" data-gallery="quarto-lightbox-gallery-1" rel="nofollow" target="_blank"><img src="https://i0.wp.com/rworks.dev/posts/june-2026-top-40-new-cran-packages/baytoAAR.png?w=578&#038;ssl=1" class="img-fluid" alt="Plot of distribution of age to death" data-recalc-dims="1"></a></p>
</section>
<section id="biology" class="level3">
<h3 class="anchored" data-anchor-id="biology">Biology</h3>
<p><a href="https://cran.r-project.org/package=power.nb" rel="nofollow" target="_blank">power.nb</a> v0.1.0: Provides functions for estimating statistical power and required sample sizes in differential abundance microbiome studies using negative binomial models and includes tools for simulation-based power analysis and sample size estimation using generalized additive models (GAMs), and visualization utilities for exploring the relationship between power, effect size, abundance, and sample size. The methods are based on <a href="https://journals.plos.org/plosone/article?id=10.1371/journal.pone.0318820" rel="nofollow" target="_blank">Agronah and Bolker (2025)</a>. See the <a href="https://cran.r-project.org/web/packages/power.nb/vignettes/stub.html" rel="nofollow" target="_blank">vignette</a>.</p>
<p><a href="https://i0.wp.com/rworks.dev/posts/june-2026-top-40-new-cran-packages/powervb.png?ssl=1" class="lightbox" data-gallery="quarto-lightbox-gallery-2" rel="nofollow" target="_blank"><img src="https://i0.wp.com/rworks.dev/posts/june-2026-top-40-new-cran-packages/powervb.png?w=578&#038;ssl=1" class="img-fluid" alt="Contour plot showing power for various combinations of mean abundance and fold change" data-recalc-dims="1"></a></p>
</section>
<section id="climate-studies" class="level3">
<h3 class="anchored" data-anchor-id="climate-studies">Climate Studies</h3>
<p><a href="https://cran.r-project.org/package=clim4health" rel="nofollow" target="_blank">clim4health</a> v0.1.0: Provides functions to obtain, transform and export climate data, including reanalyses, seasonal forecasts and hindcasts, and weather stations for their use in epidemiological analyses. Features include downscaling, verification, spatiotemporal aggregation and threshold-based indicators. See <a href="https://www.nature.com/articles/s41598-026-45067-2" rel="nofollow" target="_blank">Duzenli et al. (2026)</a> for downscaling methods and <a href="https://www.sciencedirect.com/science/article/abs/pii/S1364815217302219" rel="nofollow" target="_blank">Manubens et al. (2018)</a> for verification methods. There are six vignettes, including <a href="https://cran.r-project.org/web/packages/clim4health/vignettes/clim4health_s2dv_cubes.html" rel="nofollow" target="_blank">Introduction</a> and <a href="https://cran.r-project.org/web/packages/clim4health/vignettes/clim4health_overview.html" rel="nofollow" target="_blank">Overview</a>.</p>
</section>
<section id="computational-methods" class="level3">
<h3 class="anchored" data-anchor-id="computational-methods">Computational Methods</h3>
<p><a href="https://cran.r-project.org/package=momst" rel="nofollow" target="_blank">momst</a> v0.1.1: Provides functions to solve the Multi-Criteria Minimum Spanning Tree problem on complete weighted graphs by combining the Non-dominated Sorting Genetic Algorithm II with optional Pareto local search operators. Chromosomes are represented as Prufer sequences so that every random individual decodes to a valid spanning tree (Cayley’s theorem), avoiding repair operators. Four solver variants are provided: NSGA-II, Path Relinking, Pareto Local Search, and Tabu Search. See <a href="https://ieeexplore.ieee.org/document/7969432" rel="nofollow" target="_blank">Parraga-Alava et al. (2017)</a> for background. There are two vignettes: <a href="https://cran.r-project.org/web/packages/momst/vignettes/getting-started.html" rel="nofollow" target="_blank">Getting Started</a> and <a href="https://cran.r-project.org/web/packages/momst/vignettes/momst-variants.html" rel="nofollow" target="_blank">Comparing the Four MO-MST Variants</a>.</p>
<p><a href="https://i2.wp.com/rworks.dev/posts/june-2026-top-40-new-cran-packages/momst.png?ssl=1" class="lightbox" data-gallery="quarto-lightbox-gallery-3" rel="nofollow" target="_blank"><img src="https://i2.wp.com/rworks.dev/posts/june-2026-top-40-new-cran-packages/momst.png?w=578&#038;ssl=1" class="img-fluid" alt="Graphs of spanning tree variants" data-recalc-dims="1"></a></p>
<p><a href="https://cran.r-project.org/package=nmathopencl" rel="nofollow" target="_blank">nmathopencl</a> v0.8.3: Ships statistical and mathematical routines from the <code>R</code> internal <a href="https://github.com/SurajGupta/r-source/blob/master/src/nmath/nmath.h" rel="nofollow" target="_blank"><code>nmath</code></a> (<code>Mathlib</code>) as <a href="https://en.wikipedia.org/wiki/OpenCL" rel="nofollow" target="_blank"><code>OpenCL</code></a> <code>C</code> sources under directory <code>inst/cl/</code>, with <code>R</code> wrappers. Uses the GPU when <code>OpenCL</code> is available at compile time and falls back to <code>stats</code> equivalents otherwise. Aimed at package developers building custom kernels (for example Bayesian GLMs via suggested package <code>glmbayes</code>) using <code>opencltools</code> kernel loaders and related helpers. There are thirteen vignettes, including <a href="https://cran.r-project.org/web/packages/nmathopencl/vignettes/Chapter-00.html" rel="nofollow" target="_blank">Package Overview</a> and <a href="https://cran.r-project.org/web/packages/nmathopencl/vignettes/Chapter-10.html" rel="nofollow" target="_blank">Case study</a>.</p>
<p><a href="https://cran.r-project.org/package=sparsediff" rel="nofollow" target="_blank">sparsediff</a> v0.4.0: Implements bindings for the <code>SparseDiffEngine</code> <code>C</code> library, the sparse Jacobian and Hessian differentiation backend used by <code>CVXPY</code> for its Disciplined Nonlinear Programming extension. Provides low-level routines for building nonlinear expression graphs and evaluating sparse derivatives, intended as a backend for higher-level modeling layers such as <code>CVXR</code>. This is the <code>R</code> analog of the <code>sparsediffpy</code> <code>Python</code> package and wraps the same <code>C</code> library. See the <a href="https://cran.r-project.org/web/packages/sparsediff/vignettes/sparsediff.html" rel="nofollow" target="_blank">vignette</a>.</p>
<p><a href="https://cran.r-project.org/package=StochSimR" rel="nofollow" target="_blank">StochSimR</a> v1.1.0: Implements a modular simulation engine for a wide range of stochastic processes. Provides exact and approximate simulation methods for Poisson processes, Brownian motion, discrete- and continuous-time Markov chains, birth-death processes, the Yule pure-birth process, infinitesimal generator matrix utilities, Markovian queuing systems with exact steady-state statistics, Levy processes, Merton jump-diffusion models, Hawkes self-exciting processes, geometric Brownian motion, and Ornstein-Uhlenbeck mean-reverting diffusions. See <a href="https://link.springer.com/book/10.1007/978-0-387-21617-1" rel="nofollow" target="_blank">Glasserman (2003)</a> and <a href="https://link.springer.com/book/10.1007/978-0-387-69033-9" rel="nofollow" target="_blank">Asmussen &#038; Glynn (2007)</a> for background and the <a href="https://cran.r-project.org/web/packages/StochSimR/vignettes/introduction.html" rel="nofollow" target="_blank">vignette</a> for an introduction.</p>
<p><a href="https://i1.wp.com/rworks.dev/posts/june-2026-top-40-new-cran-packages/StochSimR.png?ssl=1" class="lightbox" data-gallery="quarto-lightbox-gallery-4" rel="nofollow" target="_blank"><img src="https://i1.wp.com/rworks.dev/posts/june-2026-top-40-new-cran-packages/StochSimR.png?w=578&#038;ssl=1" class="img-fluid" alt="Plot of simulated Brownian Motion" data-recalc-dims="1"></a></p>
<p><a href="https://cran.r-project.org/web/packages/Uno/vignettes/Uno.html" rel="nofollow" target="_blank">Uno</a> v2.7.4: Provides bindings to <a href="https://unosolver.readthedocs.io/en/latest/" rel="nofollow" target="_blank">Uno</a> (Unifying Nonlinear Optimization), a <code>C++</code> solver for smooth nonlinearly constrained optimization that unifies Lagrange-Newton methods, including sequential quadratic programming and interior-point methods, by decomposing them into interacting building blocks (constraint-relaxation, inequality-handling, Hessian, and globalization strategies). The framework is described in <a href="https://arxiv.org/abs/2406.13454" rel="nofollow" target="_blank">Vanaret and Leyffer (2024)</a>. See the <a href="https://cran.r-project.org/web/packages/Uno/vignettes/Uno.html" rel="nofollow" target="_blank">vignette</a> for an example.</p>
</section>
<section id="ecology" class="level3">
<h3 class="anchored" data-anchor-id="ecology">Ecology</h3>
<p><a href="https://cran.r-project.org/package=BayesFR" rel="nofollow" target="_blank">BayesFR</a> v1.0.1: Enables fitting various functional response models for single- and multi-prey experiments by providing nonlinear prediction functions for <code>brms</code> and provides a framework for easily testing hypotheses on trophic interactions. Models can incorporate covariates such as temperature gradients, experimental treatment variables, or random effects that account for grouping in experimental units. See <a href="https://besjournals.onlinelibrary.wiley.com/doi/10.1111/2041-210X.14372" rel="nofollow" target="_blank">Rosenbaum and Rall (2018)</a> and <a href="https://besjournals.onlinelibrary.wiley.com/doi/10.1111/2041-210X.13039" rel="nofollow" target="_blank">Rosenbaum et al. (2024)</a> for background and the <a href="https://cran.r-project.org/web/packages/BayesFR/vignettes/bayesfr-intro.html" rel="nofollow" target="_blank">vignette</a> to get started.</p>
<p><a href="https://i2.wp.com/rworks.dev/posts/june-2026-top-40-new-cran-packages/BayesFR.png?ssl=1" class="lightbox" data-gallery="quarto-lightbox-gallery-5" rel="nofollow" target="_blank"><img src="https://i2.wp.com/rworks.dev/posts/june-2026-top-40-new-cran-packages/BayesFR.png?w=578&#038;ssl=1" class="img-fluid" alt="Plot of number of eaten prey against prey abundance " data-recalc-dims="1"></a></p>
<p><a href="https://cran.r-project.org/package=nicheR" rel="nofollow" target="_blank">nicheR</a> v0.1.0: Provides tools to construct and define virtual ecological niches using ellipsoid geometries. It enables the identification and extraction of suitable environmental areas, simulation of species occurrence points with various sampling strategies, and visualization of niche boundaries and simulated occurrences in both environmental and geographic space. See <a href="https://onlinelibrary.wiley.com/doi/10.1111/j.1365-2699.2008.02041.x" rel="nofollow" target="_blank">Etherington et al. (2009)</a> and <a href="https://nsojournals.onlinelibrary.wiley.com/doi/10.1111/ecog.01961" rel="nofollow" target="_blank">Qiao et al. (2015)</a> for background. There are six vignettes, including <a href="https://cran.r-project.org/web/packages/nicheR/vignettes/plotting_vignette.html" rel="nofollow" target="_blank">Visualizing ellipsoids in environmental space</a> and <a href="https://cran.r-project.org/web/packages/nicheR/vignettes/virtual_communities.html" rel="nofollow" target="_blank">Virtual community simulation</a>.</p>
<p><a href="https://i1.wp.com/rworks.dev/posts/june-2026-top-40-new-cran-packages/nicheR.png?ssl=1" class="lightbox" data-gallery="quarto-lightbox-gallery-6" rel="nofollow" target="_blank"><img src="https://i1.wp.com/rworks.dev/posts/june-2026-top-40-new-cran-packages/nicheR.png?w=578&#038;ssl=1" class="img-fluid" alt="Stability Plot" data-recalc-dims="1"></a></p>
<p><a href="https://cran.r-project.org/package=spacc" rel="nofollow" target="_blank">spacc</a> v0.8.3: Implements <code>kNN</code> and <code>kNCN</code> sampling methods with a <code>C++</code> backend to compute spatial species accumulation curves. Supports Hill numbers, beta diversity partitioning, coverage-based rarefaction and extrapolation, phylogenetic diversity (Faith’s PD, mean pairwise distance, mean nearest taxon distance), functional diversity accumulation, diversity-area relationships, endemism-area curves, sampling-effort correction and fragmentation analysis, and species-area relationship models based on extreme value theory. See <a href="https://esajournals.onlinelibrary.wiley.com/doi/10.1890/13-0133.1" rel="nofollow" target="_blank">Chao et al. (2014)</a> and <a href="https://onlinelibrary.wiley.com/doi/10.1111/j.1466-8238.2009.00490.x" rel="nofollow" target="_blank">Baselga (2010)</a> for background. There are seven vignettes, including <a href="https://cran.r-project.org/web/packages/spacc/vignettes/quickstart.html" rel="nofollow" target="_blank">Getting Started</a> and <a href="https://cran.r-project.org/web/packages/spacc/vignettes/diversity.html" rel="nofollow" target="_blank">Diversity Accumulation</a>.</p>
<p><a href="https://rworks.dev/posts/june-2026-top-40-new-cran-packages/spacc.svg" class="lightbox" data-gallery="quarto-lightbox-gallery-7" rel="nofollow" target="_blank"><img src="https://rworks.dev/posts/june-2026-top-40-new-cran-packages/spacc.svg" class="img-fluid" alt="Plot of saptial Hill number accumulation"></a></p>
<p><a href="https://cran.r-project.org/package=TemporalModelR" rel="nofollow" target="_blank">TemporalModelR</a> v0.3.0: Provides functions to assist with three major steps for building temporally-explicit ecological niche and species distribution models: (i) preprocessing species and environmental data, (ii) building a niche model and generating temporally-explicit predictions, and (iii) model postprocessing to explore spatiotemporal trends. See <a href="https://besjournals.onlinelibrary.wiley.com/doi/10.1111/2041-210X.13564" rel="nofollow" target="_blank">Ingenloff and Peterson (2021</a> and <a href="https://nsojournals.onlinelibrary.wiley.com/doi/10.1111/ecog.03187" rel="nofollow" target="_blank">Blonder (2018)</a> for the methodological and theoretical foundations. Modeling with a <a href="https://cran.r-project.org/web/packages/TemporalModelR/vignettes/V3a_GLM.html" rel="nofollow" target="_blank">GLM</a> and <a href="https://cran.r-project.org/web/packages/TemporalModelR/vignettes/V3c_RF.html" rel="nofollow" target="_blank">Modeling with a Random Forest</a>.</p>
<p><a href="https://i2.wp.com/rworks.dev/posts/june-2026-top-40-new-cran-packages/Temporal.png?ssl=1" class="lightbox" data-gallery="quarto-lightbox-gallery-8" rel="nofollow" target="_blank"><img src="https://i2.wp.com/rworks.dev/posts/june-2026-top-40-new-cran-packages/Temporal.png?w=578&#038;ssl=1" class="img-fluid" alt="Random Forest Marginal Prediction Curves" data-recalc-dims="1"></a></p>
</section>
<section id="epidemiology" class="level3">
<h3 class="anchored" data-anchor-id="epidemiology">Epidemiology</h3>
<p><a href="https://cran.r-project.org/package=SmokingHistoryGenerator" rel="nofollow" target="_blank">SmokingHistoryGenerator</a> v7.0.0: Implements an interface to the Cancer Intervention and Surveillance Modeling Network (<a href="https://cisnet.cancer.gov/resources/model-registry/lung-models/" rel="nofollow" target="_blank">CISNET</a>) Smoking History Generator microsimulation engine, which synthesizes individual smoking histories (initiation, cessation, intensity) and ages at death from calibrated initiation, cessation, cigarettes-per-day, and mortality tables. See <a href="https://onlinelibrary.wiley.com/doi/10.1111/j.1539-6924.2011.01775.x" rel="nofollow" target="_blank">Jeon et al. (2012)</a> for background and look <a href="https://github.com/NCI-CISNET/shg-r" rel="nofollow" target="_blank">here</a> to get started.</p>
</section>
<section id="finance" class="level3">
<h3 class="anchored" data-anchor-id="finance">Finance</h3>
<p><a href="https://cran.r-project.org/package=CamelRatiosIndex" rel="nofollow" target="_blank">CamelRatiosIndex</a> v1.0.0: Computes a composite year-on-year index for bank performance assessment using the CAMEL framework (Capital Adequacy, Asset Quality, Management Efficiency, Earnings, Liquidity). The multivariate weighting scheme employs factor analysis with robust covariance estimation to derive communality-based weights from the correlation matrix of CAMEL ratios. Provides functions for index computation, visualization, and comparison across banks and time periods. The methodology is described in <a href="https://stm.bookpi.org/CMWCPIAAMR/article/view/10917" rel="nofollow" target="_blank">Ayimah et al. (2023a)</a> and <a href="https://stm.bookpi.org/CMWCPIAAMR/issue/view/1083" rel="nofollow" target="_blank">Ayimah et al. (2023b)</a>. See the <a href="https://cran.r-project.org/web/packages/CamelRatiosIndex/vignettes/introduction.html" rel="nofollow" target="_blank">vignette</a> for an introduction.</p>
<p><a href="https://i0.wp.com/rworks.dev/posts/june-2026-top-40-new-cran-packages/Camel.png?ssl=1" class="lightbox" data-gallery="quarto-lightbox-gallery-9" rel="nofollow" target="_blank"><img src="https://i0.wp.com/rworks.dev/posts/june-2026-top-40-new-cran-packages/Camel.png?w=578&#038;ssl=1" class="img-fluid" alt="Plot of CAMEL index" data-recalc-dims="1"></a></p>
<p><a href="https://cran.r-project.org/package=JumpDiffSim" rel="nofollow" target="_blank">JumpDiffSim</a> v0.1.0: Implements the <a href="https://www.sciencedirect.com/science/article/abs/pii/0304405X76900222" rel="nofollow" target="_blank">Merton (1976)</a> and <a href="https://pubsonline.informs.org/doi/10.1287/mnsc.48.8.1086.166" rel="nofollow" target="_blank">Kou (2002)</a> jump-diffusion models through a unified S4 object-oriented interface. Provides exact compound-Poisson asset price simulation, maximum likelihood parameter estimation with Hessian-based standard errors, Wald-type confidence intervals, European option pricing via the Merton analytic series expansion, and publication-quality diagnostic plots. All functionality operates entirely offline without market data dependencies. See the <a href="https://cran.r-project.org/web/packages/JumpDiffSim/vignettes/JumpDiffSim-intro.html" rel="nofollow" target="_blank">vignette</a>.</p>
<p><a href="https://i2.wp.com/rworks.dev/posts/june-2026-top-40-new-cran-packages/Jump.png?ssl=1" class="lightbox" data-gallery="quarto-lightbox-gallery-10" rel="nofollow" target="_blank"><img src="https://i2.wp.com/rworks.dev/posts/june-2026-top-40-new-cran-packages/Jump.png?w=578&#038;ssl=1" class="img-fluid" alt="Plot of simulated asset price" data-recalc-dims="1"></a></p>
</section>
<section id="functional-data-analysis" class="level3">
<h3 class="anchored" data-anchor-id="functional-data-analysis">Functional Data Analysis</h3>
<p><a href="https://cran.r-project.org/package=fda.vi" rel="nofollow" target="_blank">fda.vi</a> v1.0.0: Implements a variational Expectation-Maximization algorithm for smoothing one or multiple functional observations via basis function selection. The algorithm estimates all model parameters simultaneously and automatically, while accounting for within-curve correlation to provide a flexible and computationally efficient framework for smoothing correlated functional data. See <a href="https://arxiv.org/abs/2405.20758" rel="nofollow" target="_blank">da Cruz et al. (2024)</a> for a description of the algorithm and the <a href="https://cran.r-project.org/web/packages/fda.vi/vignettes/introduction.html" rel="nofollow" target="_blank">vignette</a> for examples.</p>
<p><a href="https://i2.wp.com/rworks.dev/posts/june-2026-top-40-new-cran-packages/fdavi.png?ssl=1" class="lightbox" data-gallery="quarto-lightbox-gallery-11" rel="nofollow" target="_blank"><img src="https://i2.wp.com/rworks.dev/posts/june-2026-top-40-new-cran-packages/fdavi.png?w=578&#038;ssl=1" class="img-fluid" alt="Plot of VEM curve" data-recalc-dims="1"></a></p>
</section>
<section id="machine-learning" class="level3">
<h3 class="anchored" data-anchor-id="machine-learning">Machine Learning</h3>
<p><a href="https://cran.r-project.org/package=svmodt" rel="nofollow" target="_blank">svmodt</a> v0.1.0: Implements Support Vector Machine Oblique Decision Trees. Recursively builds classification trees using linear Support Vector Machine hyperplanes at each node instead of axis-parallel splits, creating oblique decision boundaries. Features include multiple feature selection methods, dynamic feature subset strategies, class weight support for imbalanced datasets, pruning, and feature penalization. See the <a href="https://cran.r-project.org/web/packages/svmodt/vignettes/introduction.html" rel="nofollow" target="_blank">vignette</a>.</p>
<p><a href="https://i2.wp.com/rworks.dev/posts/june-2026-top-40-new-cran-packages/svmodt.png?ssl=1" class="lightbox" data-gallery="quarto-lightbox-gallery-12" rel="nofollow" target="_blank"><img src="https://i2.wp.com/rworks.dev/posts/june-2026-top-40-new-cran-packages/svmodt.png?w=578&#038;ssl=1" class="img-fluid" alt="Scatterplot showing SVM decision boundary" data-recalc-dims="1"></a></p>
<p><a href="https://cran.r-project.org/package=yaap" rel="nofollow" target="_blank">yaap</a> v1.0.0: Fits archetypal analysis models, including Euclidean, probabilistic, kernel, and directional variants. Methods include classical archetypal analysis from <a href="https://www.tandfonline.com/doi/abs/10.1080/00401706.1994.10485840" rel="nofollow" target="_blank">Cutler and Breiman (1994)</a>, PCHA and kernel variants from <a href="https://www.sciencedirect.com/science/article/abs/pii/S0925231211006060" rel="nofollow" target="_blank">Mørup and Hansen (2012)</a>, probabilistic archetypal analysis from <a href="https://link.springer.com/article/10.1007/s10994-015-5498-8" rel="nofollow" target="_blank">Seth and Eugster (2016</a>, directional archetypal analysis from <a href="https://www.frontiersin.org/journals/neuroscience/articles/10.3389/fnins.2022.911034/full" rel="nofollow" target="_blank">Olsen et al. (2022)</a>, AA++ initialization from <a href="https://proceedings.neurips.cc/paper_files/paper/2019/file/7f278ad602c7f47aa76d1bfc90f20263-Paper.pdf" rel="nofollow" target="_blank">Mair and Sjölund (2023)</a>, coreset-style initialization from <a href="https://proceedings.neurips.cc/paper_files/paper/2019/file/7f278ad602c7f47aa76d1bfc90f20263-Paper.pdf" rel="nofollow" target="_blank">Mair and Brefeld (2019)</a>, and adapted AIC from <a href="https://ieeexplore.ieee.org/document/8015385" rel="nofollow" target="_blank">Suleman (2017)</a>. There are four vignettes including an <a href="https://cran.r-project.org/web/packages/yaap/vignettes/introduction.html" rel="nofollow" target="_blank">Introduction</a> and <a href="https://cran.r-project.org/web/packages/yaap/vignettes/tidymodels.html" rel="nofollow" target="_blank">Tidymodels Workflows</a>.</p>
<p><a href="https://i2.wp.com/rworks.dev/posts/june-2026-top-40-new-cran-packages/yaap.png?ssl=1" class="lightbox" data-gallery="quarto-lightbox-gallery-13" rel="nofollow" target="_blank"><img src="https://i2.wp.com/rworks.dev/posts/june-2026-top-40-new-cran-packages/yaap.png?w=578&#038;ssl=1" class="img-fluid" alt="Plot of archetype positions in feature space" data-recalc-dims="1"></a></p>
</section>
<section id="medical-statistics" class="level3">
<h3 class="anchored" data-anchor-id="medical-statistics">Medical Statistics</h3>
<p><a href="https://cran.r-project.org/package=BayesTSM" rel="nofollow" target="_blank">BayesTSM</a> v1.0.1: In screening programs, individuals are usually followed up and tested (screened) for the development of a disease. The target disease often develops progressively in stages; for example, healthy (state 1), pre-state disease (state 2), and the disease state (state 3). When the pre-state disease is found during screening, an intervention may prevent disease progression.<code>BayesTSM</code> functions estimate a progressive three-state model with censoring due to intervention using Bayesian estimation methods, as described in <a href="https://projecteuclid.org/journals/annals-of-applied-statistics/volume-17/issue-2/A-Bayesian-accelerated-failure-time-model-for-interval-censored-three/10.1214/22-AOAS1669.full" rel="nofollow" target="_blank">Klausch et al. (2023)</a>. See the <a href="https://cran.r-project.org/web/packages/BayesTSM/vignettes/bayestsm-userguide.html" rel="nofollow" target="_blank">vignette</a>.</p>
<p><a href="https://i0.wp.com/rworks.dev/posts/june-2026-top-40-new-cran-packages/BayesTSM.png?ssl=1" class="lightbox" data-gallery="quarto-lightbox-gallery-14" rel="nofollow" target="_blank"><img src="https://i0.wp.com/rworks.dev/posts/june-2026-top-40-new-cran-packages/BayesTSM.png?w=578&#038;ssl=1" class="img-fluid" alt="Plot of posterior predictive priors" data-recalc-dims="1"></a></p>
<p><a href="https://cran.r-project.org/package=bayprior" rel="nofollow" target="_blank">bayprior</a> v0.2.12: Provides a toolkit for constructing, validating, and justifying Bayesian priors in clinical trial settings. Implements expert elicitation via quantile matching, the roulette method, and moment matching, linear and logarithmic expert pooling, and prior-data conflict diagnostics. Includes a fully modular <code>Shiny</code> application for interactive use. See <a href="https://www.jstor.org/stable/2982063?origin=crossref" rel="nofollow" target="_blank">Box (1980)</a> and <a href="https://shelf.sites.sheffield.ac.uk/" rel="nofollow" target="_blank">Oakley and O’Hagan (2010)</a> for background. There are six vignettes, including <a href="https://cran.r-project.org/web/packages/bayprior/vignettes/bayprior-introduction.html" rel="nofollow" target="_blank">Introduction</a> and <a href="https://cran.r-project.org/web/packages/bayprior/vignettes/robust-priors.html" rel="nofollow" target="_blank">Robust, Sceptical, and Power Priors</a>.</p>
<p><a href="https://i2.wp.com/rworks.dev/posts/june-2026-top-40-new-cran-packages/bayprior.png?ssl=1" class="lightbox" data-gallery="quarto-lightbox-gallery-15" rel="nofollow" target="_blank"><img src="https://i2.wp.com/rworks.dev/posts/june-2026-top-40-new-cran-packages/bayprior.png?w=578&#038;ssl=1" class="img-fluid" alt="Plot of Bayes factor vs power prior weight" data-recalc-dims="1"></a></p>
</section>
</div><div class="column" style="width:10%;">

</div><div class="column" style="width:45%;">
<section id="networks" class="level3">
<h3 class="anchored" data-anchor-id="networks">Networks</h3>
<p><a href="https://cran.r-project.org/package=netify" rel="nofollow" target="_blank">netify</a> v1.5.3: Provides functions to build, validate, analyze, and visualize network data from dyadic, event, matrix, <code>igraph</code>, and <code>network</code> inputs. Supports cross-sectional, longitudinal, bipartite, and multi-layer networks, with conversion helpers for common modeling workflows and plotting utilities for exploratory analysis. Network methods are described in <a href="https://www.amazon.com/Social-Network-Analysis-Applications-Structural/dp/0521387078" rel="nofollow" target="_blank">Wasserman and Faust (1994)</a>, <a href="https://www.cambridge.org/highereducation/books/inferential-network-analysis/A7797D36A24647AA1F900CE7EF694C7E#overview" rel="nofollow" target="_blank">Cranmer et al. (2021)</a>, and <a href="https://www.cambridge.org/core/journals/political-science-research-and-methods/article/abs/taking-dyads-seriously/823804FA29B988156A574C3F44280317" rel="nofollow" target="_blank">Minhas et al. (2022)</a>. There are four vignettes, including <a href="https://cran.r-project.org/web/packages/netify/vignettes/quickstart_inference.html" rel="nofollow" target="_blank">Quickstart</a> and <a href="https://cran.r-project.org/web/packages/netify/vignettes/internals.html" rel="nofollow" target="_blank">Internals</a>.</p>
<p><a href="https://i2.wp.com/rworks.dev/posts/june-2026-top-40-new-cran-packages/netify.png?ssl=1" class="lightbox" data-gallery="quarto-lightbox-gallery-16" rel="nofollow" target="_blank"><img src="https://i2.wp.com/rworks.dev/posts/june-2026-top-40-new-cran-packages/netify.png?w=578&#038;ssl=1" class="img-fluid" alt="Plots of network over time" data-recalc-dims="1"></a></p>
</section>
<section id="pharmacokinetics" class="level3">
<h3 class="anchored" data-anchor-id="pharmacokinetics">Pharmacokinetics</h3>
<p><a href="https://cran.r-project.org/package=admixr2" rel="nofollow" target="_blank">admixr2</a> v0.2.0: Provides functions to fit pharmacokinetic/pharmacodynamic (PK/PD) models to aggregate-level data (mean vector and covariance matrix per study) rather than individual-level data. Integrates with the <code>nlmixr2</code>/<code>rxode2</code> ecosystem via four estimation methods: a First-Order analytical estimator, a Monte Carlo estimator, a Gauss-Hermite quadrature estimator, and an Iterative Reweighting Monte Carlo estimator. Methods are based on <a href="https://link.springer.com/article/10.1007/s10928-021-09760-1" rel="nofollow" target="_blank">Välitalo (2021)</a> software described in van de <a href="https://link.springer.com/article/10.1007/s10928-025-10011-w" rel="nofollow" target="_blank">Beek et al. (2025)</a>. See the <a href="https://cran.r-project.org/web/packages/admixr2/vignettes/admixr2.html" rel="nofollow" target="_blank">vignette</a> to get started.</p>
<p><a href="https://i0.wp.com/rworks.dev/posts/june-2026-top-40-new-cran-packages/admixr2.png?ssl=1" class="lightbox" data-gallery="quarto-lightbox-gallery-17" rel="nofollow" target="_blank"><img src="https://i0.wp.com/rworks.dev/posts/june-2026-top-40-new-cran-packages/admixr2.png?w=578&#038;ssl=1" class="img-fluid" alt="Study diagnostic plots" data-recalc-dims="1"></a></p>
</section>
<section id="probability" class="level3">
<h3 class="anchored" data-anchor-id="probability">Probability</h3>
<p><a href="https://cran.r-project.org/package=GLBFP" rel="nofollow" target="_blank">GLBFP</a> v0.5.2: Implements nonparametric density estimation with Averaged Shifted Histogram, Linear Blend Frequency Polygon, and General Linear Blend Frequency Polygon estimators and provides pointwise and grid-based estimation workflows, sparse-prefix grid-count computation, plotting helpers, and plug-in bandwidth selection. Methodological background follows <a href="https://onlinelibrary.wiley.com/doi/book/10.1002/9780470316849" rel="nofollow" target="_blank">Scott (1992)</a>, <a href="https://www.tandfonline.com/doi/abs/10.1080/01621459.1985.10477163" rel="nofollow" target="_blank">Terrell and Scott (1985)</a>, and <a href="https://link.springer.com/article/10.1007/s10463-023-00883-5" rel="nofollow" target="_blank">Carbon and Duchesne (2024)</a>. There are nine vignettes, including <a href="https://cran.r-project.org/web/packages/GLBFP/vignettes/getting-started.html" rel="nofollow" target="_blank">Getting started</a> and <a href="https://cran.r-project.org/web/packages/GLBFP/vignettes/GLBFP_introduction.html" rel="nofollow" target="_blank">Package overview</a>.</p>
<p><a href="https://i2.wp.com/rworks.dev/posts/june-2026-top-40-new-cran-packages/GLBFP.png?ssl=1" class="lightbox" data-gallery="quarto-lightbox-gallery-18" rel="nofollow" target="_blank"><img src="https://i2.wp.com/rworks.dev/posts/june-2026-top-40-new-cran-packages/GLBFP.png?w=578&#038;ssl=1" class="img-fluid" alt="Density plot" data-recalc-dims="1"></a></p>
</section>
<section id="programming" class="level3">
<h3 class="anchored" data-anchor-id="programming">Programming</h3>
<p><a href="https://cran.r-project.org/package=rsgl" rel="nofollow" target="_blank">rsgl</a> v0.1.0: Generates plots from a database connection and an <code>SGL</code> statement. <code>SGL</code> is a graphics language designed to look and feel like <code>SQL</code> and is especially useful for those familiar with <code>SQL</code> who want to specify plots in a similar manner. The <code>SGL</code> language is described in <a href="https://arxiv.org/abs/2505.14690" rel="nofollow" target="_blank">Chapman (2025)</a>. See the vignettes <a href="https://cran.r-project.org/web/packages/rsgl/vignettes/rsgl.html" rel="nofollow" target="_blank">Get started</a> and <a href="https://cran.r-project.org/web/packages/rsgl/vignettes/example-gallery.html" rel="nofollow" target="_blank">Example gallery</a>.</p>
<p><a href="https://i1.wp.com/rworks.dev/posts/june-2026-top-40-new-cran-packages/rsgl.png?ssl=1" class="lightbox" data-gallery="quarto-lightbox-gallery-19" rel="nofollow" target="_blank"><img src="https://i1.wp.com/rworks.dev/posts/june-2026-top-40-new-cran-packages/rsgl.png?w=578&#038;ssl=1" class="img-fluid" alt="Visualization of age as an angle " data-recalc-dims="1"></a></p>
</section>
<section id="psychometrics" class="level3">
<h3 class="anchored" data-anchor-id="psychometrics">Psychometrics</h3>
<p><a href="https://cran.r-project.org/package=easyRasch2" rel="nofollow" target="_blank">easyRasch2</a> v1.1.0: Streamlines reproducible Rasch measurement theory analyses for ordinal item-response data, combining estimation routines from <code>eRm</code>, <code>psychotool</code>, <code>mirt</code>, <code>iarm</code>, and <code>lavaan</code> with consistent diagnostic, plotting, and reporting layers. Covers the four basic psychometric criteria summarized by <a href="https://onlinelibrary.wiley.com/doi/10.1111/sms.13908" rel="nofollow" target="_blank">Christensen et al. (2021)</a>: unidimensionality, local independence, ordered response category thresholds, and invariance across subgroups, together with item fit, targeting, reliability, category functioning, and descriptive item-response plots. A distinguishing feature is the use of simulation-based critical values to replace rule-of-thumb cutoffs. See the <a href="https://cran.r-project.org/web/packages/easyRasch2/vignettes/easyRasch2.html" rel="nofollow" target="_blank">vignette</a>.</p>
<p><a href="https://i0.wp.com/rworks.dev/posts/june-2026-top-40-new-cran-packages/easyRasch2.png?ssl=1" class="lightbox" data-gallery="quarto-lightbox-gallery-20" rel="nofollow" target="_blank"><img src="https://i0.wp.com/rworks.dev/posts/june-2026-top-40-new-cran-packages/easyRasch2.png?w=578&#038;ssl=1" class="img-fluid" alt="Plot of latent trait probabilities" data-recalc-dims="1"></a></p>
</section>
<section id="risk-analysis" class="level3">
<h3 class="anchored" data-anchor-id="risk-analysis">Risk Analysis</h3>
<p><a href="https://cran.r-project.org/package=riskutility" rel="nofollow" target="_blank">riskutility</a> v0.1.0: Provides comprehensive methods to measure disclosure risk and data utility for anonymized and synthetic data. Implements attribution-based risk metrics including Correct Attribution Probability, Targeted CAP, Within Equivalence Class Attribution Probability, and Risk of Attribute Prediction-Induced Disclosure. Also provides distance-based privacy metrics such as Distance to Closest Record, Nearest Neighbor Distance Ratio, and Identical Match Share. Utility assessment includes propensity score analysis, distribution comparisons, and various statistical tests. Methods are based on <a href="https://link.springer.com/chapter/10.1007/978-3-319-99771-1_9" rel="nofollow" target="_blank">Taub et al. (2018)</a>. See the <a href="https://cran.r-project.org/web/packages/riskutility/vignettes/riskutility.html" rel="nofollow" target="_blank">vignette</a>.</p>
<p><a href="https://i1.wp.com/rworks.dev/posts/june-2026-top-40-new-cran-packages/riskutility.png?ssl=1" class="lightbox" data-gallery="quarto-lightbox-gallery-21" rel="nofollow" target="_blank"><img src="https://i1.wp.com/rworks.dev/posts/june-2026-top-40-new-cran-packages/riskutility.png?w=578&#038;ssl=1" class="img-fluid" alt="histogram of distance to cloest record" data-recalc-dims="1"></a></p>
</section>
<section id="statistics" class="level3">
<h3 class="anchored" data-anchor-id="statistics">Statistics</h3>
<p><a href="https://cran.r-project.org/package=bayesqm" rel="nofollow" target="_blank">bayesqm</a> v0.1.0: Provides a Bayesian factor-analytic framework for Q methodology. Fits a low-rank factor model to Q-sort data with a Student-t likelihood and a hierarchical normal prior on loadings, samples the posterior with <code>Stan</code>, resolves rotational ambiguity via the MatchAlign post-processing of <a href="https://projecteuclid.org/journals/bayesian-analysis/volume--1/issue--1/Efficiently-Resolving-Rotational-Ambiguity-in-Bayesian-Matrix-Sampling-with-Matching/10.1214/25-BA1544.full" rel="nofollow" target="_blank">Poworoznek et al. (2025)</a> and returns posterior summaries including credible intervals for loadings and factor scores, probabilistic dominant-factor membership, distinguishing and consensus statements, and PSIS-LOO-based factor enumeration following <a href="https://link.springer.com/article/10.1007/s11222-016-9696-4" rel="nofollow" target="_blank">Vehtari et al. (2017)</a> with the <a href="https://projecteuclid.org/journals/bayesian-analysis/volume--1/issue--1/Uncertainty-in-Bayesian-Leave-One-Out-Cross-Validation-Based-Model/10.1214/25-BA1569.full" rel="nofollow" target="_blank">Sivula et al. (2025)</a> parsimony rule. See the <a href="https://cran.r-project.org/web/packages/bayesqm/vignettes/bayesqm-intro.html" rel="nofollow" target="_blank">vignette</a> to get started.</p>
<p><a href="https://i0.wp.com/rworks.dev/posts/june-2026-top-40-new-cran-packages/bayesqm.png?ssl=1" class="lightbox" data-gallery="quarto-lightbox-gallery-22" rel="nofollow" target="_blank"><img src="https://i0.wp.com/rworks.dev/posts/june-2026-top-40-new-cran-packages/bayesqm.png?w=578&#038;ssl=1" class="img-fluid" alt="Plot of ELPD peak vs. K" data-recalc-dims="1"></a></p>
<p><a href="https://cran.r-project.org/package=depthR" rel="nofollow" target="_blank">depthR</a> v0.1.8: Provides efficient implementations of multivariate statistical depth functions in arbitrary dimension. Implements Mahalanobis depth, Tukey halfspace depth, Liu simplicial depth, projection depth, spatial depth, depth-based medians, central regions, outlier detection, and depth-depth plots. <code>C++</code> backends via <code>Rcpp</code> and <code>RcppEigen</code> ensure performance at large n and d. See <a href="https://projecteuclid.org/journals/annals-of-statistics/volume-18/issue-1/On-a-Notion-of-Data-Depth-Based-on-Random-Simplices/10.1214/aos/1176347507.full" rel="nofollow" target="_blank">Liu (1990)</a>, <a href="https://projecteuclid.org/journals/annals-of-statistics/volume-28/issue-2/General-notions-of-statistical-depth-function/10.1214/aos/1016218226.full" rel="nofollow" target="_blank">Serfling and Zuo (2000)</a>, and <a href="https://www.pnas.org/doi/abs/10.1073/pnas.97.4.1423" rel="nofollow" target="_blank">Vardi and Zhang (2000)</a> for background, and the <a href="https://cran.r-project.org/web/packages/depthR/vignettes/depthR.html" rel="nofollow" target="_blank">vignette</a> for an introduction.</p>
<p><a href="https://i1.wp.com/rworks.dev/posts/june-2026-top-40-new-cran-packages/depthR.png?ssl=1" class="lightbox" data-gallery="quarto-lightbox-gallery-23" rel="nofollow" target="_blank"><img src="https://i1.wp.com/rworks.dev/posts/june-2026-top-40-new-cran-packages/depthR.png?w=578&#038;ssl=1" class="img-fluid" alt="The depth-depth plot is the multivariate analog of the QQ-plot" data-recalc-dims="1"></a></p>
<p><a href="https://cran.r-project.org/package=dppca" rel="nofollow" target="_blank">dppca</a> v0.1.0: Provides tools for differentially private principal component analysis visualization and includes functions for estimating private principal component directions, constructing private scree and proportion of variance explained summaries, and visualizing two-dimensional PCA score summaries using additive and sparse histogram mechanisms. Group-wise score visualizations and an interactive <code>shiny</code> app are also provided. See <a href="https://onlinelibrary.wiley.com/doi/10.1002/sam.70053" rel="nofollow" target="_blank">Kim and Jung (2025)</a>, <a href="https://www.emerald.com/fttcs/article-abstract/9/3-4/211/1332491/The-Algorithmic-Foundations-of-Differential?redirectedFrom=fulltext" rel="nofollow" target="_blank">Dwork and Roth (2014)</a> and <a href="https://arxiv.org/abs/2501.14095" rel="nofollow" target="_blank">Ramsay and Spicker (2025)</a> for background. There are four vignettes, including <a href="https://cran.r-project.org/web/packages/dppca/vignettes/algorithms.html" rel="nofollow" target="_blank">Algorithms</a> and <a href="https://cran.r-project.org/web/packages/dppca/vignettes/pc_direction.html" rel="nofollow" target="_blank">PC Directions in dppca</a>.</p>
<p><a href="https://cran.r-project.org/package=ernest" rel="nofollow" target="_blank">ernest</a> v1.2.5: Bayesian evidence estimation and posterior inference with the nested sampling algorithm, described in <a href="https://projecteuclid.org/journals/bayesian-analysis/volume-1/issue-4/Nested-sampling-for-general-Bayesian-computation/10.1214/06-BA127.full" rel="nofollow" target="_blank">Skilling (2006)</a> and <a href="https://projecteuclid.org/journals/statistics-surveys/volume-17/issue-none/Nested-sampling-methods/10.1214/23-SS144.full" rel="nofollow" target="_blank">Buchner (2023)</a>, along with S3 methods for simulating uncertainty and creating visualizations. See the vignettes <a href="https://cran.r-project.org/web/packages/ernest/vignettes/nested-sampling-with-ernest.html" rel="nofollow" target="_blank">Nested Sampling</a> and <a href="https://cran.r-project.org/web/packages/ernest/vignettes/more-ernest-runs.html" rel="nofollow" target="_blank">More Examples</a>.</p>
<p><a href="https://i2.wp.com/rworks.dev/posts/june-2026-top-40-new-cran-packages/ernest.png?ssl=1" class="lightbox" data-gallery="quarto-lightbox-gallery-24" rel="nofollow" target="_blank"><img src="https://i2.wp.com/rworks.dev/posts/june-2026-top-40-new-cran-packages/ernest.png?w=578&#038;ssl=1" class="img-fluid" alt="Plot showing ability to properly integrate across multimodal likelihood surfaces. " data-recalc-dims="1"></a></p>
<p><a href="https://cran.r-project.org/package=gkrreg" rel="nofollow" target="_blank">gkrreg</a> v0.4.0: Implements the Gaussian Kernel Robust Regression method proposed by <a href="https://www.sciencedirect.com/science/article/abs/pii/S0925231216315508" rel="nofollow" target="_blank">De Carvalho, Lima Neto and Ferreira (2017)</a>, which re-weights observations iteratively using the Gaussian kernel so that poorly-fitted observations receive small weights, yielding resistance to Y-space outliers, X-space outliers and leverage points. Provides three estimators for the kernel width hyper-parameter: Caputo, pairwise median, and residual variance. Inference is accomplished via an analytic sandwich variance estimator or via bootstrap. Six real datasets from the robust regression literature are included to facilitate reproducible comparisons. See the <a href="https://cran.r-project.org/web/packages/gkrreg/vignettes/introduction.html" rel="nofollow" target="_blank">vignette</a>.</p>
<p><a href="https://i2.wp.com/rworks.dev/posts/june-2026-top-40-new-cran-packages/gkrreg.png?ssl=1" class="lightbox" data-gallery="quarto-lightbox-gallery-25" rel="nofollow" target="_blank"><img src="https://i2.wp.com/rworks.dev/posts/june-2026-top-40-new-cran-packages/gkrreg.png?w=578&#038;ssl=1" class="img-fluid" alt="Three residual plots " data-recalc-dims="1"></a></p>
<p><a href="https://cran.r-project.org/package=picreg" rel="nofollow" target="_blank">picreg</a> v0.1.4 Implements the Pivotal Information Criterion developed by <a href="https://arxiv.org/abs/2603.04172" rel="nofollow" target="_blank">Sardy, van Cutsem, and van de Geer</a>. PIC is a general framework to improve on BIC and LASSO for fitting sparse regression linear models in which the regularization parameter 𝜆 is selected automatically from a pivotal statistic. Functions fit the resulting estimators across six response distributions, Gaussian, binomial, Poisson, exponential, Gumbel, and Cox, and three sparsity-inducing penalties; (LASSO), the Smoothly Clipped Absolute Deviation (SCAD), and Minimax Concave Penalty (MCP). See the <a href="https://cran.r-project.org/web/packages/picreg/vignettes/vignette.html" rel="nofollow" target="_blank">vignette</a> for an introduction.</p>
<p><a href="https://i1.wp.com/rworks.dev/posts/june-2026-top-40-new-cran-packages/picreg.png?ssl=1" class="lightbox" data-gallery="quarto-lightbox-gallery-26" rel="nofollow" target="_blank"><img src="https://i1.wp.com/rworks.dev/posts/june-2026-top-40-new-cran-packages/picreg.png?w=578&#038;ssl=1" class="img-fluid" alt="Plot showing individual survival curves" data-recalc-dims="1"></a></p>
<p><a href="https://cran.r-project.org/package=SimplexRegression" rel="nofollow" target="_blank">SimplexRegression</a> v0.1.5: Fits and analyzes simplex regression models with either fixed or parametric mean link functions. Implements the simplex probability density function, cumulative distribution function, quantile function, random number generation, and variance evaluation. Offers several fixed and parametric link functions for the mean submodel, tools for residual analysis and diagnostic plotting, hypothesis testing procedures, and influence measures such as Cook’s distance and leverage. Includes the Scout Score criterion for model selection, enabling comprehensive inference and diagnostic analysis within the simplex regression framework. See <a href="https://www.sciencedirect.com/science/article/pii/0047259X9190008P" rel="nofollow" target="_blank">Barndorff-Nielsen and Jorgensen (1991)</a> and <a href="https://www.sciencedirect.com/science/article/abs/pii/S0307904X25007863" rel="nofollow" target="_blank">Justino and Cribari-Neto (2026)</a> for more details and the <a href="https://cran.r-project.org/web/packages/SimplexRegression/vignettes/relative-humidity.html" rel="nofollow" target="_blank">vignette</a> for examples.</p>
<p><a href="https://cran.r-project.org/package=vbm" rel="nofollow" target="_blank">vbm</a> v0.1.0: Provides methods for variance-based sensitivity analysis and weighting estimators in observational studies based on the methodology by <a href="https://academic.oup.com/biomet/article-abstract/112/1/asae040/7731116?redirectedFrom=fulltext&#038;login=false" rel="nofollow" target="_blank">Huang &#038; Pimentel (2025)</a> Includes bootstrap inference, bias bounds estimation, and visualization tools for sensitivity parameters. See the <a href="https://cran.r-project.org/web/packages/vbm/vignettes/vbm.html" rel="nofollow" target="_blank">vignette</a>.</p>
<p><a href="https://i0.wp.com/rworks.dev/posts/june-2026-top-40-new-cran-packages/vbm.png?ssl=1" class="lightbox" data-gallery="quarto-lightbox-gallery-27" rel="nofollow" target="_blank"><img src="https://i0.wp.com/rworks.dev/posts/june-2026-top-40-new-cran-packages/vbm.png?w=578&#038;ssl=1" class="img-fluid" alt="Plot showing variables that should be prioritized for adjustment based on both treatment and outcome, while traditional love plot only considers treatment imbalance" data-recalc-dims="1"></a></p>
</section>
<section id="time-series" class="level3">
<h3 class="anchored" data-anchor-id="time-series">Time Series</h3>
<p><a href="https://cran.r-project.org/package=bvars" rel="nofollow" target="_blank">bvars</a> v1.0: Provides fast and efficient procedures for Bayesian estimation and forecasting using state-of-the-art vector autoregressions. Includes the model proposed by <a href="https://www.tandfonline.com/doi/full/10.1080/07350015.2018.1451336" rel="nofollow" target="_blank">Chan (2020)</a>, a Bayesian vector autoregression with Minnesota priors and a flexible structure of the error term that permits conditional multivariate normal or Student’s t distributions, as well as homoskedastic or heteroskedastic specifications with a common volatility modelled by centred or non-centred Stochastic Volatility. Additional features include predictive analyses using density forecasting and forecast-error variance decompositions. See <a href="https://cran.r-project.org/web/packages/bvars/readme/README.html" rel="nofollow" target="_blank">README</a> for an example.</p>
<p><a href="https://cran.r-project.org/package=fable.intermittent" rel="nofollow" target="_blank">fable.intermittent</a> v0.1.1: Extends the <code>fable</code> framework to support forecasting methods specifically designed for intermittent time series data, where demand occurs sporadically with many zero values. All methods produce probabilistic forecasts returned as ‘distributional’ objects. The returned forecasts can be used to evaluate accuracy, plot and print the results. Methods include: <a href="https://www.tandfonline.com/doi/abs/10.1080/07350015.1989.10509750" rel="nofollow" target="_blank">Harvey, Fernandes (1989)</a>, <a href="https://www.sciencedirect.com/science/article/abs/pii/S016920700300013X" rel="nofollow" target="_blank">Willemain, Smart, Schwarz (2004)</a> and several others. See the <a href="https://cran.r-project.org/web/packages/fable.intermittent/vignettes/fable.intermittent.html" rel="nofollow" target="_blank">vignette</a>.</p>
<p><a href="https://i1.wp.com/rworks.dev/posts/june-2026-top-40-new-cran-packages/fable.png?ssl=1" class="lightbox" data-gallery="quarto-lightbox-gallery-28" rel="nofollow" target="_blank"><img src="https://i1.wp.com/rworks.dev/posts/june-2026-top-40-new-cran-packages/fable.png?w=578&#038;ssl=1" class="img-fluid" alt="Time series with multiple forecasts" data-recalc-dims="1"></a></p>
<p><a href="https://cran.r-project.org/package=muse" rel="nofollow" target="_blank">muse</a> v0.1.0: Implements the Power / Trend / Seasonal (PTS) model, a unified state-space framework based on the Multiple Source of Error model. It brings the trend, seasonal and irregular component models of <a href="https://www.cambridge.org/core/books/forecasting-structural-time-series-models-and-the-kalman-filter/CE5E112570A56960601760E786A5E631" rel="nofollow" target="_blank">Harvey (1989)</a>, <a href="https://academic.oup.com/book/16563?login=false" rel="nofollow" target="_blank">Durbin and Koopman (2012)</a> and others together under a single estimation, selection and forecasting interface, with an optional Box-Cox power transformation. Models are estimated by maximum likelihood through the Kalman filter and smoother, with automatic component selection by information criteria. See the <a href="https://cran.r-project.org/web/packages/muse/vignettes/pts.html" rel="nofollow" target="_blank">vignette</a>.</p>
<p><a href="https://i2.wp.com/rworks.dev/posts/june-2026-top-40-new-cran-packages/muse.png?ssl=1" class="lightbox" data-gallery="quarto-lightbox-gallery-29" rel="nofollow" target="_blank"><img src="https://i2.wp.com/rworks.dev/posts/june-2026-top-40-new-cran-packages/muse.png?w=578&#038;ssl=1" class="img-fluid" alt="Time series with forecst" data-recalc-dims="1"></a></p>
</section>
<section id="utilities" class="level3">
<h3 class="anchored" data-anchor-id="utilities">Utilities</h3>
<p><a href="https://cran.r-project.org/package=ahocorasick" rel="nofollow" target="_blank">ahocorasick</a> v0.2.0: Provides fast multi-pattern string matching using the ’<code>Aho-Corasick</code> algorithm, powered by the <code>Rust</code> <code>aho-corasick</code> crate. It builds reusable automatons for detecting matches, counting matches, locating characters, extracting matched text, and replacing matches in character vectors. See <a href="https://dl.acm.org/doi/10.1145/360825.360855" rel="nofollow" target="_blank">Aho and Corasick (1975)</a> for more information on the <code>Aho-Corasick</code> algorithm and the <a href="https://cran.r-project.org/web/packages/ahocorasick/vignettes/benchmarks.html" rel="nofollow" target="_blank">vignette</a> for an example.</p>
<p><a href="https://cran.r-project.org/package=mx.crypto" rel="nofollow" target="_blank">mx.crypto</a> v0.2.0: Provides <code>Olm</code> and <code>Megolm</code> encryption ratchet primitives for the <a href="https://matrix.org/" rel="nofollow" target="_blank">Matrix messaging protocol</a>, wrapping the <code>vodozemac</code> <code>Rust</code> crate. Provides device-key generation, one-time-key management, 1:1 <code>Olm</code> sessions, and <code>Megolm</code> group sessions. Pairs with the <code>mx.api</code> package, which handles <code>Matrix HTTP</code> transport. See the <a href="https://cran.r-project.org/web/packages/mx.crypto/vignettes/security-audit.html" rel="nofollow" target="_blank">vignette</a>.</p>
<p><a href="https://cran.r-project.org/package=pkgmatch" rel="nofollow" target="_blank">pkgmatch</a> v0.5.4: Provides functions to find <code>R</code> packages from <code>CRAN</code>, <code>rOpenSci</code>, or <code>Bioconductor</code> corpora. Packages can be matched to general text descriptions, to names of installed packages, or to local paths to entire source repositories. The package is used to list the most similar packages for each new submission to the <code>rOpenSci</code> software <a href="https://zenodo.org/records/18885936" rel="nofollow" target="_blank">peer-review program</a>. There are three vignettes, including an <a href="https://cran.r-project.org/web/packages/pkgmatch/vignettes/pkgmatch.html" rel="nofollow" target="_blank">introduction</a> and <a href="https://cran.r-project.org/web/packages/pkgmatch/vignettes/A_extended-use-case.html" rel="nofollow" target="_blank">Example applications</a>.</p>
</section>
</div>
</div>



 
<div style="border: 1px solid; background: none repeat scroll 0 0 #EDEDED; margin: 1px; font-size: 13px;">
<div style="text-align: center;">To <strong>leave a comment</strong> for the author, please follow the link and comment on their blog: <strong><a href="https://rworks.dev/posts/june-2026-top-40-new-cran-packages/"> R Works</a></strong>.</div>
<hr />
<a href="https://www.r-bloggers.com/" rel="nofollow">R-bloggers.com</a> offers <strong><a href="https://feedburner.google.com/fb/a/mailverify?uri=RBloggers" rel="nofollow">daily e-mail updates</a></strong> about <a title="The R Project for Statistical Computing" href="https://www.r-project.org/" rel="nofollow">R</a> news and tutorials about <a title="R tutorials" href="https://www.r-bloggers.com/how-to-learn-r-2/" rel="nofollow">learning R</a> and many other topics. <a title="Data science jobs" href="https://www.r-users.com/" rel="nofollow">Click here if you're looking to post or find an R/data-science job</a>.

<hr>Want to share your content on R-bloggers?<a href="https://www.r-bloggers.com/add-your-blog/" rel="nofollow"> click here</a> if you have a blog, or <a href="http://r-posts.com/" rel="nofollow"> here</a> if you don't.
</div><strong>Continue reading</strong>: <a href="https://www.r-bloggers.com/2026/07/june-2026-top-40-new-cran-packages/">June 2026 Top 40 New CRAN Packages</a>]]></content:encoded>
					
		
		<enclosure url="https://rworks.dev/posts/june-2026-top-40-new-cran-packages/momst.png" length="0" type="image/png" />

		<post-id xmlns="com-wordpress:feed-additions:1">402843</post-id>	</item>
		<item>
		<title>GPopt for R: Bayesian and conformal optimization of black-box functions and hyperparameter tuning</title>
		<link>https://www.r-bloggers.com/2026/07/gpopt-for-r-bayesian-and-conformal-optimization-of-black-box-functions-and-hyperparameter-tuning/</link>
		
		<dc:creator><![CDATA[T. Moudiki]]></dc:creator>
		<pubDate>Sun, 26 Jul 2026 00:00:00 +0000</pubDate>
				<category><![CDATA[R bloggers]]></category>
		<guid isPermaLink="false">https://thierrymoudiki.github.io//blog/2026/07/26/r/GPopt</guid>

					<description><![CDATA[<div style = "width:60%; display: inline-block; float:left; "> GPopt for R: Bayesian and conformal optimization of black-box functions and hyperparameter tuning</div>
<div style = "width: 40%; display: inline-block; float:right;"></div>
<div style="clear: both;"></div>
<strong>Continue reading</strong>: <a href="https://www.r-bloggers.com/2026/07/gpopt-for-r-bayesian-and-conformal-optimization-of-black-box-functions-and-hyperparameter-tuning/">GPopt for R: Bayesian and conformal optimization of black-box functions and hyperparameter tuning</a>]]></description>
										<content:encoded><![CDATA[<!-- 
<div style="min-height: 30px;">
[social4i size="small" align="align-left"]
</div>
-->

<div style="border: 1px solid; background: none repeat scroll 0 0 #EDEDED; margin: 1px; font-size: 12px;">
[This article was first published on  <strong><a href="https://thierrymoudiki.github.io//blog/2026/07/26/r/GPopt"> T. Moudiki's Webpage - R</a></strong>, and kindly contributed to <a href="https://www.r-bloggers.com/" rel="nofollow">R-bloggers</a>].  (You can report issue about the content on this page <a href="https://www.r-bloggers.com/contact-us/">here</a>)
<hr>Want to share your content on R-bloggers?<a href="https://www.r-bloggers.com/add-your-blog/" rel="nofollow"> click here</a> if you have a blog, or <a href="http://r-posts.com/" rel="nofollow"> here</a> if you don't.
</div>
<p>This post describes the <code>R</code> version of Python’s <a href="https://github.com/Techtonique/GPopt" rel="nofollow" target="_blank">GPopt</a> 
(<a href="https://docs.techtonique.net/GPopt/GPopt.html" rel="nofollow" target="_blank">https://docs.techtonique.net/GPopt/GPopt.html</a>), a package for
‘Bayesian’ optimization of black-box functions and machine learning hyperparameter tuning, using Gaussian
Process Regression and other conformalized surrogates. The package is available on 
<a href="https://github.com/Techtonique/GPopt_r" rel="nofollow" target="_blank">GitHub</a>, and through the <a href="https://techtonique.r-universe.dev/builds" rel="nofollow" target="_blank">R universe</a>.</p>

<p>Keep in mind that this package is for Machine Learning hyperparameter tuning: <strong>the global minimum won’t always be found, but this isn’t an <em>issue</em>, since it means you aren’t overfitting the training set</strong>.</p>

<p>It’s ported the same way as <a href="https://github.com/Techtonique/nnetsauce_r" rel="nofollow" target="_blank">nnetsauce for R</a> was: with <code>uv</code> to
create an isolated Python virtual environment containing the Python <code>GPopt</code> package, and <code>reticulate</code> to call
into it from R. Every function in this R package is a thin wrapper that returns the underlying Python object;
the general rule is: <strong>object accesses with <code>.</code>’s in Python are replaced by <code>$</code>’s in R.</strong></p>

<p>See this post for the technique: <a href="https://thierrymoudiki.github.io/blog/2025/12/17/r/python/new-nnetsauce-R-uv" rel="nofollow" target="_blank">Finally figured out a way to port python packages to R using uv and reticulate</a>.</p>

<h2 id="install">Install</h2>

<h3 id="1-create-a-python-virtual-environment-with-uv">1. Create a Python virtual environment with <code>uv</code></h3>

<pre># pip install uv # if necessary
uv venv venv
source venv/bin/activate      # on Windows: venv\Scripts\activate
uv pip install pip GPopt
</pre>

<p>Keep track of where <code>venv/</code> lives – you’ll pass its path as <code>venv_path</code> to every function in this package.</p>

<h3 id="2-install-the-r-package">2. Install the R package</h3>

<pre>install.packages(&quot;remotes&quot;)
remotes::install_github(&quot;Techtonique/GPopt_r&quot;) 
</pre>

<p><code>reticulate</code> will be installed automatically as a dependency.</p>

<h2 id="examples">Examples</h2>

<h3 id="minimizing-the-branin-function">Minimizing the Branin function</h3>

<p>This is a standard test function for optimization algorithms. <code>GPOpt</code> is more suitable for expensive black-box functions, but this is a good example to illustrate the usage of the package.</p>

<pre>library(GPopt)

branin &lt;- function(x) {
  x1 &lt;- x[1]; x2 &lt;- x[2]
  term1 &lt;- (x2 - (5.1 * x1^2) / (4 * pi^2) + (5 * x1) / pi - 6)^2
  term2 &lt;- 10 * (1 - 1 / (8 * pi)) * cos(x1)
  term1 + term2 + 10
}

opt &lt;- GPOpt(
  lower_bound = c(-5, 0),
  upper_bound = c(10, 15),
  objective_func = branin,
  n_init = 10,
  n_iter = 40,
  venv_path = &quot;./venv&quot;
)

opt$optimize(verbose = 1L)
print(opt$x_min)  # best parameters
print(opt$y_min)  # best objective value
</pre>

<h3 id="tuning-a-scikit-learn-models-hyperparameters">Tuning a scikit-learn model’s hyperparameters</h3>

<pre>library(GPopt)

sklearn &lt;- get_sklearn(venv_path = &quot;./venv&quot;)
RandomForestClassifier &lt;- sklearn$ensemble$RandomForestClassifier

X &lt;- as.matrix(iris[, 1:4])
y &lt;- as.integer(iris$Species) - 1L

mlopt &lt;- MLOptimizer(scoring = &quot;accuracy&quot;, cv = 5, venv_path = &quot;./venv&quot;)

param_config &lt;- list(
  n_estimators = list(bounds = c(10, 300), dtype = &quot;int&quot;),
  max_depth    = list(bounds = c(1, 20),   dtype = &quot;int&quot;)
)

mlopt$optimize(
  X_train = X, y_train = y,
  estimator_class = RandomForestClassifier(),
  param_config = param_config,
  verbose = 1L
)

print(mlopt$get_best_parameters())
print(mlopt$get_best_score())
</pre>

<h3 id="bayesian-optimization-with-early-stopping">Bayesian optimization with early stopping</h3>

<pre>library(GPopt)

opt &lt;- BOstopping(
  f = branin,
  bounds = rbind(c(-5, 10), c(0, 15)),
  venv_path = &quot;./venv&quot;
)
result &lt;- opt$optimize(n_iter = 100L)
</pre>

<h3 id="using-a-custom-conformalized-surrogate-model">Using a custom (conformalized) surrogate model</h3>

<pre>library(GPopt)

sklearn &lt;- get_sklearn(venv_path = &quot;./venv&quot;)
ns &lt;- get_nnetsauce(venv_path = &quot;./venv&quot;)

opt &lt;- GPOpt(
  lower_bound = c(-5, 0),
  upper_bound = c(10, 15),
  objective_func = branin,
  acquisition=&quot;ucb&quot;,
  method=&quot;splitconformal&quot;,
  surrogate_obj = ns$PredictionInterval(sklearn$ensemble$RandomForestRegressor()),
  venv_path = &quot;./venv&quot;
)
opt$optimize(verbose = 1L)
</pre>

<p><img src="https://i0.wp.com/thierrymoudiki.github.io/images/2024-01-29/2024-01-29-image1.png?w=578&#038;ssl=1" alt="xxx" class="img-responsive" data-recalc-dims="1" /></p>

<div style="border: 1px solid; background: none repeat scroll 0 0 #EDEDED; margin: 1px; font-size: 13px;">
<div style="text-align: center;">To <strong>leave a comment</strong> for the author, please follow the link and comment on their blog: <strong><a href="https://thierrymoudiki.github.io//blog/2026/07/26/r/GPopt"> T. Moudiki's Webpage - R</a></strong>.</div>
<hr />
<a href="https://www.r-bloggers.com/" rel="nofollow">R-bloggers.com</a> offers <strong><a href="https://feedburner.google.com/fb/a/mailverify?uri=RBloggers" rel="nofollow">daily e-mail updates</a></strong> about <a title="The R Project for Statistical Computing" href="https://www.r-project.org/" rel="nofollow">R</a> news and tutorials about <a title="R tutorials" href="https://www.r-bloggers.com/how-to-learn-r-2/" rel="nofollow">learning R</a> and many other topics. <a title="Data science jobs" href="https://www.r-users.com/" rel="nofollow">Click here if you're looking to post or find an R/data-science job</a>.

<hr>Want to share your content on R-bloggers?<a href="https://www.r-bloggers.com/add-your-blog/" rel="nofollow"> click here</a> if you have a blog, or <a href="http://r-posts.com/" rel="nofollow"> here</a> if you don't.
</div><strong>Continue reading</strong>: <a href="https://www.r-bloggers.com/2026/07/gpopt-for-r-bayesian-and-conformal-optimization-of-black-box-functions-and-hyperparameter-tuning/">GPopt for R: Bayesian and conformal optimization of black-box functions and hyperparameter tuning</a>]]></content:encoded>
					
		
		<enclosure url="" length="0" type="" />

		<post-id xmlns="com-wordpress:feed-additions:1">402828</post-id>	</item>
		<item>
		<title>Some useful equations for biological processes</title>
		<link>https://www.r-bloggers.com/2026/07/some-useful-equations-for-biological-processes/</link>
		
		<dc:creator><![CDATA[Andrea Onofri]]></dc:creator>
		<pubDate>Thu, 23 Jul 2026 22:00:00 +0000</pubDate>
				<category><![CDATA[R bloggers]]></category>
		<guid isPermaLink="false">https://www.statforbiology.com/posts/nls_usefulEquations.html</guid>

					<description><![CDATA[<div style = "width:60%; display: inline-block; float:left; ">
<p>Biological phenomena are often studied by examining how a numerical variable, usually called the response (e.g., the weight or height of an organism), is affected by another variable, usually called the predictor (e.g., time or fertiliser applic...</p></div>
<div style = "width: 40%; display: inline-block; float:right;"></div>
<div style="clear: both;"></div>
<strong>Continue reading</strong>: <a href="https://www.r-bloggers.com/2026/07/some-useful-equations-for-biological-processes/">Some useful equations for biological processes</a>]]></description>
										<content:encoded><![CDATA[<!-- 
<div style="min-height: 30px;">
[social4i size="small" align="align-left"]
</div>
-->

<div style="border: 1px solid; background: none repeat scroll 0 0 #EDEDED; margin: 1px; font-size: 12px;">
[This article was first published on  <strong><a href="https://www.statforbiology.com/posts/nls_usefulEquations.html"> Statforbiology</a></strong>, and kindly contributed to <a href="https://www.r-bloggers.com/" rel="nofollow">R-bloggers</a>].  (You can report issue about the content on this page <a href="https://www.r-bloggers.com/contact-us/">here</a>)
<hr>Want to share your content on R-bloggers?<a href="https://www.r-bloggers.com/add-your-blog/" rel="nofollow"> click here</a> if you have a blog, or <a href="http://r-posts.com/" rel="nofollow"> here</a> if you don't.
</div>
 





<p>Biological phenomena are often studied by examining how a numerical variable, usually called the <em>response</em> (e.g., the weight or height of an organism), is affected by another variable, usually called the <em>predictor</em> (e.g., time or fertiliser application rate). These ‘predictor-response’ relationships are commonly described using <strong>models</strong>, which express the response as a mathematical function of the predictor. In general, a model can be written as:</p>
<p><img src="https://latex.codecogs.com/png.latex?Y%20=%20f(X,%20%5Ctheta)"></p>
<p>where <img src="https://latex.codecogs.com/png.latex?Y"> is the response, <img src="https://latex.codecogs.com/png.latex?X"> is the predictor, and <img src="https://latex.codecogs.com/png.latex?%5Ctheta"> is a collection of parameters, usually denoted by symbols, such as the letters of the Roman or Greek alphabet. The element <img src="https://latex.codecogs.com/png.latex?f"> is the <em>function</em>, which determines the shape of the relationship when plotted on an <em>x–y</em> graph.</p>
<p>Because mathematical modelling plays such a central role in biology and many other scientific disciplines, biologists need to be familiar with the most important mathematical functions. More importantly, they need to be able to “read” these functions and use their parameters to describe, interpret, and quantify biological processes. With this aim in mind, I have compiled a collection of the mathematical functions most commonly encountered in biology, explaining the meaning of their parameters, with particular emphasis on their biological interpretation rather than their mathematical properties.</p>
<section id="curve-shapes" class="level1">
<h1>Curve shapes</h1>
<p>Functions are often classified according to the shape they exhibit when plotted on an <em>x–y</em> graph. This approach is adopted, for example, in Ratkowsky (1990), and the classification presented below is largely based on that work.</p>
<ul>
<li>Polynomials
<ol type="1">
<li>Straight line function</li>
<li>Quadratic polynomial function</li>
</ol></li>
<li>Concave/Convex curves (no inflection)
<ol type="1">
<li>Exponential function</li>
<li>Asymptotic function / Negative exponential function</li>
<li>Power function</li>
<li>Logarithmic function</li>
<li>Rectangular hyperbola</li>
</ol></li>
<li>Sigmoidal curves
<ol type="1">
<li>Logistic function</li>
<li>Gompertz function</li>
<li>Modified Gompertz function</li>
<li>Log-logistic function</li>
<li>Weibull (type-1) function</li>
<li>Weibull (type-2) function</li>
</ol></li>
<li>Curves with maxima/minima
<ol type="1">
<li>Peaked sigmoidal function</li>
<li>Bragg function</li>
<li>Lorentz function</li>
<li>Beta function</li>
</ol></li>
</ul>
<p>I have chosen to include a relatively large number of functions, so this post is necessarily rather long. To make navigation easier, you can first inspect Figure 1 to identify the type of curve of interest and then use the links above to jump directly to the corresponding section.</p>
<p>Throughout this post, <img src="https://latex.codecogs.com/png.latex?X"> denotes the predictor, <img src="https://latex.codecogs.com/png.latex?Y"> denotes the response, and the letters of the Roman alphabet (<img src="https://latex.codecogs.com/png.latex?a">, <img src="https://latex.codecogs.com/png.latex?b">, <img src="https://latex.codecogs.com/png.latex?c">, …) denote the model parameters, which determine the shape of the function.</p>
<div class="cell">
<div class="cell-output-display">
<div id="fig-1" class="quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-1-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<img src="https://i1.wp.com/www.statforbiology.com/posts/nls_usefulEquations_files/figure-html/fig-1-1.png?w=578&#038;ssl=1" class="img-fluid figure-img" style="width:95.0%" data-recalc-dims="1">
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-1-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
Figure 1: The shapes of the most important functions. The different colors indicate the possible different shapes of the same function, with different parameters. In the case of the Bragg/Lorentz function, the red color indicate the Bragg function and the blue color indicate the Lorentz function (same parameter values).
</figcaption>
</figure>
</div>
</div>
</div>
</section>
<section id="polynomials" class="level1">
<h1>Polynomials</h1>
<p>Polynomials form a class of their own because their flexible shapes allow them to approximate a wide variety of biological processes, at least over a restricted range of the predictor. The mathematical tractation is very simple, but their main limitation is that they cannot describe asymptotic processes, which are extremely common in biology. Moreover, as the polynomial degree increases, their shapes become increasingly complex and often lack a meaningful biological interpretation.</p>
<section id="straight-line-function" class="level2">
<h2 class="anchored" data-anchor-id="straight-line-function">Straight-line function</h2>
<p>The simplest polynomial is the straight line, with equation:</p>
<p><img src="https://latex.codecogs.com/png.latex?Y%20=%20a%20+%20bX%20%5Cqquad%5Cqquad%20(1)"></p>
<p>where <img src="https://latex.codecogs.com/png.latex?a"> is the value of <img src="https://latex.codecogs.com/png.latex?Y"> when <img src="https://latex.codecogs.com/png.latex?X%20=%200">, and <img src="https://latex.codecogs.com/png.latex?b"> is the slope, that is, the change in <img src="https://latex.codecogs.com/png.latex?Y"> associated with a one-unit increase in <img src="https://latex.codecogs.com/png.latex?X">. When <img src="https://latex.codecogs.com/png.latex?b%3E0">, <img src="https://latex.codecogs.com/png.latex?Y"> increases as <img src="https://latex.codecogs.com/png.latex?X"> increases; when <img src="https://latex.codecogs.com/png.latex?b%3C0">, it decreases.</p>
<p>Because of their simplicity, straight lines are mainly used to approximate biological responses over a limited range of the predictor. Should you need it, an example of fitting a straight line to research data is given elsewhere <a href="https://www.statforbiology.com/posts/nls_modelFitting.html#straight-line-function" rel="nofollow" target="_blank">at this link</a>.</p>
</section>
<section id="quadratic-polynomial-function" class="level2">
<h2 class="anchored" data-anchor-id="quadratic-polynomial-function">Quadratic polynomial function</h2>
<p>The quadratic polynomial is described by the equation:</p>
<p><img src="https://latex.codecogs.com/png.latex?Y%20=%20a%20+%20bX%20+%20cX%5E2%20%5Cqquad%5Cqquad%20(2)"></p>
<p>This equation describes a U-shaped curve (a parabola), which may open upwards or downwards depending on the sign of <img src="https://latex.codecogs.com/png.latex?c">. If <img src="https://latex.codecogs.com/png.latex?c%3E0">, the parabola opens upwards; otherwise, it opens downwards.</p>
<p>The parameter <img src="https://latex.codecogs.com/png.latex?a"> represents the value of <img src="https://latex.codecogs.com/png.latex?Y"> when <img src="https://latex.codecogs.com/png.latex?X=0">, whereas <img src="https://latex.codecogs.com/png.latex?b"> and <img src="https://latex.codecogs.com/png.latex?c"> determine how the response changes as the predictor varies. To better understand the role of these parameters, we can examine the first derivative of Eq. (2). In R, this can be obtained with the <code>D()</code> function, which differentiates an expression with respect to a specified variable:</p>
<div class="cell">
<pre>D(expr = expression(a + b*X + c*X^2), name = &quot;X&quot;)</pre>
<div class="cell-output cell-output-stdout">
<pre>b + c * (2 * X)</pre>
</div>
</div>
<p>The derivative is not constant but varies with the value of <img src="https://latex.codecogs.com/png.latex?X"> and, in particular, <img src="https://latex.codecogs.com/png.latex?b"> represent the variation of <img src="https://latex.codecogs.com/png.latex?Y"> around the point <img src="https://latex.codecogs.com/png.latex?X%20=%200">. The stationary point, that is, the point where the derivative is zero, occurs at:</p>
<p><img src="https://latex.codecogs.com/png.latex?X_m%20=%20-%5Cfrac%7Bb%7D%7B2c%7D"></p>
<p>This point is a <strong>minimum</strong> when <img src="https://latex.codecogs.com/png.latex?c%3E0"> and a <strong>maximum</strong> when <img src="https://latex.codecogs.com/png.latex?c%3C0">.</p>
<p>The corresponding response is</p>
<p><img src="https://latex.codecogs.com/png.latex?Y_%7B%5Ctextrm%7Bmax%7D%7D%20=%20%5Cfrac%7B4ac-b%5E2%7D%7B4c%7D"></p>
<p>In practice, biologists often use only one branch of the parabola to approximate biological responses showing either a concave or a convex trend over a limited range of the predictor. Check <a href="https://www.statforbiology.com/posts/nls_modelFitting.html#quadratic-polynomial-function" rel="nofollow" target="_blank">this link</a> for an example of fitting.</p>
</section>
</section>
<section id="concaveconvex-curves-no-inflection-points" class="level1">
<h1>Concave/Convex curves (no inflection points)</h1>
<section id="exponential-function" class="level2">
<h2 class="anchored" data-anchor-id="exponential-function">Exponential function</h2>
<p>The most common parameterisation of an exponential function is:</p>
<p><img src="https://latex.codecogs.com/png.latex?%20Y%20=%20a%20e%5E%7Bk%20X%7D%20%5Cquad%20%5Cquad%20%5Cquad%20(3)%20"></p>
<p>Depending on the sign of <img src="https://latex.codecogs.com/png.latex?k">, Eq. 3 describes a concave-up monotonically increasing shape (exponential growth; <img src="https://latex.codecogs.com/png.latex?k%20%3E%200">) or a concave-up monotonically decreasing shape (exponential decay; <img src="https://latex.codecogs.com/png.latex?k%20%3C%200">).</p>
<p>The parameter <img src="https://latex.codecogs.com/png.latex?a"> represents the value of <img src="https://latex.codecogs.com/png.latex?Y"> when <img src="https://latex.codecogs.com/png.latex?X%20=%200">, whereas the meaning of <img src="https://latex.codecogs.com/png.latex?k"> can be understood by considering the first derivative:</p>
<div class="cell">
<pre>D(expression(a * exp(k * X)), &quot;X&quot;)</pre>
<div class="cell-output cell-output-stdout">
<pre>a * (exp(k * X) * k)</pre>
</div>
</div>
<p>In algebraic terms, it is:</p>
<p><img src="https://latex.codecogs.com/png.latex?%5Cfrac%7BdY%7D%7BdX%7D%20=%20k%20%5C,%20a%20%5C,%20e%5E%7Bk%20%5C,%20X%7D%20=%20k%20%5C,%20Y"></p>
<p>and thus:</p>
<p><img src="https://latex.codecogs.com/png.latex?%5Cfrac%7BdY%7D%7BdX%7D%20%5Cfrac%7B1%7D%7BY%7D%20=%20k"></p>
<p>Therefore, <img src="https://latex.codecogs.com/png.latex?k"> represents the relative rate of change (increase/decrease), throughout the domain, which is often known in growth analysis as the Relative Growth Rate (RGR).</p>
<p>Other equivalent parameterisations are:</p>
<p><img src="https://latex.codecogs.com/png.latex?%20Y%20=%20e%5E%7Bd%20+%20k%20X%7D%20%5Cquad%20%5Cquad%20%5Cquad%20(4)"></p>
<p>and:</p>
<p><img src="https://latex.codecogs.com/png.latex?Y%20=%20a%20%20%5C,%20b%5EX%20%5Cquad%20%5Cquad%20%5Cquad%20(5)"></p>
<p>Equations 3-5 are equivalent, as can be shown by setting <img src="https://latex.codecogs.com/png.latex?b%20=%20e%5Ek"> and <img src="https://latex.codecogs.com/png.latex?a%20=%20e%5Ed">:</p>
<p><img src="https://latex.codecogs.com/png.latex?a%20%5C,%20b%5EX%20%20=%20e%20%5E%20d%20%20(e%5E%7BkX%7D%20)%20=%20%20a%20%20%5C,%20e%5E%7BkX%7D"></p>
<p>Another, slightly different, parameterisation is commonly used in bioassay studies, mainly to describe exponential decay processes:</p>
<p><img src="https://latex.codecogs.com/png.latex?%20Y%20=%20d%20%5Cexp(-x/e)%20%5Cquad%20%5Cquad%20%5Cquad%20(6)"></p>
<p>where <img src="https://latex.codecogs.com/png.latex?d"> corresponds to <img src="https://latex.codecogs.com/png.latex?a"> in the previous models and <img src="https://latex.codecogs.com/png.latex?e%20=%20-%201/k">.</p>
<p>For all the exponential decay equations presented above, <img src="https://latex.codecogs.com/png.latex?Y%20%5Crightarrow%200"> as <img src="https://latex.codecogs.com/png.latex?X%20%5Crightarrow%20%5Cinfty">. A lower asymptote, <img src="https://latex.codecogs.com/png.latex?c%20%5Cneq%200">, can be incorporated into Eq. 6 to account for situations in which the response does not approach zero as the predictor tends to infinity:</p>
<p><img src="https://latex.codecogs.com/png.latex?%20Y%20=%20c%20+%20(d%20-c)%20%5Cexp(-x/e)%20%5Cquad%20%5Cquad%20%5Cquad%20(7)"></p>
<p>Exponential functions are often used to describe the growth of populations under non-limiting environmental conditions or the degradation of xenobiotics in the environment (first-order degradation kinetics). In both cases, <img src="https://latex.codecogs.com/png.latex?X"> represents time and is therefore restricted to non-negative values, while <img src="https://latex.codecogs.com/png.latex?b"> (or, equivalently, <img src="https://latex.codecogs.com/png.latex?k">) must be different from zero. Check the post <a href="https://www.statforbiology.com/posts/nls_modelFitting.html#exponential-function" rel="nofollow" target="_blank">at this link</a> for an example of fitting.</p>
</section>
<section id="asymptotic-function" class="level2">
<h2 class="anchored" data-anchor-id="asymptotic-function">Asymptotic function</h2>
<p>This function appears in several different parameterisations and is also known as the <em>monomolecular growth</em> function, the <em>Mitscherlich law</em>, or the <em>von Bertalanffy law</em>. Owing to its biological interpretation, the most widely used parameterisation is:</p>
<p><img src="https://latex.codecogs.com/png.latex?Y%20=%20a%20-%20(a%20-%20b)%20%5C,%20%5Cexp%20(-%20m%20X)%20%5Cquad%20%5Cquad%20%5Cquad%20(8)"></p>
<p>It describes a monotonically increasing, concave-down curve approaching a horizontal asymptote as <img src="https://latex.codecogs.com/png.latex?X"> tends to infinity. The parameter <img src="https://latex.codecogs.com/png.latex?a"> represents the maximum attainable value of <img src="https://latex.codecogs.com/png.latex?Y"> (the plateau), while <img src="https://latex.codecogs.com/png.latex?b"> is the value of <img src="https://latex.codecogs.com/png.latex?Y"> when <img src="https://latex.codecogs.com/png.latex?X%20=%200"> (the initial value). The parameter <img src="https://latex.codecogs.com/png.latex?m"> is proportional to the rate at which the response approaches the plateau. Indeed, the first derivative is</p>
<div class="cell">
<pre>D(expression(a - (a - b) * exp (- m * X)), &quot;X&quot;)</pre>
<div class="cell-output cell-output-stdout">
<pre>(a - b) * (exp(-m * X) * m)</pre>
</div>
</div>
<p>Considering Eq.8, we can write:</p>
<p><img src="https://latex.codecogs.com/png.latex?%5Cfrac%7BdY%7D%7BdX%7D%20=%20m%20%5C,%20(a%20-%20Y)"></p>
<p>and then:</p>
<p><img src="https://latex.codecogs.com/png.latex?%5Cfrac%7BdY%7D%7BdX%7D%20%5Cfrac%7B1%7D%7BY%7D%20=%20m%20%5C,%20%5Cfrac%7B(a%20-%20Y)%7D%7BY%7D"></p>
<p>The previous expression shows that the relative rate of change in the response (the RGR in growth analysis) is not constant, as it is for the exponential function. Instead, it depends on the attained value of <img src="https://latex.codecogs.com/png.latex?Y">. In particular, the RGR is greatest at the beginning of the process, when <img src="https://latex.codecogs.com/png.latex?Y"> is smallest, and gradually approaches zero as <img src="https://latex.codecogs.com/png.latex?Y"> approaches the plateau <img src="https://latex.codecogs.com/png.latex?a">.</p>
<p>Another closely related parameterisation is often encountered, in which <img src="https://latex.codecogs.com/png.latex?a"> is replaced by <img src="https://latex.codecogs.com/png.latex?d">, <img src="https://latex.codecogs.com/png.latex?b"> by <img src="https://latex.codecogs.com/png.latex?c">, and <img src="https://latex.codecogs.com/png.latex?m"> by <img src="https://latex.codecogs.com/png.latex?e%20=%201/m">. Some simple algebraic manipulations are also introduced to make the model consistent with the parameterisation commonly adopted for biological assay models:</p>
<p><img src="https://latex.codecogs.com/png.latex?Y%20=%20c%20+%20(d%20-%20c)%20%5C,%20%5Cleft%5B1%20-%20%5Cexp%20%5Cleft(-%20%5Cfrac%7BX%7D%7Be%7D%20%5Cright)%20%5Cright%5D%20%5Cquad%20%5Cquad%20%5Cquad%20(9)"></p>
<p>In some applications, <img src="https://latex.codecogs.com/png.latex?m"> is reparameterised through its logarithm to facilitate model fitting:</p>
<p><img src="https://latex.codecogs.com/png.latex?Y%20=%20a%20-%20(a%20-%20b)%20%5C,%20%5Cexp%20(-%20log(f)%20X)%20%5Cquad%20%5Cquad%20%5Cquad%20(10)"></p>
<p>For all these equations, setting <img src="https://latex.codecogs.com/png.latex?b%20=%200"> (or equivalently <img src="https://latex.codecogs.com/png.latex?c%20=%200">) yields a curve passing through the origin. In this case, the most common parameterisation is:</p>
<p><img src="https://latex.codecogs.com/png.latex?Y%20=%20a%20%5Cleft%5B%201-%20%5Cexp%20(-%20m%20X)%20%5Cright%5D%20%5Cquad%20%5Cquad%20%5Cquad%20(11)"></p>
<p>which is known as the <em>negative exponential function</em>.</p>
<p>The asymptotic function is widely used in biology, not only for growth analysis but also, for example, in weed competition studies. The negative exponential function has also been used to model the absorbed Photosynthetically Active Radiation (<img src="https://latex.codecogs.com/png.latex?Y%20=%20PAR_a">) as a function of leaf area index (<img src="https://latex.codecogs.com/png.latex?X%20=%20LAI">). In this context, <img src="https://latex.codecogs.com/png.latex?a"> represents the incident PAR (<img src="https://latex.codecogs.com/png.latex?a%20=%20PAR_i">), while <img src="https://latex.codecogs.com/png.latex?m"> is the light extinction coefficient. Check the post <a href="https://www.statforbiology.com/posts/nls_modelFitting.html#asymptotic-function" rel="nofollow" target="_blank">at this link</a> for an example of fitting.</p>
</section>
<section id="power-function" class="level2">
<h2 class="anchored" data-anchor-id="power-function">Power function</h2>
<p>The power function is also known as <em>Freundlich function</em> or <em>allometric function</em>. The most common parameterisation is:</p>
<p><img src="https://latex.codecogs.com/png.latex?Y%20=%20a%20%5C,%20X%5Eb%20%5Cquad%20%5Cquad%20%5Cquad%20(12)"></p>
<p>Its shape is highly flexible and is determined by the value of the parameter <img src="https://latex.codecogs.com/png.latex?b"> (see Figure 1). When <img src="https://latex.codecogs.com/png.latex?0%20%3C%20b%20%3C%201">, the response <img src="https://latex.codecogs.com/png.latex?Y"> increases with <img src="https://latex.codecogs.com/png.latex?X"> and the curve is concave down. When <img src="https://latex.codecogs.com/png.latex?b%20%3C%200">, <img src="https://latex.codecogs.com/png.latex?Y"> decreases as <img src="https://latex.codecogs.com/png.latex?X"> increases and the curve is concave up. Finally, when <img src="https://latex.codecogs.com/png.latex?b%20%3E%201">, <img src="https://latex.codecogs.com/png.latex?Y"> increases with <img src="https://latex.codecogs.com/png.latex?X"> and the curve is concave up. These three cases are illustrated in Figure 1 using different colours. The function is defined only for <img src="https://latex.codecogs.com/png.latex?X%20%3E%200"> and has no horizontal asymptote as <img src="https://latex.codecogs.com/png.latex?X%20%5Crightarrow%20%5Cinfty">.</p>
<p>The biological interpretation of the parameters <img src="https://latex.codecogs.com/png.latex?a"> and <img src="https://latex.codecogs.com/png.latex?b"> is not straightforward. Both influence the slope of the curve, as can be seen by examining the first derivative:</p>
<div class="cell">
<pre>D(expression(a * X^b), &quot;X&quot;)</pre>
<div class="cell-output cell-output-stdout">
<pre>a * (X^(b - 1) * b)</pre>
</div>
</div>
<p>The power function is mathematically equivalent to an exponential function of <img src="https://latex.codecogs.com/png.latex?%5Clog(X)">, since:</p>
<p><img src="https://latex.codecogs.com/png.latex?a%20%5C,X%5Eb%20=%20a%20%5C,%20e%5E%7B%5Clog(%20X%5Eb%20)%7D%20=%20a%20%5C,%20e%5E%7Bb%20%5C,%20%5Clog(X)%7D"></p>
<p>The power function (named as the Freundlich equation) is widely used in agricultural chemistry, for example to model the sorption of xenobiotics in soil. It is also used to describe the relationship between the number of plant species and the sampled area (the species–area relationship). Check the post <a href="https://www.statforbiology.com/posts/nls_modelFitting.html#power-function" rel="nofollow" target="_blank">at this link</a> for an example of fitting.</p>
</section>
<section id="logarithmic-function" class="level2">
<h2 class="anchored" data-anchor-id="logarithmic-function">Logarithmic function</h2>
<p>This function is linear in <img src="https://latex.codecogs.com/png.latex?%5Clog(X)">:</p>
<p><img src="https://latex.codecogs.com/png.latex?y%20=%20a%20+%20b%20%5C,%20%5Clog(X)%20%5Cquad%20%5Cquad%20%5Cquad%20(13)"></p>
<p>Because of the logarithmic transformation, the function is only defined for <img src="https://latex.codecogs.com/png.latex?X%20%3E%200">. The parameter <img src="https://latex.codecogs.com/png.latex?b"> determines the shape of the curve. When <img src="https://latex.codecogs.com/png.latex?b%20%3E%200">, the response <img src="https://latex.codecogs.com/png.latex?Y"> increases with <img src="https://latex.codecogs.com/png.latex?X"> and the curve is concave down. Conversely, when <img src="https://latex.codecogs.com/png.latex?b%20%3C%200">, <img src="https://latex.codecogs.com/png.latex?Y"> decreases as <img src="https://latex.codecogs.com/png.latex?X"> increases and the curve is concave up, as shown in Figure 1.</p>
<p>The interpretation of the parameters is fairly straightforward. The parameter <img src="https://latex.codecogs.com/png.latex?a"> is the value of the response when <img src="https://latex.codecogs.com/png.latex?X%20=%201">. Changing <img src="https://latex.codecogs.com/png.latex?a"> while keeping <img src="https://latex.codecogs.com/png.latex?b"> constant simply shifts the curve vertically without altering its shape, so that the difference between any two curves remains constant for every value of <img src="https://latex.codecogs.com/png.latex?X"> (Fig. 2).</p>
<p>The parameter <img src="https://latex.codecogs.com/png.latex?b"> controls the slope of the curve and, more specifically, it is equal to the slope at <img src="https://latex.codecogs.com/png.latex?X%20=%201">, as can be seen from the expression for the first derivative:</p>
<div class="cell">
<pre>D(expression(a + b*log(X)), &quot;X&quot;)</pre>
<div class="cell-output cell-output-stdout">
<pre>b * (1/X)</pre>
</div>
</div>
<p>Changing <img src="https://latex.codecogs.com/png.latex?b"> while keeping <img src="https://latex.codecogs.com/png.latex?a"> constant produces curves that all intersect at <img src="https://latex.codecogs.com/png.latex?X%20=%201"> (Fig. 2).</p>
<div class="cell">
<div class="cell-output-display">
<div id="fig-2" class="quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-2-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<img src="https://i0.wp.com/www.statforbiology.com/posts/nls_usefulEquations_files/figure-html/fig-2-1.png?w=578&#038;ssl=1" class="img-fluid figure-img" style="width:75.0%" data-recalc-dims="1">
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-2-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
Figure 2: Effects of changing parameter values on the shape of logarithmic curves. The parameter <img src="https://latex.codecogs.com/png.latex?a"> is 1 for the red curves and 3 for the black curves, while <img src="https://latex.codecogs.com/png.latex?b"> is 1 for the solid lines (-1 on the right panel) and 0.5 for the dotted lines (-0.5 in the right panel)
</figcaption>
</figure>
</div>
</div>
</div>
<p>In biology, logarithmic functions are used, for example, to describe species–area relationships in ecology, enzyme kinetics in biochemistry, and sensory perception in neurobiology. Check the post <a href="https://www.statforbiology.com/posts/nls_modelFitting.html#logarithmic-function" rel="nofollow" target="_blank">at this link</a> for an example of fitting.</p>
</section>
<section id="rectangular-hyperbola" class="level2">
<h2 class="anchored" data-anchor-id="rectangular-hyperbola">Rectangular hyperbola</h2>
<p>The rectangular hyperbola is commonly known as the Michaelis-Menten function and is usually parameterised as</p>
<p><img src="https://latex.codecogs.com/png.latex?Y%20=%20%5Cfrac%7Ba%20%5C,%20X%7D%20%7Bb%20+%20X%7D%20%5Cquad%20%5Cquad%20%5Cquad%20(14)"></p>
<p>The curve is monotonically increasing and concave down, approaching the horizontal asymptote (plateau) <img src="https://latex.codecogs.com/png.latex?a">. It passes through the origin of the axes (<img src="https://latex.codecogs.com/png.latex?Y%20=%200"> when <img src="https://latex.codecogs.com/png.latex?X%20=%200">). The parameter <img src="https://latex.codecogs.com/png.latex?b"> is the value of <img src="https://latex.codecogs.com/png.latex?X"> that produces a response equal to <img src="https://latex.codecogs.com/png.latex?a/2">. Indeed,</p>
<p><img src="https://latex.codecogs.com/png.latex?%5Cfrac%7Ba%7D%7B2%7D%20=%20%5Cfrac%7Ba%20%5C,X_%7B50%7D%20%7D%20%7Bb%20+%20X_%7B50%7D%20%7D"></p>
<p>which is readily solved to obtain <img src="https://latex.codecogs.com/png.latex?X_%7B50%7D%20=%20b">.</p>
<p>The first derivative is:</p>
<div class="cell">
<pre>D(expression( (a*X) / (b + X) ), &quot;X&quot;)</pre>
<div class="cell-output cell-output-stdout">
<pre>a/(b + X) - (a * X)/(b + X)^2</pre>
</div>
</div>
<p>From this expression, we can see that the initial slope (at <img src="https://latex.codecogs.com/png.latex?X%20=%200">) is <img src="https://latex.codecogs.com/png.latex?i%20=%20a/b">.</p>
<p>Equation 14 is not defined for <img src="https://latex.codecogs.com/png.latex?X%20=%20-b"> and has no biological meaning for <img src="https://latex.codecogs.com/png.latex?X%20%3C%20-b">. In most biological applications, however, both <img src="https://latex.codecogs.com/png.latex?X"> and <img src="https://latex.codecogs.com/png.latex?b"> are positive.</p>
<p>An equivalent parameterisation is:</p>
<p><img src="https://latex.codecogs.com/png.latex?Y%20=%20%5Cfrac%7Ba%20%5C,%20X%7D%20%7Bb%20+%20X%7D%20=%20%5Cfrac%7Ba%7D%7B%20%5Cfrac%7Bb%7D%7BX%7D%20+%20%5Cfrac%7BX%7D%7BX%7D%7D%20=%20%5Cfrac%7Ba%7D%7B1%20+%20%5Cfrac%7Bb%7D%7BX%7D%7D%20%5Cquad%20%5Cquad%20%5Cquad%20(15)"></p>
<p>In this form, the parameters <img src="https://latex.codecogs.com/png.latex?a"> and <img src="https://latex.codecogs.com/png.latex?b"> are often replaced by <img src="https://latex.codecogs.com/png.latex?d"> and <img src="https://latex.codecogs.com/png.latex?e">, respectively. Although the response is not defined for <img src="https://latex.codecogs.com/png.latex?X%20=%200">, it tends to zero as <img src="https://latex.codecogs.com/png.latex?X%20%5Crightarrow%200">.</p>
<p>Another common parameterisation includes the initial slope <img src="https://latex.codecogs.com/png.latex?i"> as an explicit parameter because of its biological relevance. This is obtained by dividing both the numerator and denominator by <img src="https://latex.codecogs.com/png.latex?b"> and noting that <img src="https://latex.codecogs.com/png.latex?i%20=%20a/b">, so that <img src="https://latex.codecogs.com/png.latex?b%20=%20a/i">:</p>
<p><img src="https://latex.codecogs.com/png.latex?Y%20=%20%5Cfrac%7Ba%20%5C,%20X%7D%20%7Bb%20+%20X%7D%20=%20%5Cfrac%7B%20%5Cfrac%7Ba%7D%7Bb%7D%20%5C,%20X%7D%20%7B%5Cfrac%7Bb%7D%7Bb%7D%20+%20%5Cfrac%7BX%7D%7Bb%7D%7D%20=%20%5Cfrac%7Bi%20%5C,%20X%7D%7B1%20+%20%5Cfrac%7Bi%20%5C,%20X%20%7D%7Ba%7D%7D%20%5Cquad%20%5Cquad%20%5Cquad%20(16)"></p>
<p>The Michaelis-Menten function is widely used in pesticide chemistry, enzyme kinetics (Eq. 14), biological assay models (Eq. 15), and weed competition studies, where it is used to describe crop yield loss as a function of weed density (Eq. 16). An example of fitting is shown in another post, <a href="https://www.statforbiology.com/posts/nls_usefulEquations.html#rectangular-hyperbola" rel="nofollow" target="_blank">at this link</a>.</p>
</section>
</section>
<section id="sigmoidal-function" class="level1">
<h1>Sigmoidal functions</h1>
<p>Sigmoidal functions are S-shaped, with two horizontal asymptotes (a lower and an upper asymptote) and an inflection point. They can be parameterised in countless ways, which may be confusing when selecting the most appropriate model for a particular biological process. In this post, I will use the parameterisations proposed in Ritz et al (2019), which is very consistent and puts all the curves on the same ground. Furthermore, the fitting properties are good, which contribute to good convergence and reliable estimation.</p>
<p>For the sake of simplicity, it is useful to recognise that most sigmoidal models belong to one of three basic families, which differ only in the position of the inflection point relative to the two asymptotes:</p>
<ol type="1">
<li><strong>Logistic</strong>: the ordinate of the inflection point lies halfway between the lower and upper asymptotes; consequently, the S-shape is symmetric (the concave-up and the concave-down portions ‘mirror’ each other).</li>
<li><strong>Gompertz</strong>: the ordinate of the inflection point lies closer to the lower asymptote, and, thus, the concave-up portions is ‘shorter’ than the concave-down portion.</li>
<li><strong>Modified Gompertz</strong>: the ordinate of the inflection point lies closer to the upper asymptote, and, thus, the concave-up portion is ‘longer’ than than the concave-down portion.</li>
</ol>
<p>Each of these three equations can describe either increasing or decreasing responses, depending on the sign of one of the model parameters (see below). Their different shapes are compared side by side in Fig. 3.</p>
<div class="cell">
<div class="cell-output-display">
<div id="fig-3" class="quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-3-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<img src="https://i1.wp.com/www.statforbiology.com/posts/nls_usefulEquations_files/figure-html/fig-3-1.png?w=450&#038;ssl=1" class="img-fluid figure-img"  data-recalc-dims="1">
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-3-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
Figure 3: The different shapes of sigmoidal curves based on x: logistic (red lines), Gompertz (blue lines) and modified Gompertz (green lines).
</figcaption>
</figure>
</div>
</div>
</div>
<p>Each of these three families (logistic, Gompertz and modified Gompertz) can be transformed by replacing <img src="https://latex.codecogs.com/png.latex?X"> with <img src="https://latex.codecogs.com/png.latex?%5Clog(X)">, giving raise to three corresponding families:</p>
<ol type="1">
<li><strong>Log-logistic</strong></li>
<li><strong>Type-I Weibull</strong></li>
<li><strong>Type-II Weibull</strong></li>
</ol>
<p>Like their linear-scale counterparts, these three families can describe either increasing or decreasing responses, depending on the sign of the same model parameter (see below). In the end, we have twelve different sigmoidal functions to choose from. The choice among them depends primarily on the expected symmetry of the response and on whether the predictor is more naturally interpreted on a linear or logarithmic scale.</p>
<p>Thanks to their versatility, sigmoidal functions have been used for an uncountable number of biological applications. Just to mention a few examples in agriculture, I would like to cite plant growth, dose-response curves in biological assays and the time-course of seed germination. For some examples, take a look at my post <a href="https://www.statforbiology.com/posts/nls_modelFitting.html#sigmoidal-function" rel="nofollow" target="_blank">at this link</a>.</p>
<section id="logistic-function" class="level2">
<h2 class="anchored" data-anchor-id="logistic-function">Logistic function</h2>
<p>The logistic curve is derived from the cumulative logistic distribution function. It is symmetric about its inflection point and can be parameterised as:</p>
<p><img src="https://latex.codecogs.com/png.latex?Y%20=%20c%20+%20%5Cfrac%7Bd%20-%20c%7D%7B1%20+%20exp(-%20b%20(X%20-%20e))%7D%20%5Cquad%20%5Cquad%20%5Cquad%20(17)"></p>
<p>where <img src="https://latex.codecogs.com/png.latex?d"> is the upper asymptote, <img src="https://latex.codecogs.com/png.latex?c"> is the lower asymptote, <img src="https://latex.codecogs.com/png.latex?e"> is the value of <img src="https://latex.codecogs.com/png.latex?X"> at the inflection point, and <img src="https://latex.codecogs.com/png.latex?b"> is proportional to the slope at the inflection point. Because the curve is symmetric, <img src="https://latex.codecogs.com/png.latex?e"> also represents the value of <img src="https://latex.codecogs.com/png.latex?X"> that produces a response halfway between <img src="https://latex.codecogs.com/png.latex?d"> and <img src="https://latex.codecogs.com/png.latex?c"> (commonly referred to as the ED50 in biological assays). The parameter <img src="https://latex.codecogs.com/png.latex?b"> may be either positive or negative and, consequently, the response may either increase or decrease as <img src="https://latex.codecogs.com/png.latex?X"> increases.</p>
<p>This equation is known as the four-parameter logistic model. If appropriate, constraints can be imposed on the parameter values. For example, <img src="https://latex.codecogs.com/png.latex?c"> may be fixed at 0, yielding the three-parameter logistic model. If, in addition, <img src="https://latex.codecogs.com/png.latex?d"> is fixed at 1, the model reduces to the two-parameter logistic model.</p>
</section>
<section id="gompertz-function" class="level2">
<h2 class="anchored" data-anchor-id="gompertz-function">Gompertz function</h2>
<p>The Gompertz curve can be parameterised in many different ways. I prefer a parameterisation that closely resembles that of the logistic function:</p>
<p><img src="https://latex.codecogs.com/png.latex?Y%20=%20c%20+%20(d%20-%20c)%20%5Cexp%20%5Cleft%5C%7B-%20%5Cexp%20%5Cleft%5B%20-%20b%20%5C,%20(X%20-%20e)%20%5Cright%5D%20%5Cright%5C%7D%20%5Cquad%20%5Cquad%20%5Cquad%20(18)"></p>
<p>Unlike the logistic function, the Gompertz curve is not symmetric about its inflection point. It exhibits a longer lag phase at the beginning, followed by a progressively steeper increase before gradually approaching the upper asymptote. The parameters have essentially the same interpretation as those of the logistic function, except that <img src="https://latex.codecogs.com/png.latex?e">, the abscissa of the inflection point, does not correspond to the value of <img src="https://latex.codecogs.com/png.latex?X"> producing a response halfway between <img src="https://latex.codecogs.com/png.latex?c"> and <img src="https://latex.codecogs.com/png.latex?d">.</p>
<p>As with the logistic function, four-, three-, and two-parameter Gompertz models can be obtained by constraining one or both asymptotes.</p>
</section>
<section id="modified-gompertz-function" class="level2">
<h2 class="anchored" data-anchor-id="modified-gompertz-function">Modified Gompertz function</h2>
<p>We have seen that the logistic curve is symmetric about its inflection point, whereas the Gompertz curve exhibits a longer lag phase at the beginning, followed by a progressively steeper increase. A different asymmetric pattern can be obtained by modifying the Gompertz function as follows:</p>
<p><img src="https://latex.codecogs.com/png.latex?%20Y%20=%20c%20+%20(d%20-%20c)%20%5Cleft%5C%7B%201%20-%20%5Cexp%20%5Cleft%5C%7B-%20%5Cexp%20%5Cleft%5B%20b%20%5C,%20(X%20-%20e)%20%5Cright%5D%20%5Cright%5C%7D%20%5Cright%5C%7D%20%5Cquad%20%5Cquad%20%5Cquad%20(19)"></p>
<p>The resulting curve increases rapidly at the beginning but gradually slows down as it approaches the upper asymptote. As with the logistic and Gompertz functions, one or both asymptotes can be constrained (<img src="https://latex.codecogs.com/png.latex?d%20=%201"> and/or <img src="https://latex.codecogs.com/png.latex?c%20=%200">), giving rise to four-, three-, and two-parameter versions of the modified Gompertz model.</p>
</section>
<section id="log-logistic-function" class="level2">
<h2 class="anchored" data-anchor-id="log-logistic-function">Log-logistic function</h2>
<p>The log-logistic curve is symmetric with respect to <img src="https://latex.codecogs.com/png.latex?%5Clog(X)">. A log-normal curve has a very similar shape, although it is used much less frequently. In biological assays (and also in germination studies), the log-logistic function is commonly parameterised as</p>
<p><img src="https://latex.codecogs.com/png.latex?Y%20=%20c%20+%20%5Cfrac%7Bd%20-%20c%7D%7B1%20+%20%5Cexp%20%5Cleft%5C%7B%20-%20b%20%5Cleft%5B%20%5Clog(X)%20-%20%5Clog(e)%20%5Cright%5D%20%5Cright%5C%7D%20%7D%20%5Cquad%20%5Cquad%20%5Cquad%20(20)"></p>
<p>The parameters have the same interpretation as in the logistic function. In particular, <img src="https://latex.codecogs.com/png.latex?e"> represents the value of <img src="https://latex.codecogs.com/png.latex?X"> that produces a response halfway between <img src="https://latex.codecogs.com/png.latex?c"> and <img src="https://latex.codecogs.com/png.latex?d"> (the ED50). It is easy to show that the above equation is equivalent to</p>
<p><img src="https://latex.codecogs.com/png.latex?Y%20=%20c%20+%20%5Cfrac%7Bd%20-%20c%7D%7B1%20+%20%5Cleft(%20%5Cfrac%7BX%7D%7Be%7D%20%5Cright)%5E%7B-b%7D%7D"></p>
<p>Like the logistic function, the log-logistic model can be fitted in four-, three-, or two-parameter versions by constraining one or both asymptotes. It is widely used to describe dose-response relationships in biological assays, seed germination, and crop growth.</p>
</section>
<section id="weibull-function-type-1" class="level2">
<h2 class="anchored" data-anchor-id="weibull-function-type-1">Weibull function (type 1)</h2>
<p>The Type I Weibull function is the logarithmic counterpart of the Gompertz function, being defined on <img src="https://latex.codecogs.com/png.latex?%5Clog(X)"> rather than on <img src="https://latex.codecogs.com/png.latex?X">. It is parameterised as</p>
<p><img src="https://latex.codecogs.com/png.latex?%20Y%20=%20c%20+%20(d%20-%20c)%20%5Cexp%20%5Cleft%5C%7B-%20%5Cexp%20%5Cleft%5B%20-%20b%20%5C,%20(%5Clog(X)%20-%20%5Clog(e))%20%5Cright%5D%20%5Cright%5C%7D%20%5Cquad%20%5Cquad%20%5Cquad%20(21)"></p>
<p>The parameters have essentially the same interpretation as those of the other sigmoidal functions presented above. In particular, <img src="https://latex.codecogs.com/png.latex?c"> and <img src="https://latex.codecogs.com/png.latex?d"> are the lower and upper asymptotes, respectively, while <img src="https://latex.codecogs.com/png.latex?e"> is the value of <img src="https://latex.codecogs.com/png.latex?X"> corresponding to the inflection point. Unlike the log-logistic function, however, <img src="https://latex.codecogs.com/png.latex?e"> does not correspond to the ED50.</p>
</section>
<section id="weibull-function-type-2" class="level2">
<h2 class="anchored" data-anchor-id="weibull-function-type-2">Weibull function (type 2)</h2>
<p>The Type II Weibull function is closely related to the Type I Weibull function, but it describes a different type of asymmetry, analogous to that of the modified Gompertz function:</p>
<p><img src="https://latex.codecogs.com/png.latex?%20Y%20=%20c%20+%20(d%20-%20c)%20%5Cleft%5C%7B%201%20-%20%5Cexp%20%5Cleft%5C%7B-%20%5Cexp%20%5Cleft%5B%20b%20%5C,%20(%5Clog(X)%20-%20%5Clog(e))%20%5Cright%5D%20%5Cright%5C%7D%20%5Cright%5C%7D%20%5Cquad%20%5Cquad%20%5Cquad%20(22)"></p>
<p>The parameters have the same interpretation as those of the Type I Weibull function. In particular, <img src="https://latex.codecogs.com/png.latex?c"> and <img src="https://latex.codecogs.com/png.latex?d"> are the lower and upper asymptotes, respectively, while <img src="https://latex.codecogs.com/png.latex?e"> is the value of <img src="https://latex.codecogs.com/png.latex?X"> at the inflection point. As with the Type I Weibull function, <img src="https://latex.codecogs.com/png.latex?e"> does not correspond to the ED50. One or both asymptotes may be constrained, giving rise to four-, three-, and two-parameter versions of the model.</p>
</section>
<section id="another-flexible-sigmoid" class="level2">
<h2 class="anchored" data-anchor-id="another-flexible-sigmoid">Another ‘flexible’ sigmoid</h2>
<p>I would also like to mention another sigmoidal function that has been widely used in biology because of its supposed flexibility: the <em>Richards</em> function:</p>
<p><img src="https://latex.codecogs.com/png.latex?Y%20=%20c%20+%20%5Cfrac%7Bd%20-%20c%7D%7B%5Cleft%5B1%20+%20exp(-%20b%20(X%20-%20e))%5Cright%5D%5E%7B1/f%7D%7D"></p>
<p>In this model, the degree of asymmetry is controlled by the parameter <img src="https://latex.codecogs.com/png.latex?f">. When <img src="https://latex.codecogs.com/png.latex?f%20=%201">, the function reduces to the logistic model, whereas, as <img src="https://latex.codecogs.com/png.latex?f"> decreases below 1, the curve progressively resembles a Gompertz function. Figure 4 illustrates the different shapes obtained for different values of <img src="https://latex.codecogs.com/png.latex?f">.</p>
<p>Despite this apparent flexibility, the Richards function has poor statistical properties for parameter estimation. In particular, the additional parameter often causes strong correlations among the estimates, making the fitting process unstable and the parameter estimates difficult to interpret. Ratkowsky (1990) described it as having <em>“more undesirable nonlinear regression behaviour than almost any nonlinear regression model in common use.”</em> For these reasons, the Richards function will not be considered further in this blog.</p>
<div class="cell">
<div class="cell-output-display">
<div id="fig-4" class="quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-4-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<img src="https://i0.wp.com/www.statforbiology.com/posts/nls_usefulEquations_files/figure-html/fig-4-1.png?w=450&#038;ssl=1" class="img-fluid figure-img"  data-recalc-dims="1">
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-4-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
Figure 4: The different shapes of the Richard’s function, based on the <img src="https://latex.codecogs.com/png.latex?f"> parameter: <img src="https://latex.codecogs.com/png.latex?f%20=%201"> (black line), <img src="https://latex.codecogs.com/png.latex?f%20=%200.5"> (blue line) and <img src="https://latex.codecogs.com/png.latex?f%20=%201.5"> (red line)
</figcaption>
</figure>
</div>
</div>
</div>
</section>
</section>
<section id="maxima-fun" class="level1">
<h1>Curves with maxima/minima</h1>
<p>It is sometimes necessary to describe phenomena where the <img src="https://latex.codecogs.com/png.latex?Y"> variable reaches a maximum value at a certain level of the <img src="https://latex.codecogs.com/png.latex?X"> variable, and drops afterwords. For example, growth or germination rates are higher at optimal temperature levels and lower at supra-optimal or sub-optimal temperature levels. Another example relates to bioassays: in some cases, low doses of toxic substances induce a stimulation of growth (hormesis), which needs to be described by an appropriate model. The second order (and higher order) polynomial funcion we have seen earlier is capable of accounting for maxima/minima, but there are a few other interesting functions that may turn out useful in some circumstances.</p>
<section id="brain-function" class="level2">
<h2 class="anchored" data-anchor-id="brain-function">Peaked sigmoidal function</h2>
<p>The log-logistic decreasing curve can be modified to account for possible hormetic effects at low doses, by combining mathematical switching functions (Schabenberger and Pierce, 2002; pag. 275). The most widespread parameterisation, that was originally devised by Brain and Cousens (<em>Brain, P., Cousens, R., 1989. An equation to describe dose responses where there is stimulation of growth at low doses. Weed Research 29, 93–96</em>) in a slightly different form, is:</p>
<p><img src="https://latex.codecogs.com/png.latex?Y%20=%20c%20+%20%5Cfrac%7Bd%20-%20c%20+%20f%20%5C,%20X%7D%7B1%20+%20%5Cexp%20%5Cleft%5C%7B%20-%20b%20%5Cleft%5B%20%5Clog(X)%20-%20%5Clog(e)%20%5Cright%5D%20%5Cright%5C%7D%20%7D%20%5Cquad%20%5Cquad%20%5Cquad%20(23)"></p>
<p>The parameters have the same interpretation as in the log-logistic curves, but <img src="https://latex.codecogs.com/png.latex?e"> does not represent the response half-way between the lower and higher asymptote and <img src="https://latex.codecogs.com/png.latex?f%20%3E%200"> represents the size of the hormetic effect, which increases as <img src="https://latex.codecogs.com/png.latex?f"> increases, while <img src="https://latex.codecogs.com/png.latex?f%20=%200"> corresponds to the situation of no hormesis (and the function reduces to a log-logistic.</p>
</section>
<section id="bragg-function" class="level2">
<h2 class="anchored" data-anchor-id="bragg-function">Bragg function</h2>
<p>This function is connected to the normal (Gaussian) distribution and has a symmetric shape with a maximum equal to <img src="https://latex.codecogs.com/png.latex?d">, that is reached when <img src="https://latex.codecogs.com/png.latex?X%20=%20e"> and two inflection points. In this model, <img src="https://latex.codecogs.com/png.latex?b"> relates to the slope at the inflection points; the response <img src="https://latex.codecogs.com/png.latex?Y"> approaches 0 when <img src="https://latex.codecogs.com/png.latex?X"> approaches <img src="https://latex.codecogs.com/png.latex?%5Cpm%20%5Cinfty">:</p>
<p><img src="https://latex.codecogs.com/png.latex?Y%20=%20d%20%5C,%20%5Cexp%20%5Cleft%5B%20-%20b%20(X%20-%20e)%5E2%20%5Cright%5D%20%5Cquad%20%5Cquad%20%5Cquad%20(24)"></p>
<p>If we would like to have lower asymptotes different from 0, we should add the parameter <img src="https://latex.codecogs.com/png.latex?c">, as follows:</p>
<p><img src="https://latex.codecogs.com/png.latex?Y%20=%20c%20+%20(d%20-%20c)%20%5C,%20%5Cexp%20%5Cleft%5B%20-%20b%20(X%20-%20e)%5E2%20%5Cright%5D%20%5Cquad%20%5Cquad%20%5Cquad%20(24a)"></p>
<p>The two Bragg functions have proven useful in applications relating to the science of carbon materials.</p>
</section>
<section id="lorentz-function" class="level2">
<h2 class="anchored" data-anchor-id="lorentz-function">Lorentz function</h2>
<p>The Lorentz function is similar to the Bragg function, although it has worse statistical properties (Ratkowsky, 1990). The equation is:</p>
<p><img src="https://latex.codecogs.com/png.latex?Y%20=%20%5Cfrac%7Bd%7D%20%7B%201%20+%20b%20(X%20-%20e)%5E2%20%7D%20%5Cquad%20%5Cquad%20%5Cquad%20(25)"></p>
<p>We can also allow for lower asymptotes different from 0, by adding a further parameter:</p>
<p><img src="https://latex.codecogs.com/png.latex?Y%20=%20c%20+%20%5Cfrac%7Bd%20-%20c%7D%20%7B%201%20+%20b%20(X%20-%20e)%5E2%20%7D%20%5Cquad%20%5Cquad%20%5Cquad%20(25a)"></p>
</section>
<section id="beta-function" class="level2">
<h2 class="anchored" data-anchor-id="beta-function">Beta function</h2>
<p>The beta function derives from the beta density function and it has been adapted to describe phenomena taking place only within a minimum and a maximum threshold value (threshold model). One typical example is seed germination, where the germination rate (GR, i.e. the inverse of germination time) is 0 below the base temperature level and above the cutoff temperature level. Between these two extremes, the GR increases with temperature up to a maximum level, that is reached at the optimal temperature level.</p>
<p>The equation is:</p>
<p><img src="https://latex.codecogs.com/png.latex?%20Y%20=%20d%20%5C,%5Cleft%5C%7B%20%20%5Cleft(%20%5Cfrac%7BX%20-%20X_b%7D%7BX_o%20-%20X_b%7D%20%5Cright)%20%5Cleft(%20%5Cfrac%7BX_c%20-%20X%7D%7BX_c%20-%20X_o%7D%20%5Cright)%20%5E%20%7B%5Cfrac%7BX_c%20-%20X_o%7D%7BX_o%20-%20X_b%7D%7D%20%5Cright%5C%7D%5Eb%20%5Cquad%20%5Cquad%20%5Cquad%20(26)"></p>
<p>where <img src="https://latex.codecogs.com/png.latex?d"> is the maximum level for the expected response <img src="https://latex.codecogs.com/png.latex?Y">, <img src="https://latex.codecogs.com/png.latex?X_b"> and <img src="https://latex.codecogs.com/png.latex?X_c"> are, respectively, the minumum and maximum threshold levels, <img src="https://latex.codecogs.com/png.latex?X_o"> is the abscissa at the maximum expected response level and <img src="https://latex.codecogs.com/png.latex?b"> is a shape parameter. The above function is only defined for <img src="https://latex.codecogs.com/png.latex?X_b%20%3C%20X%20%3C%20X_c"> and it returns 0 elsewhere.</p>
</section>
</section>
<section id="conclusions" class="level1">
<h1>Conclusions</h1>
<p>Here we are; I have discussed more almost 30 functions, which are commonly used to model biological processes. These functions can be found in several other different parameterisations and I suggest you read the book chapter by Miguez et al. (2018), for other interesting information.</p>
<p>Thanks for reading! And … don’t forget to check out my new book!</p>
<p>Prof. Andrea Onofri<br>
Department of Agricultural, Food and Environmental Sciences<br>
University of Perugia (Italy)<br>
Send comments to: <a href="mailto:andrea.onofri@unipg.it" rel="nofollow" target="_blank">andrea.onofri@unipg.it</a></p>
<p><a href="https://www.awin1.com/cread.php?awinmid=26429&#038;awinaffid=2675822&#038;ued=https%3A%2F%2Flink.springer.com%2Fbook%2F10.1007%2F978-3-032-08199-5" rel="nofollow" target="_blank"><img src="https://i0.wp.com/www.statforbiology.com/Figures/Email_Signature_978-3-032-08199-5.png?w=578&#038;ssl=1" alt="Book cover" class="cover" align="center" data-recalc-dims="1"></a></p>
<hr>
</section>
<section id="further-readings" class="level1">
<h1>Further readings</h1>
<ol type="1">
<li>Miguez, F., Archontoulis, S., Dokoohaki, H., Glaz, B., Yeater, K.M., 2018. Chapter 15: Nonlinear Regression Models and Applications, in: ACSESS Publications. American Society of Agronomy, Crop Science Society of America, and Soil Science Society of America, Inc.</li>
<li>Ratkowsky, D.A., 1990. Handbook of nonlinear regression models. Marcel Dekker Inc., New York, USA.</li>
<li>Ritz, C., Jensen, S. M., Gerhard, D., Streibig, J. C., 2019. Dose-Response Analysis Using R. CRC Press</li>
<li>Schabenberger, O., Pierce, F.J., 2002. Contemporary statistical models for the plant and soil sciences. Taylor &#038; Francis, CRC Press, Books.</li>
</ol>
<p>This post was originally published in this blog on 2019-01-08</p>


</section>

 
<div style="border: 1px solid; background: none repeat scroll 0 0 #EDEDED; margin: 1px; font-size: 13px;">
<div style="text-align: center;">To <strong>leave a comment</strong> for the author, please follow the link and comment on their blog: <strong><a href="https://www.statforbiology.com/posts/nls_usefulEquations.html"> Statforbiology</a></strong>.</div>
<hr />
<a href="https://www.r-bloggers.com/" rel="nofollow">R-bloggers.com</a> offers <strong><a href="https://feedburner.google.com/fb/a/mailverify?uri=RBloggers" rel="nofollow">daily e-mail updates</a></strong> about <a title="The R Project for Statistical Computing" href="https://www.r-project.org/" rel="nofollow">R</a> news and tutorials about <a title="R tutorials" href="https://www.r-bloggers.com/how-to-learn-r-2/" rel="nofollow">learning R</a> and many other topics. <a title="Data science jobs" href="https://www.r-users.com/" rel="nofollow">Click here if you're looking to post or find an R/data-science job</a>.

<hr>Want to share your content on R-bloggers?<a href="https://www.r-bloggers.com/add-your-blog/" rel="nofollow"> click here</a> if you have a blog, or <a href="http://r-posts.com/" rel="nofollow"> here</a> if you don't.
</div><strong>Continue reading</strong>: <a href="https://www.r-bloggers.com/2026/07/some-useful-equations-for-biological-processes/">Some useful equations for biological processes</a>]]></content:encoded>
					
		
		<enclosure url="" length="0" type="" />

		<post-id xmlns="com-wordpress:feed-additions:1">402841</post-id>	</item>
		<item>
		<title>Babe Ruth:  How good was he?  Mantle versus Ruth</title>
		<link>https://www.r-bloggers.com/2026/07/babe-ruth-how-good-was-he-mantle-versus-ruth/</link>
		
		<dc:creator><![CDATA[Jerry Tuttle]]></dc:creator>
		<pubDate>Thu, 23 Jul 2026 13:40:56 +0000</pubDate>
				<category><![CDATA[R bloggers]]></category>
		<guid isPermaLink="false">http://www.r-bloggers.com/?guid=5d604b1e3883f211bead13b9aee0a3ea</guid>

					<description><![CDATA[<div style = "width:60%; display: inline-block; float:left; ">
<p>     <br />
  As a kid, my baseball hero was Mickey Mantle.  In his 18-year Major League career, he amassed tremendous statistics, and surely he was one of the game's all-time greats. When Mantle retired, he was third on...</p></div>
<div style = "width: 40%; display: inline-block; float:right;"></div>
<div style="clear: both;"></div>
<strong>Continue reading</strong>: <a href="https://www.r-bloggers.com/2026/07/babe-ruth-how-good-was-he-mantle-versus-ruth/">Babe Ruth:  How good was he?  Mantle versus Ruth</a>]]></description>
										<content:encoded><![CDATA[<!-- 
<div style="min-height: 30px;">
[social4i size="small" align="align-left"]
</div>
-->

<div style="border: 1px solid; background: none repeat scroll 0 0 #EDEDED; margin: 1px; font-size: 12px;">
[This article was first published on  <strong><a href="https://onlinecollegemathteacher.blogspot.com/2026/07/babe-ruth-how-good-was-he-mantle-versus.html"> Online College Math Teacher</a></strong>, and kindly contributed to <a href="https://www.r-bloggers.com/" rel="nofollow">R-bloggers</a>].  (You can report issue about the content on this page <a href="https://www.r-bloggers.com/contact-us/">here</a>)
<hr>Want to share your content on R-bloggers?<a href="https://www.r-bloggers.com/add-your-blog/" rel="nofollow"> click here</a> if you have a blog, or <a href="http://r-posts.com/" rel="nofollow"> here</a> if you don't.
</div>
<font size = 3>
  
  
  <div class="separator" style="clear: both;"><a href="https://i0.wp.com/blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiCCmsSfa9WIoWzQAP-ZBXO_SBQqll6JMXhJEjdON2COM4C6AQtwUyfrYrFogPc3rEtkSvs6327YWzDdT_Rt3XPEuupvMvxC8ygDnD_lw8OCX8WHzFLF9oxJf9hW1wwNb9iYogPAqUEgH-ATGrYGyhvJ8lPS5DuZkk5Z2p4VPpuxETa_cTHCCUZogT8QDo/s697/mick_babe.jpg?ssl=1" style="display: block; padding: 1em 0; text-align: center; " rel="nofollow" target="_blank"><img alt="" border="0" width="400" data-original-height="400" data-original-width="450" src="https://i0.wp.com/blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiCCmsSfa9WIoWzQAP-ZBXO_SBQqll6JMXhJEjdON2COM4C6AQtwUyfrYrFogPc3rEtkSvs6327YWzDdT_Rt3XPEuupvMvxC8ygDnD_lw8OCX8WHzFLF9oxJf9hW1wwNb9iYogPAqUEgH-ATGrYGyhvJ8lPS5DuZkk5Z2p4VPpuxETa_cTHCCUZogT8QDo/s400/mick_babe.jpg?resize=400%2C400&#038;ssl=1" data-recalc-dims="1"/></a></div>
  
     
  As a kid, my baseball hero was Mickey Mantle.  In his 18-year Major League career, he amassed tremendous statistics, and surely he was one of the game&#8217;s all-time greats. When Mantle retired, he was third on the all-time career home run list with 536 home runs, trailing only Babe Ruth (714) and Willie Mays (587). Unfortunately, he suffered numerous injuries, leaving fans to wonder what his numbers would look like if he had enjoyed a healthier career. <p>
  
     
  For decades many people considered (and still consider) Babe Ruth to be the greatest all-around baseball player, because he was a star pitcher and a star hitter.  The counter-argument to the Mantle &#8220;what-if&#8221; is:  what if Ruth had not spent his first six years as a pitcher and instead had been a full-time hitter? (Similarly, what if Ted Williams had not spent some of his prime years in the military.) <p>
  
     
  Nowadays Shohei Ohtani is certainly a once-in-a-generation two-way star.  However, he spent his early prime years in Japan&#8217;s professional baseball, and he may not have enough time left in US baseball to amass these historic lifetime stats.  Aaron Judge is another exceptional modern hitter; hopefully, he stays healthy so we can watch his career numbers climb.  <p>
  
     
  To compare Mantle and Ruth’s lifetime stats objectively, I turned to data. The Sean Lahman baseball dataset contains Major League player stats back to 1871, and is available in the R library <i>lahman</i>.  This was a good opportunity to practice data manipulation using <i>dplyr</i>. <p>
  
     
  
  Ruth played 102 more games than Mantle over a 22-year career (2,503 versus 2,401). His lifetime statistics eclipse Mantle&#8217;s in every offensive category except stolen bases — though Ruth did steal home 10 times and hit nearly twice as many triples, suggesting he was faster than most realize. His lifetime batting average was an impressive .342, sitting just behind Tris Speaker and Ted Williams. <p>
  
     
  
  Lineup protection played a massive role for both men. Ruth generally batted directly before Lou Gehrig, and Mantle batted directly before Yogi Berra. While both Ruth and Mantle drew plenty of walks, presumably pitchers rarely chose to walk them intentionally just to face Gehrig or Berra. <p>
  
     
  
  I was also curious about their defensive metrics. For a fair comparison, I filtered the data to isolate only their outfield appearances. There is no value in comparing an outfield throw to an assist Ruth made on a comeback grounder while pitching. Similarly, I excluded Mantle&#8217;s infield appearances; he primarily played first base in his final two seasons and filled in briefly at other infield spots early in his career. <p>
  
     
  
  Ruth played 222 more outfield games than Mantle (2,241 versus 2,019). Their total outfield putouts were nearly identical, likely because Mantle played centerfield and covered more ground. However, Ruth recorded nearly twice as many outfield assists (204 versus 117), which aligns with the arm strength expected of a former pitcher. While Ruth&#8217;s 204 assists don&#8217;t match stars such as Roberto Clemente&#8217;s 266, it remains a highly respectable number. <p>
  
     
  Ultimately, the data shows that even if you completely ignore his pitching career, Babe Ruth built an outstanding, standalone career as both a hitter and a fielder. <p>
  
<pre>
              
          MANTLE  RUTH
games       2401  2503
at_bats     8102  8398
runs        1677  2174
hits        2415  2873
doubles      344   506
triples       72   136
home_runs    536   714
BA         0.298 0.342
rbi         1509  2217
sb           153   123
bb          1733  2062
so          1710  1330
games_of    2019  2241
putouts     4438  4444
assists      117   204

</pre><p>  
  
      
  Here is my R code:<p>
  
<pre>
library(Lahman)
library(tidyverse)

data(People)
which(People$nameLast == &quot;Mantle&quot;)   # 11773,  playerID = mantlmi01
which(People$nameLast == &quot;Ruth&quot;)   # 16674 , playerID = ruthba01 
data(Batting)    
data(Fielding)   # for fielding, want games in outfield POS == 'OF'

df_fielding &lt;- Fielding %&gt;% 
  filter(playerID %in% c('mantlmi01', 'ruthba01'), POS == 'OF') %&gt;% 
  group_by(playerID) %&gt;% 
  summarize(games_of = sum(G, na.rm = TRUE), putouts = sum(PO, na.rm = TRUE),
    assists = sum(A, na.rm = TRUE)
  )

df &lt;- Batting %&gt;% 
  filter(playerID %in% c('mantlmi01', 'ruthba01')) %&gt;% 
   group_by(playerID) %&gt;% 
   summarize(games = sum(G, na.rm = TRUE), at_bats = sum(AB, na.rm = TRUE),
                runs = sum(R, na.rm = TRUE), hits = sum(H, na.rm = TRUE),
                doubles = sum(X2B, na.rm = TRUE), 
                triples = sum(X3B, na.rm = TRUE), home_runs = sum(HR, na.rm = TRUE),
                BA = round(hits / at_bats,3), 
                rbi = sum(RBI, na.rm = TRUE),  sb = sum(SB, na.rm = TRUE),
                bb = sum(BB, na.rm = TRUE),  so = sum(SO, na.rm = TRUE),
                )  %&gt;%
  merge(df_fielding, by = &quot;playerID&quot;, all.x = TRUE) 

df_transposed &lt;- as.data.frame(t(df))
colnames(df_transposed) &lt;- c(&quot;MANTLE&quot;, &quot;RUTH&quot;)
df_transposed &lt;- df_transposed[-1, ]
df_transposed

</pre><p>
  
End
</font>
                 
                 
<div style="border: 1px solid; background: none repeat scroll 0 0 #EDEDED; margin: 1px; font-size: 13px;">
<div style="text-align: center;">To <strong>leave a comment</strong> for the author, please follow the link and comment on their blog: <strong><a href="https://onlinecollegemathteacher.blogspot.com/2026/07/babe-ruth-how-good-was-he-mantle-versus.html"> Online College Math Teacher</a></strong>.</div>
<hr />
<a href="https://www.r-bloggers.com/" rel="nofollow">R-bloggers.com</a> offers <strong><a href="https://feedburner.google.com/fb/a/mailverify?uri=RBloggers" rel="nofollow">daily e-mail updates</a></strong> about <a title="The R Project for Statistical Computing" href="https://www.r-project.org/" rel="nofollow">R</a> news and tutorials about <a title="R tutorials" href="https://www.r-bloggers.com/how-to-learn-r-2/" rel="nofollow">learning R</a> and many other topics. <a title="Data science jobs" href="https://www.r-users.com/" rel="nofollow">Click here if you're looking to post or find an R/data-science job</a>.

<hr>Want to share your content on R-bloggers?<a href="https://www.r-bloggers.com/add-your-blog/" rel="nofollow"> click here</a> if you have a blog, or <a href="http://r-posts.com/" rel="nofollow"> here</a> if you don't.
</div><strong>Continue reading</strong>: <a href="https://www.r-bloggers.com/2026/07/babe-ruth-how-good-was-he-mantle-versus-ruth/">Babe Ruth:  How good was he?  Mantle versus Ruth</a>]]></content:encoded>
					
		
		<enclosure url="" length="0" type="" />

		<post-id xmlns="com-wordpress:feed-additions:1">402791</post-id>	</item>
		<item>
		<title>New Frontier</title>
		<link>https://www.r-bloggers.com/2026/07/new-frontier/</link>
		
		<dc:creator><![CDATA[Stephen Royle]]></dc:creator>
		<pubDate>Thu, 23 Jul 2026 10:45:00 +0000</pubDate>
				<category><![CDATA[R bloggers]]></category>
		<guid isPermaLink="false">https://quantixed.org/?p=3820</guid>

					<description><![CDATA[<div style = "width:60%; display: inline-block; float:left; "> Remember the “AI rat penis” incident at Frontiers in Cell &#038; Developmental Biology? Well, that was two and a half years ago. That’s enough water under the bridge to now check in and see how this incident affected the journal. If we look at how many papers published, we should ...</div>
<div style = "width: 40%; display: inline-block; float:right;"></div>
<div style="clear: both;"></div>
<strong>Continue reading</strong>: <a href="https://www.r-bloggers.com/2026/07/new-frontier/">New Frontier</a>]]></description>
										<content:encoded><![CDATA[<!-- 
<div style="min-height: 30px;">
[social4i size="small" align="align-left"]
</div>
-->

<div style="border: 1px solid; background: none repeat scroll 0 0 #EDEDED; margin: 1px; font-size: 12px;">
[This article was first published on  <strong><a href="https://quantixed.org/2026/07/23/new-frontier/"> Rstats – quantixed</a></strong>, and kindly contributed to <a href="https://www.r-bloggers.com/" rel="nofollow">R-bloggers</a>].  (You can report issue about the content on this page <a href="https://www.r-bloggers.com/contact-us/">here</a>)
<hr>Want to share your content on R-bloggers?<a href="https://www.r-bloggers.com/add-your-blog/" rel="nofollow"> click here</a> if you have a blog, or <a href="http://r-posts.com/" rel="nofollow"> here</a> if you don't.
</div>

<p class="wp-block-paragraph">Remember the “AI rat penis” incident at Frontiers in Cell &#038; Developmental Biology?</p>



<div data-wp-context="{ "autoclose": false, "accordionItems": [] }" data-wp-interactive="core/accordion" role="group" class="wp-block-accordion is-layout-flow wp-block-accordion-is-layout-flow">
<div data-wp-class--is-open="state.isOpen" data-wp-context="{ "id": "accordion-item-1", "openByDefault": false }" data-wp-init="callbacks.initAccordionItems" data-wp-on-window--hashchange="callbacks.hashChange" class="wp-block-accordion-item is-layout-flow wp-block-accordion-item-is-layout-flow">
<h3 class="wp-block-accordion-heading"><button aria-expanded="false" aria-controls="accordion-item-1-panel" data-wp-bind--aria-expanded="state.isOpen" data-wp-on--click="actions.toggle" data-wp-on--keydown="actions.handleKeyDown" id="accordion-item-1" type="button" class="wp-block-accordion-heading__toggle"><span class="wp-block-accordion-heading__toggle-title">What “AI rat penis” incident? (click here if you don’t remember)</span><span class="wp-block-accordion-heading__toggle-icon" aria-hidden="true">+</span></button></h3>



<div inert aria-labelledby="accordion-item-1" data-wp-bind--inert="!state.isOpen" id="accordion-item-1-panel" role="region" class="wp-block-accordion-panel is-layout-flow wp-block-accordion-panel-is-layout-flow">
<p class="wp-block-paragraph">In Feb 2024, Frontiers in Cell &#038; Developmental Biology published a review paper with two comically bad AI-generated figures. In the first, a rat had a rather large organ. In the second, there was a nonsensical signalling pathway. Both figures had garbled labels. I won’t reproduce them here, but the paper (since retracted) is <a href="https://doi.org/10.3389/fcell.2023.1339390" rel="nofollow" target="_blank">here</a>. An example news piece covering the furore at The Vice is <a href="https://www.vice.com/en/article/scientific-journal-frontiers-publishes-ai-generated-rat-with-gigantic-penis-in-worrying-incident/" rel="nofollow" target="_blank">here</a>.</p>
</div>
</div>
</div>



<p class="wp-block-paragraph">Well, that was two and a half years ago. That’s enough water under the bridge to now check in and see how this incident affected the journal. If we look at how many papers published, we should be able to see whether the incident affected submissions.</p>



<p class="wp-block-paragraph">I will say upfront that <strong>this analysis did not reveal what I thought it would</strong>. It’s well known that Frontiers journals had huge growth some years ago and I also knew that submissions had decreased in the last few years. So, I expected that this drop off was due to authors not wanting to publish in the journal after the AI figure debacle or perhaps a combination of that and the <a href="https://doi.org/10.1162/qss_a_00327" rel="nofollow" target="_blank">study</a> by Mark Hanson and colleagues showing suspiciously fast turnaround times at journals, including titles from this publisher.</p>



<p class="wp-block-paragraph">The plots can be quickly generated using <code>{PubMedLagR}</code> which is available <a href="https://github.com/quantixed/PubMedLagR" rel="nofollow" target="_blank">here</a>.</p>



<p class="wp-block-paragraph">Jump to the <a href="https://quantixed.org/2026/07/23/new-frontier/#code" data-type="internal" data-id="#code" rel="nofollow" target="_blank">code</a>, or just look at the plots.</p>



<p class="wp-block-paragraph">If we pull all the articles in PubMed for this journal and see how many were published per month, we get a plot like this. The dotted line shows the date of the rat penis incident.</p>



<figure data-wp-context="{"imageId":"6a61ff7ec2578"}" data-wp-interactive="core/image" data-wp-key="6a61ff7ec2578" class="wp-block-image size-large wp-lightbox-container"><img loading="lazy" fetchpriority="high" decoding="async" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on--pointerdown="actions.preloadImage" data-wp-on--pointerenter="actions.preloadImageWithDelay" data-wp-on--pointerleave="actions.cancelPreload" data-wp-on-window--resize="callbacks.setButtonStyles" src="https://i2.wp.com/quantixed.org/wp-content/uploads/2026/07/frontiers-1024x768.png?w=450&#038;ssl=1" alt="" class="wp-image-3821" srcset_temp="https://i2.wp.com/quantixed.org/wp-content/uploads/2026/07/frontiers-1024x768.png?w=450&#038;ssl=1 1024w, https://quantixed.org/wp-content/uploads/2026/07/frontiers-300x225.png 300w, https://quantixed.org/wp-content/uploads/2026/07/frontiers-768x576.png 768w, https://quantixed.org/wp-content/uploads/2026/07/frontiers-1536x1152.png 1536w, https://quantixed.org/wp-content/uploads/2026/07/frontiers-2048x1536.png 2048w" sizes="(max-width: 1024px) 100vw, 1024px" data-recalc-dims="1" /><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			data-wp-bind--aria-label="state.thisImage.triggerButtonAriaLabel"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.thisImage.buttonRight"
			data-wp-style--top="state.thisImage.buttonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button></figure>



<p class="wp-block-paragraph">So there was a huge boom in publications in the COVID-19 pandemic era and then a decrease. This decrease predates the rat penis incident. If anything, the number of papers published began to stabilise and perhaps even recover following the incident!</p>



<p class="wp-block-paragraph">It’s a bit hard to see if the composition of articles has changed over time from the plot above. So let’s replot these data and look at the fraction of all articles that are papers versus other types. I did some spot-checking and there were several papers that are clearly Commentary, Editorial and Review types that are not properly tagged on PubMed. So take this with a pinch of salt. The articles are split 50:50 between papers and other types and this has not really changed. It could be argued that commissioned content might be unaffected whereas as directly submitted papers might drop off if authors were concerned about a journal. But there’s no evidence of that here.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" src="https://i2.wp.com/quantixed.org/wp-content/uploads/2026/07/frontiers_scaled-1024x768.png?w=450&#038;ssl=1" alt="" class="wp-image-3822" srcset_temp="https://i2.wp.com/quantixed.org/wp-content/uploads/2026/07/frontiers_scaled-1024x768.png?w=450&#038;ssl=1 1024w, https://quantixed.org/wp-content/uploads/2026/07/frontiers_scaled-300x225.png 300w, https://quantixed.org/wp-content/uploads/2026/07/frontiers_scaled-768x576.png 768w, https://quantixed.org/wp-content/uploads/2026/07/frontiers_scaled-1536x1152.png 1536w, https://quantixed.org/wp-content/uploads/2026/07/frontiers_scaled-2048x1536.png 2048w" sizes="(max-width: 1024px) 100vw, 1024px" data-recalc-dims="1" /></figure>



<p class="wp-block-paragraph">This is looking at published papers. Obviously this metric lags behind the author behaviour we’re interested in. Did the rat penis incident affect <em>submissions</em> to the journal? We can look at the received dates of published papers:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" src="https://i1.wp.com/quantixed.org/wp-content/uploads/2026/07/frontiers_subs-1024x768.png?w=450&#038;ssl=1" alt="" class="wp-image-3823" srcset_temp="https://i1.wp.com/quantixed.org/wp-content/uploads/2026/07/frontiers_subs-1024x768.png?w=450&#038;ssl=1 1024w, https://quantixed.org/wp-content/uploads/2026/07/frontiers_subs-300x225.png 300w, https://quantixed.org/wp-content/uploads/2026/07/frontiers_subs-768x576.png 768w, https://quantixed.org/wp-content/uploads/2026/07/frontiers_subs-1536x1152.png 1536w, https://quantixed.org/wp-content/uploads/2026/07/frontiers_subs-2048x1536.png 2048w" sizes="(max-width: 1024px) 100vw, 1024px" data-recalc-dims="1" /></figure>



<p class="wp-block-paragraph">Pretty much the same story: month-on-moth submission are steadily rising after the incident.</p>



<p class="wp-block-paragraph">Obviously we only have submission data for papers that were eventually published in the journal. We don’t know what the rejection rate was over this period. It would be possible for a beleaguered journal to reduce the rejection rate to stabilise the numbers of papers it publishes. But if we assume the rejection rate is constant, then submissions follow similar dynamics.</p>



<p class="wp-block-paragraph"><strong>Conclusion: the AI debacle didn’t negatively affect submissions at this journal.</strong></p>



<p class="wp-block-paragraph">Maybe potential authors were unaware of this issue (although there was plenty of publicity), or maybe they view the incident as a one-off, or perhaps they’re not concerned about science integrity issues.</p>



<p class="wp-block-paragraph">It’s no secret that the biggest drivers of journal choice for authors are 1) the journal impact factor and 2) the turnaround time/hassle to publish the work. The journals with the highest impact factor and the fastest turnaround win big. A scandal like this doesn’t seem to have affected journal choice. Of course, this is just a simple analysis and there are many factors at play here.</p>



<p class="wp-block-paragraph">Isn’t it ironic though that authors want to publish in a journals with high impact factors? They want their paper to be viewed as potentially highly citable because of where it is published; but if that means that their paper appeared in a journal that has a scientific integrity issue, the cry is “judge the paper on its own merits, not where it’s published”…</p>



<h2 id="code" class="wp-block-heading">The code</h2>


<pre>
library(PubMedLagR)
library(ggplot2)

retrieve_journal_year_records(&quot;Front Cell Dev Biol&quot;, 2015:2026, batch_size = 200, papers_only = FALSE)
all &lt;- pubmed_xmls_to_df(clean = FALSE)
# remove duplicate rows
all &lt;- all[!duplicated(all),]
# clear Data/ and then
retrieve_journal_year_records(&quot;Front Cell Dev Biol&quot;, 2015:2026, batch_size = 200)
pprs &lt;- pubmed_xmls_to_df()
# classify the papers in all
all$paper &lt;- ifelse(all$pmid %in% unique(pprs$pmid),&quot;paper&quot;, &quot;other&quot;)
# convert publication date to the first of the month
all$year_month &lt;- as.Date(paste0(substr(all$pubdate,1,7),&quot;-01&quot;))

# frontiers colours for fun
x &lt;- c(&quot;242 130 91&quot;, &quot;24 157 196&quot;)
fcolours &lt;- sapply(strsplit(x, &quot; &quot;), function(x)
  rgb(x[1], x[2], x[3], maxColorValue=255))

# ggplot of number of papers per month-year
p1 &lt;- ggplot(all, aes(x = year_month, fill = paper)) +
  geom_bar() +
  scale_fill_manual(values = fcolours) +
  geom_vline(xintercept = as.POSIXct(as.Date(&quot;2024-02-14&quot;)), linetype=2) +
  labs(x = &quot;&quot;, y = &quot;Papers per month&quot;) +
  theme_classic()
p1

# stacked plot version
p2 &lt;- ggplot(all, aes(x = year_month, fill = paper)) +
  geom_bar(position = &quot;fill&quot;) +
  scale_fill_manual(values = fcolours) +
  geom_vline(xintercept = as.POSIXct(as.Date(&quot;2024-02-14&quot;)), linetype=2) +
  labs(x = &quot;&quot;, y = &quot;Composition&quot;) +
  theme_classic()
p2

# what about submissions?
all$sub_year_month &lt;- as.Date(paste0(substr(all$recdate,1,7),&quot;-01&quot;))
p3 &lt;- ggplot(all, aes(x = sub_year_month, fill = paper)) +
  geom_bar() +
  scale_fill_manual(values = fcolours) +
  geom_vline(xintercept = as.POSIXct(as.Date(&quot;2024-02-14&quot;)), linetype=2) +
  labs(x = &quot;&quot;, y = &quot;Papers per month&quot;) +
  theme_classic()
p3
</pre>


<p class="wp-block-paragraph">I added some styling to the plots to post them here, but the code will give the same three plots as in the post.</p>



<p class="wp-block-paragraph">—</p>



<p class="wp-block-paragraph">The post title comes from “New Frontier” by Donald Fagen from his 1982 “The Nightfly” LP.</p>

<div style="border: 1px solid; background: none repeat scroll 0 0 #EDEDED; margin: 1px; font-size: 13px;">
<div style="text-align: center;">To <strong>leave a comment</strong> for the author, please follow the link and comment on their blog: <strong><a href="https://quantixed.org/2026/07/23/new-frontier/"> Rstats – quantixed</a></strong>.</div>
<hr />
<a href="https://www.r-bloggers.com/" rel="nofollow">R-bloggers.com</a> offers <strong><a href="https://feedburner.google.com/fb/a/mailverify?uri=RBloggers" rel="nofollow">daily e-mail updates</a></strong> about <a title="The R Project for Statistical Computing" href="https://www.r-project.org/" rel="nofollow">R</a> news and tutorials about <a title="R tutorials" href="https://www.r-bloggers.com/how-to-learn-r-2/" rel="nofollow">learning R</a> and many other topics. <a title="Data science jobs" href="https://www.r-users.com/" rel="nofollow">Click here if you're looking to post or find an R/data-science job</a>.

<hr>Want to share your content on R-bloggers?<a href="https://www.r-bloggers.com/add-your-blog/" rel="nofollow"> click here</a> if you have a blog, or <a href="http://r-posts.com/" rel="nofollow"> here</a> if you don't.
</div><strong>Continue reading</strong>: <a href="https://www.r-bloggers.com/2026/07/new-frontier/">New Frontier</a>]]></content:encoded>
					
		
		<enclosure url="" length="0" type="" />

		<post-id xmlns="com-wordpress:feed-additions:1">402786</post-id>	</item>
	</channel>
</rss>
