<?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>Wed, 29 Jul 2026 12:43:07 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=5.5.18</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>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>
		<item>
		<title>controller: tidy messy terminology in R with controlled vocabularies</title>
		<link>https://www.r-bloggers.com/2026/07/controller-tidy-messy-terminology-in-r-with-controlled-vocabularies/</link>
		
		<dc:creator><![CDATA[Joe Roe]]></dc:creator>
		<pubDate>Thu, 23 Jul 2026 00:00:00 +0000</pubDate>
				<category><![CDATA[R bloggers]]></category>
		<guid isPermaLink="false">https://joeroe.io/2026/07/23/controller-0.1.0</guid>

					<description><![CDATA[<p>controller is an R package for working with controlled vocabularies.<br />
It’s first release (v0.1.0) is now available now on CRAN.</p>
<p>The package addresses something I find myself doing very often in analysis code: tidying messy and inconsistent terminologi...</p>
<strong>Continue reading</strong>: <a href="https://www.r-bloggers.com/2026/07/controller-tidy-messy-terminology-in-r-with-controlled-vocabularies/">controller: tidy messy terminology in R with controlled vocabularies</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/23/controller-0.1.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><a href="https://controller.joeroe.io/" rel="nofollow" target="_blank">controller</a> is an R package for working with controlled vocabularies. 
It’s first release (v0.1.0) is now available now <a href="https://cran.r-project.org/package=controller" rel="nofollow" target="_blank">on CRAN</a>.</p>

<p>The package addresses something I find myself doing very often in analysis code: tidying messy and inconsistent terminologies.
For smaller datasets, <code>dplyr::recode()</code> is okay for this, but writing the mapping out as an R function call gets tedious fast when dealing with a long list of terms.
It becomes <em>very</em> tedious when you have variants distinguished only by things like capitalisation (<code>OxA-</code> vs. <code>oxa-</code>), word boundaries (<code>Çatalhöyük</code> vs. <code>Çatal Höyük</code>) or character encoding (<code>ʿAin Ghazal</code> vs. <code>ʽAyn Ghazal</code>).</p>

<p>controller instead defines preferred terms and their variants in a data frame.
Its <code>control()</code> verb is the equivalent of <code>dplyr::recode()</code> but using this thesaurus and with a few extra bells and whistles for fuzzy matching and reporting what was (and wasn’t) changed:</p>

<pre>library(controller)
data(&quot;colour_thesaurus&quot;)

shades &lt;- c(&quot;daffodil&quot;, &quot;purple&quot;, &quot;magenta&quot;, &quot;azure&quot;, &quot;navy&quot;, &quot;violet&quot;)
control(shades, colour_thesaurus)
#&gt; Replaced values:
#&gt; &#x2139; daffodil → yellow
#&gt; &#x2139; azure → blue
#&gt; &#x2139; navy → blue
#&gt; &#x2139; violet → purple
#&gt; Warning: Some values of `x` were not matched in `thesaurus`:
#&gt; &#x2716; magenta
</pre>

<p>Fuzzy matching means we don’t need to exhaustively list those variants from things like differences in case, word boundaries, or character encoding:</p>

<pre>control_ci(toupper(shades), colour_thesaurus)
#&gt; Replaced values:
#&gt; &#x2139; DAFFODIL → yellow
#&gt; &#x2139; PURPLE → purple
#&gt; &#x2139; AZURE → blue
#&gt; &#x2139; NAVY → blue
#&gt; &#x2139; VIOLET → purple
#&gt; [1] &quot;yellow&quot;  &quot;purple&quot;  &quot;MAGENTA&quot; &quot;blue&quot;    &quot;blue&quot;    &quot;purple&quot;
#&gt; Warning message:
#&gt; Some values of `x` were not matched in `thesaurus`:
#&gt; &#x2716; MAGENTA
</pre>

<hr />

<p>This package has been hanging around for a while!
It started off as a helper function I used for cleaning up site names from prehistoric sites in Southwest Asia.
The basic idea was inspired by similar functions that used to exist in <a href="https://github.com/ISAAKiel/c14bazAAR" rel="nofollow" target="_blank">c14bazAAR</a> for cleaning sample metadata for radiocarbon date, that I thought were quite neat.
So when the maintainers of that package decided to deprecate those, I took over the thesauri as part of <a href="https://c14.joeroe.io/" rel="nofollow" target="_blank">c14</a> and spun the supporting functions off into controller as a standalone package.
Then over the years it acquired some more functionality for working with controlled vocabularies (a surprising gap in the R ecosystem), like reading heritage vocabularies in <a href="https://heritage-standards.org.uk/fish-vocabularies/" rel="nofollow" target="_blank">Historic England’s FISH format</a>.
Five years later, I am finally getting around to releasing it on CRAN because I need to release c14 on CRAN, because <em>that’s</em> used in analyses I’m now publishing.
It’s the research software engineering of <a href="https://www.youtube.com/watch?v=5W4NFcamRhM" rel="nofollow" target="_blank">changing a lightbulb</a>, basically.</p>

<hr />

<p>The first release of controller includes:</p>

<ul>
  <li><code>control()</code>, <code>control_ci()</code>, and <code>control_fuzzy()</code> for recoding values</li>
  <li><code>control_names()</code>, <code>control_names_ci()</code>, and <code>control_names_fuzzy()</code> for recoding names</li>
  <li><code>control_matches()</code> for inspecting how matches were made</li>
  <li><code>read_fish()</code> for reading vocabularies in <a href="https://heritage-standards.org.uk/fish-vocabularies/" rel="nofollow" target="_blank">Historic England’s FISH format</a></li>
  <li><code>colour_thesaurus</code>, an example dataset</li>
</ul>

<p>You can install it from CRAN:</p>

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

<p>Or the development version from GitHub:</p>

<pre>remotes::install_github(&quot;joeroe/controller&quot;)
</pre>

<p>You can find the full documentation at <a href="https://controller.joeroe.io/" rel="nofollow" target="_blank">https://controller.joeroe.io</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://joeroe.io/2026/07/23/controller-0.1.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/controller-tidy-messy-terminology-in-r-with-controlled-vocabularies/">controller: tidy messy terminology in R with controlled vocabularies</a>]]></content:encoded>
					
		
		<enclosure url="" length="0" type="" />

		<post-id xmlns="com-wordpress:feed-additions:1">402802</post-id>	</item>
		<item>
		<title>muttest 0.3.0: Turn surviving mutants into a to-do list</title>
		<link>https://www.r-bloggers.com/2026/07/muttest-0-3-0-turn-surviving-mutants-into-a-to-do-list/</link>
		
		<dc:creator><![CDATA[Jakub Sobolewski]]></dc:creator>
		<pubDate>Wed, 22 Jul 2026 22:00:00 +0000</pubDate>
				<category><![CDATA[R bloggers]]></category>
		<guid isPermaLink="false">https://jakubsobolewski.com/blog/muttest-0_3_0</guid>

					<description><![CDATA[<div style = "width:60%; display: inline-block; float:left; "> HTML and JSON reporting, and smarter scoring for mutation testing in 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/07/muttest-0-3-0-turn-surviving-mutants-into-a-to-do-list/">muttest 0.3.0: Turn surviving mutants into a to-do list</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://jakubsobolewski.com/blog/muttest-0_3_0"> Jakub Sobolewski</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><img src="https://i1.wp.com/jakubsobolewski.com/blog/muttest-0_3_0/og-image.png?w=578&#038;ssl=1" alt="muttest 0.3.0: Turn surviving mutants into a to-do list" data-recalc-dims="1" /></p><p><a href="https://github.com/jakubsob/muttest" rel="nofollow" target="_blank"><code>muttest</code></a> so far only printed to the console which mutants were killed and which survived.</p>
<p>That’s the minimal setup you need to act on mutation testing findings, but it’s far from optimal. Clear the terminal, close the IDE, and the results are gone unless you saved the output.</p>
<p><code>muttest@0.3.0</code> fixes that with an HTML report.</p>
<ol>
<li>Run your tests with new JSON reporter.</li>
<li>Render the report.</li>
<li>Open it in your browser, and every mutant is laid over your source code.</li>
</ol>
<p>Click the ones that survived and see exactly what slipped past your suite. That list of survivors is your to-do list: every one is a candidate test. You decide which are worth writing and which are just noise.</p>
<blockquote>
<p><img src="https://s.w.org/images/core/emoji/13.0.0/72x72/1f4dd.png" alt="📝" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Read the full changelog <a href="https://github.com/jakubsob/muttest/blob/main/NEWS.md" rel="nofollow" target="_blank">here</a>.</p>
</blockquote>
<h2 id="new-to-mutation-testing">New to mutation testing?</h2>
<p>Coverage tells you which lines ran. It says nothing about whether your tests would notice if those lines were wrong. You can delete every assertion in your suite, run <code>covr</code>, and still see 100%.</p>
<p>Mutation testing asks the harder question: <em>if this code were subtly broken, would a test fail?</em> It makes small changes to your source (<code>&gt;</code> becomes <code>&gt;=</code>, <code>TRUE</code> becomes <code>FALSE</code>) and reruns your tests against each version. Each changed version is a <strong>mutant</strong>. If a test fails, the mutant is <strong>killed</strong>. If every test still passes, the mutant <strong>survived</strong>, and you’ve found a gap.</p>
<p>A surviving mutant isn’t a bug to fix. It’s a missing test that could hide an expensive bug later.</p>
<p>If you want to dive deeper, the <a href="https://jakubsobolewski.com/blog/muttest-0_2_0" rel="nofollow" target="_blank">0.2.0 post</a> walks through it with an example.</p>
<h2 id="the-report">The report</h2>
<p>Run your mutation tests with <code>JSONMutationReporter</code>, call <code>report()</code>, and you get a self-contained HTML file.</p>
<p><img alt="HTML report" loading="lazy" decoding="async" fetchpriority="auto" width="450" src="https://jakubsobolewski.com/_astro/1.BnUOu2qB_Z2dRrSv.webp" ></p>
<p><img alt="HTML report" loading="lazy" decoding="async" fetchpriority="auto" width="450" src="https://jakubsobolewski.com/_astro/2.MUnYt7vW_Z1vdtA.webp" ></p>
<p>See the full example report <a href="https://jakubsob.github.io/muttest/report/muttest.html" rel="nofollow" target="_blank">here</a>.</p>
<p>Here’s what the report does that the console can’t do:</p>
<ul>
<li><strong>Your source code annotated with mutants.</strong> Every file is shown with its actual code, and each mutated line is marked inline. You read the survivor in context instead of reconstructing where a given line was.</li>
<li><strong>Per-file scores.</strong> The overall number is a starting point, not a diagnosis. The report breaks the score down by file, so you can see your parser sitting at 95% while the validation module is at 40%. That tells you which file to open first.</li>
<li><strong>Per-line mutant diffs.</strong> Click a mutant and see exactly what changed: the original line, the mutated line, and whether your tests killed it. When something survived, the diff tells you what kind of a potential bug slipped through.</li>
<li><strong>Filter by status.</strong> The report opens focused on survivors, since the killed mutants already did their job. You can bring the others back when you want the full picture, but the default is the view you actually came for.</li>
<li><strong>Keyboard navigation.</strong> Step through mutants without scrolling through the whole file.</li>
</ul>
<p>That’s the workflow – filter to survivors, walk the list top to bottom, and each one is a decision: write the test, or call it noise and move on.</p>
<p>A checklist you can work through.</p>
<h2 id="json-output">JSON output</h2>
<p>The new <code>JSONMutationReporter</code> writes results to a file that conforms to the <a href="https://github.com/stryker-mutator/mutation-testing-elements/blob/master/packages/report-schema/src/mutation-testing-report-schema.json" rel="nofollow" target="_blank">mutation-testing-elements</a> schema. That schema isn’t something I invented. It’s the format shared by StrykerJS, Stryker.NET, Stryker for Scala, and others. If other teams in your organization already use Stryker and its reporting tools, you can plug <code>muttest</code> results straight into the same dashboards.</p>
<pre>library(muttest)

plan &lt;- muttest_plan(
  source_files = &quot;R/shipping.R&quot;,
  mutators = comparison_operators()
)

muttest(plan, reporter = JSONMutationReporter$new())

report()</pre>
<p><code>JSONMutationReporter</code> writes to <code>muttest.json</code> by default, and <code>report()</code> reads that same file and writes <code>muttest.html</code> next to it, so with the defaults there’s nothing to wire up.</p>
<p>If you don’t like the built-in report, the JSON file is there to build your own. I plan to keep this schema stable so don’t worry about your report breaking with every next release.</p>
<h2 id="watch-it-run-save-it-for-later">Watch it run, save it for later</h2>
<p>You usually want both: a live progress table while the run happens, and a saved file to open afterward. Before, you picked one reporter and got one behavior.</p>
<p><code>MultiReporter</code> runs several reporters at once. Feed it a <code>ProgressMutationReporter</code> and a <code>JSONMutationReporter</code> together. The console fills up as mutants are tested, and the JSON file is waiting when it’s done.</p>
<pre>muttest(
  plan,
  reporter = MultiReporter$new(
    ProgressMutationReporter$new(),
    JSONMutationReporter$new()
  )
)</pre>
<p>It’s exactly the same idea as <code>testthat</code>’s <a href="https://testthat.r-lib.org/reference/MultiReporter.html" rel="nofollow" target="_blank"><code>MultiReporter</code></a>.</p>
<h2 id="scoring-changes-worth-knowing-about">Scoring changes worth knowing about</h2>
<p>Two changes in this release will move your score:</p>
<ul>
<li><strong>Errored mutants now count as killed.</strong> Some mutations don’t just fail an expectation; they make the code throw before a test can even assert anything. A mutation that produces an error is still a mutation your suite detected, so 0.3.0 scores it as killed. This matches PIT, Stryker, and mutmut. Previously <code>muttest</code> counted these as survived, which was too harsh: the test <em>did</em> catch the change, it just caught it by blowing up.</li>
<li><strong>Uncovered code gets its own category.</strong> Under <code>FileTestStrategy</code>, a mutant in a source file with no matching test file used to look identical to a mutant your tests ran and missed. Those are different problems. A survived mutant means your tests are weak; an uncovered mutant means there are no tests at all. 0.3.0 reports uncovered mutants as a separate <code>no coverage</code> category and leaves them out of the score, so untested code stops masquerading as escaped mutants and dragging your number down for the wrong reason.</li>
</ul>
<p>If your score shifts after upgrading, this is why. It’s more honest this way.</p>
<h2 id="tell-me-about-your-experience-of-using-muttest">Tell me about your experience of using <code>muttest</code></h2>
<p>I hope this release makes it easier to analyze results.</p>
<p><code>muttest</code> is still young and the interface may shift. If the report is missing something you’d want to see, if a mutation you care about has no way to be expressed, or if the new scoring surprises you in a way that feels wrong, open an issue on <a href="https://github.com/jakubsob/muttest/issues" rel="nofollow" target="_blank">GitHub</a>.</p>
<p>Feature requests are just as welcome as bug reports.</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://jakubsobolewski.com/blog/muttest-0_3_0"> Jakub Sobolewski</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/muttest-0-3-0-turn-surviving-mutants-into-a-to-do-list/">muttest 0.3.0: Turn surviving mutants into a to-do list</a>]]></content:encoded>
					
		
		<enclosure url="" length="0" type="" />

		<post-id xmlns="com-wordpress:feed-additions:1">402804</post-id>	</item>
		<item>
		<title>Little useless-useful R functions – Jug solver with Bezout’s Identity</title>
		<link>https://www.r-bloggers.com/2026/07/little-useless-useful-r-functions-jug-solver-with-bezouts-identity/</link>
		
		<dc:creator><![CDATA[tomaztsql]]></dc:creator>
		<pubDate>Tue, 21 Jul 2026 19:15:27 +0000</pubDate>
				<category><![CDATA[R bloggers]]></category>
		<guid isPermaLink="false">http://tomaztsql.wordpress.com/?p=11182</guid>

					<description><![CDATA[<p>We all were presented with this problem – water jug problem, which – in the time of Football world cup 2026 – can be translated to any liquid. *hint hint* But the riddle is as logical as mathematical. With mathematics…Read more ›</p>
<strong>Continue reading</strong>: <a href="https://www.r-bloggers.com/2026/07/little-useless-useful-r-functions-jug-solver-with-bezouts-identity/">Little useless-useful R functions – Jug solver with Bezout’s Identity</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/07/21/little-useless-useful-r-functions-jug-solver-with-bezouts-identity/"> 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 all were presented with this problem – water jug problem, which – in the time of Football world cup 2026 – can be translated to any liquid. *hint hint*  But the riddle is as logical as mathematical. With mathematics finding the greatest common divisor. In general, it can be used with state search or Depth First Search (DFS). </p>



<p class="wp-block-paragraph">With DFS we can solve this with <a href="https://en.wikipedia.org/wiki/B%C3%A9zout%27s_identity" rel="nofollow" target="_blank">Bezout’s identity;</a> which in general is a theorem which relates two arbitraty integers with their greatests common divisor; and used in algebraic language, finding common zeros of n-polznomials in n-indeterminates. So the common zeros equals the product of the degrees of the polynomials.</p>


<div class="wp-block-image">
<figure class="aligncenter size-large"><a href="https://i0.wp.com/tomaztsql.wordpress.com/wp-content/uploads/2026/07/water_jug_puzzle_solver-1.gif?ssl=1" rel="nofollow" target="_blank"><img loading="lazy" data-attachment-id="11189" data-permalink="https://tomaztsql.wordpress.com/2026/07/21/little-useless-useful-r-functions-jug-solver-with-bezouts-identity/water_jug_puzzle_solver-2/" data-orig-file="https://tomaztsql.wordpress.com/wp-content/uploads/2026/07/water_jug_puzzle_solver-1.gif" data-orig-size="480,320" 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="Water_jug_puzzle_solver" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/tomaztsql.wordpress.com/wp-content/uploads/2026/07/water_jug_puzzle_solver-1.gif?w=450&#038;ssl=1" src="https://i0.wp.com/tomaztsql.wordpress.com/wp-content/uploads/2026/07/water_jug_puzzle_solver-1.gif?w=450&#038;ssl=1" alt="" class="wp-image-11189" srcset_temp="https://tomaztsql.wordpress.com/wp-content/uploads/2026/07/water_jug_puzzle_solver-1.gif 480w, https://tomaztsql.wordpress.com/wp-content/uploads/2026/07/water_jug_puzzle_solver-1.gif?w=150 150w, https://tomaztsql.wordpress.com/wp-content/uploads/2026/07/water_jug_puzzle_solver-1.gif?w=300 300w" sizes="(max-width: 480px) 100vw, 480px" data-recalc-dims="1" /></a></figure>
</div>


<p class="wp-block-paragraph">And now that the imagine splitting the 16L <a href="https://www.thebeergiraffe.com/blog/what-is-a-beer-giraffe" rel="nofollow" target="_blank">beer Giraffe </a>in two 8L Giraffes but you are only using 11L and 7L empty giraffes <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">This is the proof that with beer, Algebra is more fun <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 because it is fun, we can also find greated common divisors using Breadth-First Search (BFS). And here is the code:</p>



<pre>
solve_jugs &lt;- function(caps = c(16, 11, 7), start = c(16, 0, 0), goal = c(8, 8, 0)) {
  # BFS over all (a, b, c) states
  # Each state is a named integer vector of water = amount is each jug or ?????
  
  queue   &lt;- list(list(state = start, path = list(start)))
  visited &lt;- list()
  key     &lt;- function(s) paste(s, collapse = &quot;-&quot;)
  
  while (length(queue) &gt; 0) {
    node  &lt;- queue[[1]]
    queue &lt;- queue[-1]
    s     &lt;- node$state
    
    if (isTRUE(all(s == goal))) return(node$path)
    if (!is.null(visited[[key(s)]])) next
    visited[[key(s)]] &lt;- TRUE
    
    n &lt;- length(s)
    for (from in 1:n) {
      for (to in 1:n) {
        if (from == to || s[from] == 0 || s[to] == caps[to]) next
        
        pour    &lt;- min(s[from], caps[to] - s[to])
        new_s   &lt;- s
        new_s[from] &lt;- s[from] - pour
        new_s[to]   &lt;- s[to]   + pour
        
        if (is.null(visited[[key(new_s)]])) {
          queue &lt;- c(queue, list(list(
            state = new_s,
            path  = c(node$path, list(new_s))
          )))
        }
      }
    }
  }
  NULL  # no solution; add message or smht :)
}

solution &lt;- solve_jugs()

 
for (step in solution) {
  cat(sprintf(&quot;  %-4d  %-4d  %-4d\n&quot;, step[1], step[2], step[3]))
}
  </pre>



<p class="wp-block-paragraph">And the final solution will reveal the steps and actions:</p>



<pre>  16    0     0   
  5     11    0   
  5     4     7   
  12    4     0   
  12    0     4   
  1     11    4   
  1     8     7   
  8     8     0   
  </pre>



<p class="wp-block-paragraph">Similar steps are presented on the animation above.</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 code to the animation  is <a href="https://github.com/tomaztk/Useless_R_functions/blob/main/functions/WaterJugSolver_Animation.R" rel="nofollow" target="_blank">here</a> (same Github repository).</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>



<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://tomaztsql.wordpress.com/2026/07/21/little-useless-useful-r-functions-jug-solver-with-bezouts-identity/"> 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/07/little-useless-useful-r-functions-jug-solver-with-bezouts-identity/">Little useless-useful R functions – Jug solver with Bezout’s Identity</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/07/water_jug_puzzle_solver-1.gif?w=480" length="0" type="" />

		<post-id xmlns="com-wordpress:feed-additions:1">402745</post-id>	</item>
		<item>
		<title>A world still to be mapped: reflections on geocomputation in R: takeaways from the talk and workshop at UseR! 2026</title>
		<link>https://www.r-bloggers.com/2026/07/a-world-still-to-be-mapped-reflections-on-geocomputation-in-r-takeaways-from-the-talk-and-workshop-at-user-2026/</link>
		
		<dc:creator><![CDATA[Jakub Nowosad]]></dc:creator>
		<pubDate>Tue, 21 Jul 2026 00:00:00 +0000</pubDate>
				<category><![CDATA[R bloggers]]></category>
		<guid isPermaLink="false">https://jakubnowosad.com/posts/2026-07-21-user/</guid>

					<description><![CDATA[<div style = "width:60%; display: inline-block; float:left; ">
<p>At useR! 2026 in Warsaw, I contributed to a workshop on Geocomputation with R (July 6, 2026) and gave a keynote entitled A world still to be mapped: reflections on geocomputation in R (July 8, 2026). Both were opportunities to consider what the ...</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/a-world-still-to-be-mapped-reflections-on-geocomputation-in-r-takeaways-from-the-talk-and-workshop-at-user-2026/">A world still to be mapped: reflections on geocomputation in R: takeaways from the talk and workshop at UseR! 2026</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://jakubnowosad.com/posts/2026-07-21-user/"> Thinking in spatial patterns</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>At <a href="https://user2026.r-project.org/" rel="nofollow" target="_blank">useR! 2026</a> in Warsaw, I contributed to a workshop on <em>Geocomputation with R</em> (July 6, 2026) and gave a keynote entitled <em>A world still to be mapped: reflections on geocomputation in R</em> (July 8, 2026). Both were opportunities to consider what the R spatial ecosystem already makes possible, its strengths, limitations, and what remains to be done.</p>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://jakubnowosad.com/user2026/" rel="nofollow" target="_blank"><img src="https://i1.wp.com/jakubnowosad.com/posts/2026-07-21-user/user2026-title-slide.png?w=578&#038;ssl=1" class="img-fluid figure-img" data-recalc-dims="1"></a></p>
<figcaption>Title slide of the talk</figcaption>
</figure>
</div>
<p><strong>Keynote slides:</strong> <a href="https://jakubnowosad.com/user2026/" class="uri" rel="nofollow" target="_blank">https://jakubnowosad.com/user2026/</a></p>
<p><strong>Workshop materials:</strong> <a href="https://github.com/geocompx/user26" class="uri" rel="nofollow" target="_blank">https://github.com/geocompx/user26</a></p>
<section id="workshop" class="level2">
<h2 class="anchored" data-anchor-id="workshop">Workshop</h2>
<p>The workshop, led by Jannes Muenchow and based on the second edition of <a href="https://r.geocompx.org/" rel="nofollow" target="_blank"><em>Geocomputation with R</em></a>, introduced some of the core building blocks of spatial work in R. It covered vector data with the <strong>sf</strong> package, raster data with the <strong>terra</strong> package, and spatial data visualization with the <strong>tmap</strong> package. I presented the visualization part, showing the main ingredients of the mapping workflow and demonstrating how maps can be used to explore geographic data and communicate analytical results.</p>
<p>These tools represent a mature and increasingly interoperable ecosystem. They make it possible to import, manipulate, analyze, and visualize geographic data while drawing on R’s wider capabilities for data processing and statistics. The workshop combined presentations, live coding, and exercises to provide a practical starting point for working with these tools. You can try the exercises yourself by following the instructions in <a href="https://github.com/geocompx/user26" rel="nofollow" target="_blank">the workshop materials</a>.</p>
</section>
<section id="talk" class="level2">
<h2 class="anchored" data-anchor-id="talk">Talk</h2>
<p>At UseR! 2026, <a href="https://jakubnowosad.com/user2026/" rel="nofollow" target="_blank">I spoke about geocomputation in R</a> through the lens of my work as a computational geographer. I started by showing that geography is not only about drawing maps or attaching coordinates to data. For me, it is a way of asking questions about what is happening, where it is happening, why it is happening there, and how those patterns change over time. To answer those questions, I use a combination of spatial data, statistical models, and visualization.</p>
<p>I also reflected on how far the R spatial ecosystem has come. Over the last few decades, R has grown into a strong environment for spatial analysis, with tools for vector and raster data, visualization, reproducibility, and integration with broader geospatial infrastructure. At the same time, some of the most important gaps are no longer just technical. We can keep building better packages, but that alone will not solve problems like weak validation practices or misleading maps – the challenge is not only to make better maps, but to make predictions and maps that we can trust. For these purposes, I discussed ideas such as prediction-domain adaptive evaluation in the context of spatial machine learning and the importance of proper color palettes and projection choices in the context of spatial visualization.</p>
<p>My conclusion was that the future of geocomputation in R depends as much on community as on code. The R spatial ecosystem is strong in scientific rigor, geospatial infrastructure, visualization, and reproducible workflows, but these strengths depend on an active community. Good spatial work still requires data, domain knowledge, careful evaluation, and honest communication. We should, therefore, continue building tools while also supporting people who maintain software, share examples and expertise, mentor others, and connect methods to real-world problems.</p>


</section>

<div id="quarto-appendix" class="default"><section class="quarto-appendix-contents" id="quarto-citation"><h2 class="anchored quarto-appendix-heading">Citation</h2><div><div class="quarto-appendix-secondary-label">BibTeX citation:</div><pre>@online{nowosad2026,
  author = {Nowosad, Jakub},
  title = {A World Still to Be Mapped: Reflections on Geocomputation in
    {R:} Takeaways from the Talk and Workshop at {UseR!} 2026},
  date = {2026-07-21},
  url = {https://jakubnowosad.com/posts/2026-07-21-user/},
  langid = {en}
}
</pre><div class="quarto-appendix-secondary-label">For attribution, please cite this work as:</div><div id="ref-nowosad2026" class="csl-entry quarto-appendix-citeas">
Nowosad, Jakub. 2026. <span>“A World Still to Be Mapped: Reflections on
Geocomputation in R: Takeaways from the Talk and Workshop at UseR!
2026.”</span> July 21. <a href="https://jakubnowosad.com/posts/2026-07-21-user/" rel="nofollow" target="_blank">https://jakubnowosad.com/posts/2026-07-21-user/</a>.
</div></div></section></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://jakubnowosad.com/posts/2026-07-21-user/"> Thinking in spatial patterns</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/a-world-still-to-be-mapped-reflections-on-geocomputation-in-r-takeaways-from-the-talk-and-workshop-at-user-2026/">A world still to be mapped: reflections on geocomputation in R: takeaways from the talk and workshop at UseR! 2026</a>]]></content:encoded>
					
		
		<enclosure url="" length="0" type="" />

		<post-id xmlns="com-wordpress:feed-additions:1">402715</post-id>	</item>
		<item>
		<title>Level With Me: Can the WGI Predict the WJP’s Rule of Law Scores?</title>
		<link>https://www.r-bloggers.com/2026/07/level-with-me-can-the-wgi-predict-the-wjps-rule-of-law-scores/</link>
		
		<dc:creator><![CDATA[Giles Dickenson-Jones]]></dc:creator>
		<pubDate>Mon, 20 Jul 2026 23:30:00 +0000</pubDate>
				<category><![CDATA[R bloggers]]></category>
		<guid isPermaLink="false">https://www.gilesd-j.com/?p=4254</guid>

					<description><![CDATA[<div style = "width:60%; display: inline-block; float:left; "> TLDR: The first post established that the WGI and WJP rule of law measures agree on how they rank countries. […]<br />
The post Level With Me: Can the WGI Predict the WJP’s Rule of Law Scores? appeared first on Giles.</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/level-with-me-can-the-wgi-predict-the-wjps-rule-of-law-scores/">Level With Me: Can the WGI Predict the WJP’s Rule of Law Scores?</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.gilesd-j.com/2026/07/21/level-with-me-can-the-wgi-predict-the-wjps-rule-of-law-scores/"> Data Analytics and AI Archives - Giles</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"><strong>TLDR:</strong> The first post established that the WGI and WJP rule of law measures agree on how they rank countries. This follow-up tests the stricter question of whether the WGI can predict the WJP’s <em>levels</em>, rather than just the relative ranking / relative position of countries. It can: forecasting errors appear to be minimal and don’t vary significantly over time.</p>



<p class="wp-block-paragraph"><em>This is second post in a series examining relationships between the rule of law and economic and social outcomes.</em></p>



<p class="wp-block-paragraph"><a href="https://www.gilesd-j.com/2026/07/07/close-enough-using-the-wgi-as-a-proxy-for-the-wjp-rule-of-law-index/https://www.gilesd-j.com/2026/07/07/close-enough-using-the-wgi-as-a-proxy-for-the-wjp-rule-of-law-index/" rel="nofollow" target="_blank">In the previous post in the series</a> I tested whether the World Governance Indicator’s (WGI) rule of law index (RoL) was a worthy substitute for the index produced by the World Justice Project when needing to take advantage of the WGI’s wider and longer coverage.</p>



<p class="wp-block-paragraph">When I asked Claude for feedback it rudely provided it, arguing that my analysis was fine for confirming <em>general agreement</em> as to how the two measures ranked countries, but additional analysis was needed to test whether the WGI could reliably be used to predict RoL levels.</p>



<p class="wp-block-paragraph">My first response was to tell Claude that <em>nobody </em>should be using composite indices in this way in the first place as it implied a level of precision they don’t have, but I decided it would be a useful addendum to the first post that I could post during my holiday in the Northern Territory.</p>



<h3 class="wp-block-heading">Project Setup and Data</h3>



<p class="wp-block-paragraph">Once again, data used in this post can be <a href="https://www.gilesd-j.com/2026/07/21/level-with-me-can-the-wgi-predict-the-wjps-rule-of-law-scores/gilesd-j.com/shared_resources/blogs/260310_RoL/wgidataset_with_sourcedata-2025.xlsx" rel="nofollow" target="_blank">downloaded here for the WGI</a> and <a href="https://www.gilesd-j.com/2026/07/21/level-with-me-can-the-wgi-predict-the-wjps-rule-of-law-scores/gilesd-j.com/shared_resources/blogs/260310_RoL/2025_wjp_rule_of_law_index_HISTORICAL_DATA_FILE.xlsx" rel="nofollow" target="_blank">here for the WJP’s RoL index</a>. These were current as of July 2025.</p>



<pre>#load the packages we'll probably need
library(tidyverse)
library(readxl)
library(janitor)
library(countrycode)

#import WGI data
dta_wgi_2025&lt;-read_excel(&quot;./Data/wgidataset_with_sourcedata-2025.xlsx&quot;,
                         sheet=&quot;rl&quot;) |&gt; 
  clean_names()

#import World Justice Project RoL data
dta_wjp_rol&lt;-read_excel('./Data/2025_wjp_rule_of_law_index_HISTORICAL_DATA_FILE.xlsx', sheet=&quot;Historical Data&quot;)|&gt; 
  clean_names()</pre>



<h3 class="wp-block-heading">Data Cleaning</h3>



<p class="wp-block-paragraph">Data cleaning is identical to the last post and revolves around making sure that countries names and regions are consistently applied across the two indices.</p>



<pre>#standardize column names
dta_wgi_2025&lt;-dta_wgi_2025 |&gt; 
  rename(country=economy_name,
         iso3c=economy_code,
         wgi_rol=governance_estimate_approx_2_5_to_2_5)

dta_wjp_rol&lt;-dta_wjp_rol |&gt; 
  rename(iso3c=country_code) |&gt; 
  rename_with(~ str_replace(., &quot;^x&quot;, &quot;factor_&quot;), starts_with(&quot;x&quot;))

#change wjp's year variable to YYYY format and convert to numeric 
#(adopts the first 4 digit year when in YYYY-YYYY format)
dta_wjp_rol &lt;- dta_wjp_rol |&gt; 
  mutate(year = as.numeric(str_sub(year, 1, 4)))

#cold-heartedly drop columns I'm not interested in 
dta_wgi_2025&lt;-dta_wgi_2025 |&gt; 
  select(iso3c, income_classification, year,wgi_rol)
#drop country and region name labels so these can be standardized 
dta_wjp_rol&lt;-dta_wjp_rol |&gt; 
  select(-country_year,-country,-region) |&gt; 
  rename(wjp_rol=wjp_rule_of_law_index_overall_score)


#merge dataframes
dta_rol_unified&lt;-left_join(dta_wgi_2025,
                           dta_wjp_rol,
                           by = join_by(year, iso3c), 
                           keep=FALSE) 

#add standardized and region names country names

#define country code assignments for legacy / ambigious codes
#(Note: matches devised by Claude) 
ref_iso3c_custom_names &lt;- c(ADO = &quot;Andorra&quot;,
                            ANT = &quot;Netherlands Antilles&quot;,
                            PRI = &quot;Puerto Rico&quot;,
                            REU = &quot;Réunion&quot;,
                            XKX = &quot;Kosovo&quot;)

ref_iso3c_custom_regions &lt;- c(ADO = &quot;Europe &#038; Central Asia&quot;,
                              ANT = &quot;Latin America &#038; Caribbean&quot;,
                              PRI = &quot;Latin America &#038; Caribbean&quot;,
                              REU = &quot;Sub-Saharan Africa&quot;,
                              XKX = &quot;Europe &#038; Central Asia&quot;)

#assign country names and regions:
dta_rol_unified&lt;-dta_rol_unified |&gt; 
  mutate(country_name=countrycode(iso3c, 
                                  origin='iso3c',
                                  destination = 'country.name.en',    
                                  custom_match = ref_iso3c_custom_names),
         region=countrycode(iso3c, 
                            origin='iso3c',
                            destination = 'region',    
                            custom_match =ref_iso3c_custom_regions))</pre>



<h3 class="wp-block-heading">Testing Cardinal Substitution</h3>



<p class="wp-block-paragraph">The code below basically asks whether it’s possible to estimate the <em>level </em>of WJP’s RoL index using the WGI’s RoL measure using a simple linear model. At the outset, the model’s fit is quite high at 97 percent, but we could have guessed this from the cross-country scatter we produced in our last post.</p>



<pre># Cardinal substitution: does a WGI-&gt;WJP mapping reproduce WJP levels? -----
sum_rol_country &lt;- dta_rol_unified |&gt;
  filter(!is.na(wgi_rol), !is.na(wjp_rol)) |&gt;
  summarise(wgi_rol_mean = mean(wgi_rol),
            wjp_rol_mean = mean(wjp_rol),
            .by = country_name)

mod_rol_calib &lt;- lm(wjp_rol_mean ~ wgi_rol_mean, data = sum_rol_country)

#output the R squared
summary(mod_rol_calib)$r.squared |&gt; round(2)</pre>



<p class="wp-block-paragraph">The second chunk calculates the Leave-One-Out Cross-Validation Root Mean Squared Error (LOO RMSE), which estimates prediction error for each country when it’s held out of the sample: a smaller LOO RMSE implies smaller forecast errors when predicting outside the sample. This is then scaled by the standard deviation of the country-level WJP means to make it easier to interpretat.</p>



<p class="wp-block-paragraph">The results are encouraging: the LOO RMSE indicates that using the WGI to estimate WJP levels carries a typical error of less than three percent, which is roughly 19% of the cross-country spread in WJP scores. Suggesting the WGI <em>can </em>provide a reasonable proxy when the levels are important too.</p>



<pre># Leave-One-Out Cross-Validation Root Mean Squared Error (LOO RMSE)
rlt_rol_loo_rmse   &lt;- sqrt(mean((residuals(mod_rol_calib) /
                                   (1 - hatvalues(mod_rol_calib)))^2))

#divide by standard deviation of WJP index means to put the figure in the context fo the data
rlt_rol_rmse_ratio &lt;- rlt_rol_loo_rmse / sd(sum_rol_country$wjp_rol_mean)</pre>



<h3 class="wp-block-heading">Systematic Bias</h3>



<p class="wp-block-paragraph">Of course, because the LOO RMSE measures is calculated across the entire dataset, it might hide systematic bias, such as if the forecast accuracy varies depending on the WGI score.</p>



<p class="wp-block-paragraph">This is tested in the plot below, by comparing the prediction error (residual) with the predicted value for the WJP’s index (using the WGI RoL measure). If there no systematic bias, the residuals should remain relatively stable across the predicted WJP values.</p>



<p class="wp-block-paragraph">Alas, this doesn’t appear to be the case, with the model under-predicting the WJP’s RoL index at both ends. Although this bias is relatively mild at 0.05 (in WJP index units), it does suggest the WGI is likely to be a poorer substitute for the WJP’s index for countries at either end of the RoL spectrum.</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" loading="lazy" src="https://i2.wp.com/www.gilesd-j.com/wp-content/uploads/2026/07/estimate_bias.png?w=450&#038;ssl=1" alt="" class="wp-image-4256" srcset_temp="https://i2.wp.com/www.gilesd-j.com/wp-content/uploads/2026/07/estimate_bias.png?w=450&#038;ssl=1 604w, https://www.gilesd-j.com/wp-content/uploads/2026/07/estimate_bias-300x227.png 300w" sizes="auto, (max-width: 604px) 100vw, 604px" data-recalc-dims="1" /></figure>



<pre>dta_plt_rol_calib &lt;- sum_rol_country |&gt;
  mutate(wjp_pred = fitted(mod_rol_calib),
         resid    = wjp_rol_mean - wjp_pred)

plt_rol_calib &lt;- ggplot(dta_plt_rol_calib, aes(wjp_pred, resid)) +
  geom_hline(yintercept = 0, linewidth = 0.3, col = &quot;grey70&quot;) +
  geom_point(alpha = 0.6) +
  geom_smooth(method = &quot;loess&quot;, se = FALSE, col = &quot;grey40&quot;, linewidth = 0.5) +
  labs(x = &quot;Predicted WJP (from WGI)&quot;, y = &quot;Residual (WJP units)&quot;) +
  theme_classic()

plt_rol_calib</pre>



<p class="wp-block-paragraph">However, being an applied economist means I know a simple trick: add non-linear terms to everything and see if the smile disappears.</p>



<p class="wp-block-paragraph">And it does, the smile is now a grimace: as is shown in the plot below adding a non-linear term seems to take care of the bias at either end. Notice the average errors no longer increase at either end, making the prediction relatively constant (and small) across the RoL spectrum. Suggesting the WGI <em>can </em>be trusted to predict the WJP index at either end of the spectrum provided we account for the non-linearity.</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" loading="lazy" src="https://i0.wp.com/www.gilesd-j.com/wp-content/uploads/2026/07/systematic_bias_nl.png?w=450&#038;ssl=1" alt="" class="wp-image-4259" srcset_temp="https://i0.wp.com/www.gilesd-j.com/wp-content/uploads/2026/07/systematic_bias_nl.png?w=450&#038;ssl=1 604w, https://www.gilesd-j.com/wp-content/uploads/2026/07/systematic_bias_nl-300x227.png 300w" sizes="auto, (max-width: 604px) 100vw, 604px" data-recalc-dims="1" /></figure>



<pre>#reestimate the model with a non-linear WGI term 
mod_rol_calib_non_linear &lt;- lm(wjp_rol_mean ~ wgi_rol_mean + I(wgi_rol_mean^2),
                               data = sum_rol_country)


dta_plt_rol_calib_nl &lt;- sum_rol_country |&gt;
  mutate(wjp_pred = fitted(mod_rol_calib_non_linear),
         resid    = wjp_rol_mean - wjp_pred)

plt_rol_calib_nl &lt;- ggplot(dta_plt_rol_calib_nl, aes(wjp_pred, resid)) +
  geom_hline(yintercept = 0, linewidth = 0.3, col = &quot;grey70&quot;) +
  geom_point(alpha = 0.6) +
  geom_smooth(method = &quot;loess&quot;, se = FALSE, col = &quot;grey40&quot;, linewidth = 0.5) +
  labs(x = &quot;Predicted WJP (from WGI, quadratic)&quot;, y = &quot;Residual (WJP units)&quot;) +
  theme_classic()

plt_rol_calib_nl</pre>



<h3 class="wp-block-heading">But does it drift?</h3>



<p class="wp-block-paragraph">The final question Claude suggested I ask was whether the WGI’s ability to predict the WJP’s index changes over time. The code below tests this by comparing a simple linear prediction model with one where the influence of the WGI changes over time.</p>



<p class="wp-block-paragraph">The anova() function then compares results of both models to test whether allowing the WGI’s influence to change over time improves the model’s forecasting accuracy. If it does (indicated by a significant p-value), the WGI’s ability to predict the WJP’s index might not be stable over time.</p>



<p class="wp-block-paragraph">The result: a p value of 9%, which points to the time invariant model being good enough for predicting the WJP’s index.</p>



<pre>#estimate a simple linear model with WGI's influence kept constant over time
mod_rol_calib_flat &lt;- lm(wjp_rol ~ wgi_rol, data = dta_rol_unified)

#estimate a model where WGI's influence varies over time
mod_rol_calib_yr   &lt;- lm(wjp_rol ~ wgi_rol * factor(year), data = dta_rol_unified)

#compare the prediction capacity of both models 
anova(mod_rol_calib_flat, mod_rol_calib_yr)</pre>



<h3 class="wp-block-heading">Look what Claude made me do…</h3>



<p class="wp-block-paragraph">So there you have it: the WGI can serve as a useful substitute for the WJP’s rule of law index whether you’re interested in RoL rankings <em>or </em>levels, provided you account for the non-linearity at either end of the RoL scale.</p>



<p class="wp-block-paragraph"><strong>How AI was used for this post:</strong> As this additional analysis was Claude’s suggestion <em>and </em>I was hours away from a holiday I leaned heavily on Claude for the first draft of the code. Much of the text is mine, but I did ask AI for suggestions to make sure I was explaining the analysis accurately.</p>



<p class="wp-block-paragraph"></p>
<p>The post <a href="https://www.gilesd-j.com/2026/07/21/level-with-me-can-the-wgi-predict-the-wjps-rule-of-law-scores/" rel="nofollow" target="_blank">Level With Me: Can the WGI Predict the WJP’s Rule of Law Scores?</a> appeared first on <a href="https://www.gilesd-j.com/" rel="nofollow" target="_blank">Giles</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.gilesd-j.com/2026/07/21/level-with-me-can-the-wgi-predict-the-wjps-rule-of-law-scores/"> Data Analytics and AI Archives - Giles</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/level-with-me-can-the-wgi-predict-the-wjps-rule-of-law-scores/">Level With Me: Can the WGI Predict the WJP’s Rule of Law Scores?</a>]]></content:encoded>
					
		
		<enclosure url="" length="0" type="" />

		<post-id xmlns="com-wordpress:feed-additions:1">402713</post-id>	</item>
		<item>
		<title>A collection of self-starters for nonlinear regression in R</title>
		<link>https://www.r-bloggers.com/2026/07/a-collection-of-self-starters-for-nonlinear-regression-in-r-3/</link>
		
		<dc:creator><![CDATA[Andrea Onofri]]></dc:creator>
		<pubDate>Mon, 20 Jul 2026 22:00:00 +0000</pubDate>
				<category><![CDATA[R bloggers]]></category>
		<guid isPermaLink="false">https://www.statforbiology.com/posts/nls_modelFitting.html</guid>

					<description><![CDATA[<div style = "width:60%; display: inline-block; float:left; ">
<p>Usually, the first step in every nonlinear regression analysis is to select the function  that best describes the phenomenon under study. The next step is to fit this function to the observed data, possibly by using some sort of nonlinear least ...</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/a-collection-of-self-starters-for-nonlinear-regression-in-r-3/">A collection of self-starters for nonlinear regression 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="https://www.statforbiology.com/posts/nls_modelFitting.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>Usually, the first step in every nonlinear regression analysis is to select the function <img src="https://latex.codecogs.com/png.latex?f"> that best describes the phenomenon under study. The next step is to fit this function to the observed data, possibly by using some sort of nonlinear least squares algorithm.</p>
<p>We have already devoted a post to the first task, which you can find <a href="https://www.statforbiology.com/posts/nls_usefulEquations.html" rel="nofollow" target="_blank">at this link</a>.</p>
<p>As for the second step, the main problem is that nonlinear least squares algorithms are iterative, in the sense that they start from some initial guesses for the model parameters, which are continuously improved until the least squares solution is approximately reached. Quite often, providing such initial guesses for all model parameters becomes a problem: if our guesses are not close enough to the least squares estimates, the algorithm may stall and fail to converge. Or, even worse, it may converge to the wrong solution. How do we obtain good initial guesses for the model parameters? This is not easily accomplished, especially for students and practitioners. This is where self-starters come in handy.</p>
<p>Self-starter functions can automatically calculate initial values for any given dataset and, therefore, they can make nonlinear regression almost as straightforward as linear regression. From a teaching perspective, this means that the transition from linear to nonlinear models is immediate and hassle-free.</p>
<p>In another post, <a href="https://www.statforbiology.com/posts/nls_selfStarting.html" rel="nofollow" target="_blank">at this link</a>, I explained how self-starters can be built for both the <code>nls()</code> function in the ‘stats’ package and the <code>drm()</code> function in the ‘drc’ package (Ritz et al., 2019). In this post, I would like to provide an overview of the self-starting functions that already exist in R, either in the ‘stats’, ‘drc’, or ‘statforbiology’ packages. I do not aim for completeness here, as other packages also contain self-starters, such as the ‘nlraa’ package (Miguez, 2025), with which I am not sufficiently familiar. The exemplary datasets are included in the ‘statforbiology’ package and they all come from real field or greenhouse experiments; further information and citations to the original works can be found in my book (Onofri, 2026), or in the additional meterial at <a href="https://www.statforbiology.com/_statbookeng/" rel="nofollow" target="_blank">this link</a>.</p>
<section id="functions-and-curve-shapes" class="level1">
<h1>Functions and curve shapes</h1>
<p>As in the other post, I have classified linear/nonlinear regression functions according to the shape they show when they are plotted in an <em>x-y</em> graph, following the approach taken in Ratkowsky (1990):</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>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>
<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://i2.wp.com/www.statforbiology.com/posts/nls_modelFitting_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>
<p>First of all, we need to install (if necessary) and load these packages, by using the code below.</p>
<div class="cell">
<pre># installing package, if not yet available
# install.packages(&quot;statforbiology&quot;)

# loading package
library(statforbiology)</pre>
</div>
</section>
<section id="polynomials" class="level1">
<h1>Polynomials</h1>
<section id="straight-line-function" class="level2">
<h2 class="anchored" data-anchor-id="straight-line-function">Straight line function</h2>
<p>The equation is:</p>
<p><img src="https://latex.codecogs.com/png.latex?Y%20=%20b_0%20+%20b_1%20,%20X%20%5Cquad%20%5Cquad%20%5Cquad%20(1)"></p>
<p>Please check the details of parameter interpretation in <a href="https://www.statforbiology.com/posts/nls_usefulEquations.html#straight-line-function" rel="nofollow" target="_blank">my previous post</a>. This is a linear model and, in R, linear regression is fitted by using the <code>lm()</code> function. However, in a few circumstances I have found it useful to fit a linear regression model by using nonlinear regression algorithms. I know that this is rather inefficient, but, as a partial excuse, I should say that some methods for ‘drc’ objects are also rather handy for linear regression, for example, to obtain parameter estimates and compare regression curves in ANCOVA models. For these unusual cases, we can use the <code>NLS.linear()</code> and <code>DRC.linear()</code> functions in the ‘statforbiology’ package.</p>
<section id="example-1" class="level3">
<h3 class="anchored" data-anchor-id="example-1">Example 1</h3>
<p>Let’s consider the ‘metamitron’ dataset, which is available in ‘statforbiology’. It describes the degradation of the sugarbeet herbicide metamitron (M) in soil, either alone or in the presence of two co-applied herbicides, namely phenmedipham (P) and chloridazon (C). Independent soil samples treated with the four herbicide combinations (i.e. M, MP, MC and MPC) were assayed at eight different times (0, 7, 14, 21, 32, 42, 55 and 67 days after treatment, with three replicates per sampling date) to determine the residual concentration of metamitron. In my book (Onofri, 2026, p. 212), I analysed this dataset by using linear regression. Here, instead, I would like to show how the same model can be fitted with the <code>drm()</code> function in the ‘drc’ package, obtaining the slopes and intercepts for all herbicide combinations directly from the output of the <code>summary()</code> method.</p>
<div class="cell">
<pre># Example of fitting four straight lines at once
library(statforbiology)
dataset &lt;- getAgroData(&quot;metamitron&quot;)
model &lt;- drm(log(Conc) ~ Time, fct = DRC.linear(),
             curveid = Herbicide, data = dataset)
summary(model)</pre>
<div class="cell-output cell-output-stdout">
<pre>
Model fitted: Straight line (2 parms)

Parameter estimates:

        Estimate Std. Error t-value   p-value    
a:M    4.5159111  0.0577603  78.184 &lt; 2.2e-16 ***
a:MP   4.6304853  0.0577603  80.167 &lt; 2.2e-16 ***
a:MC   4.5401707  0.0577603  78.604 &lt; 2.2e-16 ***
a:MPC  4.7546974  0.0577603  82.318 &lt; 2.2e-16 ***
b:M   -0.0386165  0.0015585 -24.777 &lt; 2.2e-16 ***
b:MP  -0.0318908  0.0015585 -20.462 &lt; 2.2e-16 ***
b:MC  -0.0231879  0.0015585 -14.878 &lt; 2.2e-16 ***
b:MPC -0.0234014  0.0015585 -15.015 &lt; 2.2e-16 ***
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error:

 0.1687429 (88 degrees of freedom)</pre>
</div>
</div>
</section>
</section>
<section id="quadratic-polynomial-function" class="level2">
<h2 class="anchored" data-anchor-id="quadratic-polynomial-function">Quadratic polynomial function</h2>
<p>The equation is:</p>
<p><img src="https://latex.codecogs.com/png.latex?Y%20=%20a%20+%20b%5C,%20X%20+%20c%20%5C,%20X%5E2%20%5Cquad%20%5Cquad%20%5Cquad%20(2)"></p>
<p>Check the post <a href="https://www.statforbiology.com/posts/nls_usefulEquations.html#quadratic-polynomial-function" rel="nofollow" target="_blank">at this link</a> for details about the biological interpretation of the model parameters. In the same vein as the straight line function, a second-order polynomial can be fitted with the <code>lm()</code> function, but, if necessary, it can also be fitted with <code>nls()</code> or <code>drm()</code>, by using the functions <code>NLS.poly2()</code> and <code>DRC.poly2()</code>.</p>
<section id="example-2" class="level3">
<h3 class="anchored" data-anchor-id="example-2">Example 2</h3>
<p>The dataset ‘waterProductivity’ in the ‘statforbiology’ package shows the relationship between water productivity in lettuce, as affected by the irrigation regime and as determined in a simulated experiment based on the data from Toscano et al. (2026). It is expected that the relationship under study may show a maximum at an intermediate irrigation regime, which is confirmed by fitting a second-order polynomial function. This same analysis could, of course, be performed more efficiently by using linear regression.</p>
<div class="cell">
<pre>library(statforbiology)
dataset &lt;- getAgroData(&quot;waterProductivity&quot;)

# nls fit
model &lt;- nls(WP ~ NLS.poly2(Regime, a, b, c),
             data = dataset)

#drc fit
model &lt;- drm(WP ~ Regime, fct = DRC.poly2(),
             data = dataset)</pre>
</div>
<div class="cell" data-layout-align="center">
<div class="cell-output cell-output-stdout">
<pre>
Model fitted: Second Order Polynomial (3 parms)

Parameter estimates:

                 Estimate  Std. Error  t-value   p-value    
a:(Intercept)  1.9187e+00  2.3171e-01   8.2806 1.679e-05 ***
b:(Intercept)  4.2977e-01  8.4554e-03  50.8287 2.217e-12 ***
c:(Intercept) -3.3618e-03  6.6586e-05 -50.4884 2.355e-12 ***
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error:

 0.1441625 (9 degrees of freedom)</pre>
</div>
<div class="cell-output-display">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://i2.wp.com/www.statforbiology.com/posts/nls_modelFitting_files/figure-html/unnamed-chunk-4-1.png?w=450&#038;ssl=1" class="img-fluid quarto-figure quarto-figure-center figure-img"  data-recalc-dims="1"></p>
</figure>
</div>
</div>
</div>
</section>
</section>
</section>
<section id="concaveconvex-curves" class="level1">
<h1>Concave/Convex curves</h1>
<section id="exponential-function" class="level2">
<h2 class="anchored" data-anchor-id="exponential-function">Exponential function</h2>
<p>The most common equations are:</p>
<p><img src="https://latex.codecogs.com/png.latex?Y%20=%20a%20%20e%5E%7Bk%20%5C,%20X%7D%20%5Cquad%20%5Cquad%20%5Cquad%20(3)"></p>
<p><img src="https://latex.codecogs.com/png.latex?Y%20=%20e%5E%7Bd%20+%20k%20%5C,%20X%7D%20%5Cquad%20%5Cquad%20%5Cquad%20(4)"></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><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>and, for the cases where a lower asymptote <img src="https://latex.codecogs.com/png.latex?c%20%5Cneq%200"> is needed:</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>Check the post <a href="https://www.statforbiology.com/posts/nls_usefulEquations.html#exponential-function" rel="nofollow" target="_blank">at this link</a> for details about the model parameters. In order to fit these models, several self-starting functions are available. In the <code>statforbiology</code> package, you can find <code>NLS.expoGrowth()</code>, <code>NLS.expoDecay()</code>, <code>DRC.expoGrowth()</code>, and <code>DRC.expoDecay()</code>, which can be used to fit the exponential growth and decay models represented by Equation 3 with <code>nls()</code> and <code>drm()</code>, respectively. The <code>drc</code> package also contains the functions <code>EXD.2()</code> and <code>EXD.3()</code>, which can be used to fit Equations 6 and 7, respectively.</p>
<section id="example-3" class="level3">
<h3 class="anchored" data-anchor-id="example-3">Example 3</h3>
<p>The ‘degradation’ dataset, which is available in the ‘statforbiology’ package, refers to an herbicide degradation experiment, where the decrease in concentration over time is assumed to follow first-order kinetics, according to an exponential decay function.</p>
<div class="cell">
<pre>library(statforbiology)
data(degradation)

# nls fit
model &lt;- nls(Conc ~ NLS.expoDecay(Time, a, k),
             data = degradation)

# drm fit
model &lt;- drm(Conc ~ Time, fct = DRC.expoDecay(),
             data = degradation)
summary(model)</pre>
<div class="cell-output cell-output-stdout">
<pre>
Model fitted: Exponential Decay Model (2 parms)

Parameter estimates:

                 Estimate Std. Error t-value   p-value    
C0:(Intercept) 99.6349312  1.4646680  68.026 &lt; 2.2e-16 ***
k:(Intercept)   0.0670391  0.0019089  35.120 &lt; 2.2e-16 ***
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error:

 2.621386 (22 degrees of freedom)</pre>
</div>
</div>
<div class="cell" data-layout-align="center">
<div class="cell-output-display">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://i2.wp.com/www.statforbiology.com/posts/nls_modelFitting_files/figure-html/unnamed-chunk-6-1.png?w=450&#038;ssl=1" class="img-fluid quarto-figure quarto-figure-center figure-img"  data-recalc-dims="1"></p>
</figure>
</div>
</div>
</div>
</section>
</section>
<section id="asymptotic-function" class="level2">
<h2 class="anchored" data-anchor-id="asymptotic-function">Asymptotic function</h2>
<p>The following parameterisations are available:</p>
<p><img src="https://latex.codecogs.com/png.latex?Y%20=%20a%20-%20(a%20-%20b)%20%5C,%20%5Cexp%20(-%20m%20%5C,%20X)%20%5Cquad%20%5Cquad%20%5Cquad%20(8)"></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><img src="https://latex.codecogs.com/png.latex?Y%20=%20a%20-%20(a%20-%20b)%20%5C,%20%5Cexp%20(-%20log(f)%5C,%20X)%20%5Cquad%20%5Cquad%20%5Cquad%20(10)"></p>
<p>If we set <img src="https://latex.codecogs.com/png.latex?b%20=%200"> (or, equivalently, <img src="https://latex.codecogs.com/png.latex?c%20=%200">) in the equations above, we obtain a curve passing through the origin, which is usually referred to as the <em>negative exponential function</em> and is most commonly parameterised as:</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>Check the post <a href="https://www.statforbiology.com/posts/nls_usefulEquations.html#asymptotic-function" rel="nofollow" target="_blank">at this link</a> for details about the model parameters. To fit the asymptotic function, the ‘statforbiology’ package contains the self-starting routines <code>NLS.asymReg()</code> and <code>DRC.asymReg()</code>, which can be used to fit Eq. 8 with <code>nls()</code> and <code>drm()</code>, respectively. The ‘drc’ package contains the function <code>AR.3()</code> to fit Eq. 9 with <code>drm()</code>, while the ‘stats’ package contains <code>SSasymp()</code>, which can be used to fit Eq. 10 with <code>nls()</code>. The negative exponential function can be fitted with <code>NLS.negExp()</code>, <code>DRC.negExp()</code> (in ‘statforbiology’), <code>AR.2()</code> (in ‘drc’), and <code>SSasympOrig()</code> (in ‘stats’).</p>
<section id="example-4" class="level3">
<h3 class="anchored" data-anchor-id="example-4">Example 4</h3>
<p>In this example, we consider a growth curve where the weight of a crop is measured at different times. As the data do not show any visible inflection point, we fit an asymptotic regression model.</p>
<div class="cell">
<pre>Time &lt;- c(1, 3, 5, 7, 9, 11, 13, 20)
Weight &lt;- c(8.22, 14.0, 17.2, 16.9, 19.2, 19.6, 19.4, 19.6)

# nls fit
model &lt;- nls(Weight ~ NLS.asymReg(Time, b, m, a) )

# drm fit
model &lt;- drm(Weight ~ Time, fct = DRC.asymReg(names = c(&quot;b&quot;, &quot;m&quot;, &quot;a&quot;)))
summary(model)</pre>
<div class="cell-output cell-output-stdout">
<pre>
Model fitted: Asymptotic Regression Model (3 parms)

Parameter estimates:

               Estimate Std. Error t-value   p-value    
b:(Intercept)  3.756123   1.367835  2.7460  0.040500 *  
m:(Intercept)  0.337078   0.052704  6.3957  0.001385 ** 
a:(Intercept) 19.629817   0.420557 46.6758 8.525e-08 ***
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error:

 0.639656 (5 degrees of freedom)</pre>
</div>
</div>
<div class="cell" data-layout-align="center">
<div class="cell-output-display">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://i1.wp.com/www.statforbiology.com/posts/nls_modelFitting_files/figure-html/unnamed-chunk-8-1.png?w=450&#038;ssl=1" class="img-fluid quarto-figure quarto-figure-center figure-img"  data-recalc-dims="1"></p>
</figure>
</div>
</div>
</div>
</section>
</section>
<section id="power-function" class="level2">
<h2 class="anchored" data-anchor-id="power-function">Power function</h2>
<p>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>Check the post <a href="https://www.statforbiology.com/posts/nls_usefulEquations.html#power-function" rel="nofollow" target="_blank">at this link</a> for details about the model parameters. This function can be fitted by using the self-starting functions <code>DRC.powerCurve()</code> and <code>NLS.powerCurve()</code> in the ‘statforbiology’ package.</p>
<section id="example-5" class="level3">
<h3 class="anchored" data-anchor-id="example-5">Example 5</h3>
<p>The ‘speciesArea’ dataset in the ‘statforbiology’ package was obtained from an experiment aimed at determining the species–area relationship for the weed community in an orange grove. The response variable is the number of species, while the predictor is the sampled area.</p>
<div class="cell">
<pre>library(statforbiology)
speciesArea &lt;- getAgroData(&quot;speciesArea&quot;)

#nls fit
model &lt;- nls(numSpecies ~ NLS.powerCurve(Area, a, b),
             data = speciesArea)

# drm fit
model &lt;- drm(numSpecies ~ Area, fct = DRC.powerCurve(),
             data = speciesArea)
summary(model)</pre>
<div class="cell-output cell-output-stdout">
<pre>
Model fitted: Power curve (Freundlich equation) (2 parms)

Parameter estimates:

              Estimate Std. Error t-value   p-value    
a:(Intercept) 4.348404   0.337197  12.896 3.917e-06 ***
b:(Intercept) 0.329770   0.016723  19.719 2.155e-07 ***
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error:

 0.9588598 (7 degrees of freedom)</pre>
</div>
</div>
<div class="cell" data-layout-align="center">
<div class="cell-output-display">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://i2.wp.com/www.statforbiology.com/posts/nls_modelFitting_files/figure-html/unnamed-chunk-10-1.png?w=450&#038;ssl=1" class="img-fluid quarto-figure quarto-figure-center figure-img"  data-recalc-dims="1"></p>
</figure>
</div>
</div>
</div>
</section>
</section>
<section id="logarithmic-function" class="level2">
<h2 class="anchored" data-anchor-id="logarithmic-function">Logarithmic function</h2>
<p>It has the following main parameterisation:</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>Check the post <a href="https://www.statforbiology.com/posts/nls_usefulEquations.html#logarithmic-function" rel="nofollow" target="_blank">at this link</a> for details about the parameters. The logarithmic function can be fitted by using <code>lm()</code>, with a log-transformed predictor. If necessary, it can also be fitted by using <code>nls()</code> and <code>drm()</code>, with the self-starting functions <code>NLS.logCurve()</code> and <code>DRC.logCurve()</code>, which are available in the ‘statforbiology’ package.</p>
<section id="example-6" class="level3">
<h3 class="anchored" data-anchor-id="example-6">Example 6</h3>
<p>In this example, we use the ‘speciesArea’ dataset to fit a logarithmic curve, which is another candidate model for describing species–area curves. In this case, based on the AIC value, we can conclude that the power function provides a better fit to the observed data.</p>
<div class="cell">
<pre>library(statforbiology)
speciesArea &lt;- getAgroData(&quot;speciesArea&quot;)

#nls fit
model2 &lt;- nls(numSpecies ~ NLS.logCurve(Area, a, b),
             data = speciesArea)

# drm fit
model2 &lt;- drm(numSpecies ~ Area, fct = DRC.logCurve(),
             data = speciesArea)
summary(model2)</pre>
<div class="cell-output cell-output-stdout">
<pre>
Model fitted: Linear regression on log-transformed x (2 parms)

Parameter estimates:

              Estimate Std. Error t-value   p-value    
a:(Intercept)  1.51111    1.17401  1.2871     0.239    
b:(Intercept)  4.06359    0.35575 11.4224 8.847e-06 ***
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error:

 1.910082 (7 degrees of freedom)</pre>
</div>
</div>
<div class="cell" data-layout-align="center">
<div class="cell-output-display">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://i0.wp.com/www.statforbiology.com/posts/nls_modelFitting_files/figure-html/unnamed-chunk-12-1.png?w=450&#038;ssl=1" class="img-fluid quarto-figure quarto-figure-center figure-img"  data-recalc-dims="1"></p>
</figure>
</div>
</div>
<div class="cell-output cell-output-stdout">
<pre>       df      AIC
model   3 28.52288
model2  3 40.92769</pre>
</div>
</div>
</section>
</section>
<section id="rectangular-hyperbola" class="level2">
<h2 class="anchored" data-anchor-id="rectangular-hyperbola">Rectangular hyperbola</h2>
<p>Common parameterisations are:</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><img src="https://latex.codecogs.com/png.latex?Y%20=%20%5Cfrac%7Bd%7D%7B1%20+%20%5Cfrac%7Be%7D%7BX%7D%7D%20%5Cquad%20%5Cquad%20%5Cquad%20(15)"></p>
<p><img src="https://latex.codecogs.com/png.latex?Y%20=%20c%20+%20%5Cfrac%7Bd%20-%20c%7D%7B1%20+%20%5Cfrac%7Be%7D%7BX%7D%7D%20%5Cquad%20%5Cquad%20%5Cquad%20(15a)"></p>
<p><img src="https://latex.codecogs.com/png.latex?Y%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 derivation of the alternative parameterisations and the interpretation of the parameters are described in another post <a href="https://www.statforbiology.com/posts/nls_usefulEquations.html#rectangular-hyperbola" rel="nofollow" target="_blank">at this link</a>. In R, the rectangular hyperbola can be fitted by using ‘nls()’ and the self-starting function <code>SSmicmen()</code>, available in the ‘nlme’ package. If you prefer a ‘drm()’ fit, you can use the <code>MM.2()</code> and <code>MM.3()</code> functions in the ‘drc’ package, which use the parameterisations in Eq. 15 and 15a, respectively. For competition studies, Eq. 16 is available through the self-starting functions <code>NLS.YL()</code> and <code>DRC.YL()</code>.</p>
<section id="example-7" class="level3">
<h3 class="anchored" data-anchor-id="example-7">Example 7</h3>
<p>The dataset ‘Ammi94_YL’ contains the results of a competition experiment on the effect of increasing densities of the weed species <em>Ammi majus</em> on sunflower achene yield. Yield data were expressed as yield losses relative to the yield in weed-free plots and were used as the response variable to fit Eq. 16 and derive the competition index <img src="https://latex.codecogs.com/png.latex?i">.</p>
<div class="cell">
<pre>library(statforbiology)
dataset &lt;- getAgroData(&quot;Ammi94_YL&quot;)

#drm fit
model &lt;- drm(YL ~ Density, fct = DRC.YL(), data = dataset)
summary(model)</pre>
<div class="cell-output cell-output-stdout">
<pre>
Model fitted: Yield-Loss function (Cousens, 1985) (2 parms)

Parameter estimates:

               Estimate Std. Error t-value p-value  
i:(Intercept) 0.0118359  0.0045637  2.5935 0.02228 *
A:(Intercept) 0.4841796  0.1863969  2.5976 0.02211 *
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error:

 0.05453432 (13 degrees of freedom)</pre>
</div>
</div>
<div class="cell" data-layout-align="center">
<div class="cell-output-display">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://i0.wp.com/www.statforbiology.com/posts/nls_modelFitting_files/figure-html/unnamed-chunk-14-1.png?w=450&#038;ssl=1" class="img-fluid quarto-figure quarto-figure-center figure-img"  data-recalc-dims="1"></p>
</figure>
</div>
</div>
</div>
</section>
</section>
</section>
<section id="sigmoidal-function" class="level1">
<h1>Sigmoidal curves</h1>
<p>In the previous post (<a href="https://www.statforbiology.com/posts/nls_usefulEquations.qmd" rel="nofollow" target="_blank">at this link</a>) we examined six different sigmoidal shapes based on <img src="https://latex.codecogs.com/png.latex?X">, to be selected according to the expected symmetry of the response. The equations are the logistic, Gompertz, and modified Gompertz functions, with the following three equations, respectively:</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><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(X%20-%20e)%20%5Cright%5D%20%5Cright%5C%7D%20%5Cquad%20%5Cquad%20%5Cquad%20(18)"></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 same curves can be based on the logarithm of <img src="https://latex.codecogs.com/png.latex?X">, to obtain the corresponding log-logistic, Type-1 Weibull, and Type-2 Weibull equations, which are, respectively:</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><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><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 meaning of the model parameters and details about the shapes can be found in another post <a href="https://www.statforbiology.com/posts/nls_UsefulEquations.qmd#sigmoidal" rel="nofollow" target="_blank">at this link</a>.</p>
<p>For all these four-parameter curves, it is possible to set <img src="https://latex.codecogs.com/png.latex?c%20=%200"> to obtain the three-parameter curves (17a), (18a), (19a), (20a), (21a), and (22a). Likewise, we can constrain both <img src="https://latex.codecogs.com/png.latex?c%20=%200"> and <img src="https://latex.codecogs.com/png.latex?d%20=%201"> to obtain the two-parameter curves (17b), (18b), (19b), (20b), (21b), and (22b). The collection of self-starters is huge; therefore, I will provide a summary table.</p>
<table class="caption-top table">
<caption>List of sigmoidal functions, together with self-starters for fitting with <code>drm()</code> and <code>nls()</code>. (1) These self-starters are included in the ‘drc’ package and the corresponding curves have an increasing shape when <img src="https://latex.codecogs.com/png.latex?b%20%3C%200"> and a decreasing shape when <img src="https://latex.codecogs.com/png.latex?b%20%3E%200">. For all other self-starters, which are available in the ‘statforbiology’ package, the reverse is true (which is the most common definition, apart from the case of herbicide bioassays){#tbl-models}</caption>
<colgroup>
<col style="width: 45%">
<col style="width: 13%">
<col style="width: 20%">
<col style="width: 20%">
</colgroup>
<thead>
<tr class="header">
<th style="text-align: left;">Name</th>
<th style="text-align: left;">Eq. No.</th>
<th style="text-align: left;">for <code>drm()</code></th>
<th style="text-align: left;">for <code>nls()</code></th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;">Logistic (4-parameters)</td>
<td style="text-align: left;">(17)</td>
<td style="text-align: left;"><code>L.4()</code> (1)</td>
<td style="text-align: left;"><code>NLS.L4()</code></td>
</tr>
<tr class="even">
<td style="text-align: left;">Logistic (3-parameters)</td>
<td style="text-align: left;">(17a)</td>
<td style="text-align: left;"><code>L.3()</code> (1)</td>
<td style="text-align: left;"><code>NLS.L3()</code></td>
</tr>
<tr class="odd">
<td style="text-align: left;">Logistic (2-parameters)</td>
<td style="text-align: left;">(17b)</td>
<td style="text-align: left;"><code>L.2()</code> (1)</td>
<td style="text-align: left;"><code>NLS.L2()</code></td>
</tr>
<tr class="even">
<td style="text-align: left;">Gompertz (4-parameters)</td>
<td style="text-align: left;">(18)</td>
<td style="text-align: left;"><code>G.4()</code> (1)</td>
<td style="text-align: left;"><code>NLS.G4()</code></td>
</tr>
<tr class="odd">
<td style="text-align: left;">Gompertz (3-parameters)</td>
<td style="text-align: left;">(18a)</td>
<td style="text-align: left;"><code>G.3()</code> (1)</td>
<td style="text-align: left;"><code>NLS.G3()</code></td>
</tr>
<tr class="even">
<td style="text-align: left;">Gompertz (2-parameters)</td>
<td style="text-align: left;">(18b)</td>
<td style="text-align: left;"><code>G.2()</code> (1)</td>
<td style="text-align: left;"><code>NLS.G2()</code></td>
</tr>
<tr class="odd">
<td style="text-align: left;">mod-Gompertz (4-parameters)</td>
<td style="text-align: left;">(19)</td>
<td style="text-align: left;"><code>DRC.E4()</code></td>
<td style="text-align: left;"><code>NLS.E4()</code></td>
</tr>
<tr class="even">
<td style="text-align: left;">mod-Gompertz (3-parameters)</td>
<td style="text-align: left;">(19a)</td>
<td style="text-align: left;"><code>DRC.E3()</code></td>
<td style="text-align: left;"><code>NLS.E3()</code></td>
</tr>
<tr class="odd">
<td style="text-align: left;">mod-Gompertz (2-parameters)</td>
<td style="text-align: left;">(19b)</td>
<td style="text-align: left;"><code>DRC.E2()</code></td>
<td style="text-align: left;"><code>NLS.E2()</code></td>
</tr>
<tr class="even">
<td style="text-align: left;">Log-logistic (4-parameters)</td>
<td style="text-align: left;">(20)</td>
<td style="text-align: left;"><code>LL.4()</code> (1)</td>
<td style="text-align: left;"><code>NLS.LL4()</code></td>
</tr>
<tr class="odd">
<td style="text-align: left;">Log-logistic (3-parameters)</td>
<td style="text-align: left;">(20a)</td>
<td style="text-align: left;"><code>LL.3()</code> (1)</td>
<td style="text-align: left;"><code>NLS.LL3()</code></td>
</tr>
<tr class="even">
<td style="text-align: left;">Log-logistic (2-parameters)</td>
<td style="text-align: left;">(20b)</td>
<td style="text-align: left;"><code>LL.2()</code> (1)</td>
<td style="text-align: left;"><code>NLS.LL2()</code></td>
</tr>
<tr class="odd">
<td style="text-align: left;">Type-1 Weibull (4-parameters)</td>
<td style="text-align: left;">(21)</td>
<td style="text-align: left;"><code>W1.4()</code> (1)</td>
<td style="text-align: left;"><code>NLS.W1.4()</code></td>
</tr>
<tr class="even">
<td style="text-align: left;">Type-1 Weibull (3-parameters)</td>
<td style="text-align: left;">(21a)</td>
<td style="text-align: left;"><code>W1.3()</code> (1)</td>
<td style="text-align: left;"><code>NLS.W1.3()</code></td>
</tr>
<tr class="odd">
<td style="text-align: left;">Type-1 Weibull (2-parameters)</td>
<td style="text-align: left;">(21b)</td>
<td style="text-align: left;"><code>W1.2()</code> (1)</td>
<td style="text-align: left;"><code>NLS.W1.2()</code></td>
</tr>
<tr class="even">
<td style="text-align: left;">Type-2 Weibull (4-parameters)</td>
<td style="text-align: left;">(22)</td>
<td style="text-align: left;"><code>W2.4()</code> (1)</td>
<td style="text-align: left;"><code>NLS.W2.4()</code></td>
</tr>
<tr class="odd">
<td style="text-align: left;">Type-2 Weibull (3-parameters)</td>
<td style="text-align: left;">(22a)</td>
<td style="text-align: left;"><code>W2.3()</code> (1)</td>
<td style="text-align: left;"><code>NLS.W2.3()</code></td>
</tr>
<tr class="even">
<td style="text-align: left;">Type-2 Weibull (2-parameters)</td>
<td style="text-align: left;">(22b)</td>
<td style="text-align: left;"><code>W2.2()</code> (1)</td>
<td style="text-align: left;"><code>NLS.W2.2()</code></td>
</tr>
</tbody>
</table>
<section id="example-8" class="level2">
<h2 class="anchored" data-anchor-id="example-8">Example 8</h2>
<p>The dataset ‘beetGrowth’ in the ‘statforbiology’ package reports the results of an experiment in which the growth of sugar beet was evaluated under either weed-free or weed-infested conditions. In the following example, we consider the time course of crop weight under infested conditions and fit the logistic, Gompertz, and modified Gompertz functions to the observed data. We see that, based on the AIC, the three fits are equivalent in practice. We fit the same models with ‘drm()’ to show that the two fitting functions give the same results, apart from the sign of the <img src="https://latex.codecogs.com/png.latex?b"> parameter, which is reversed in the <code>L.3()</code> function.</p>
<div class="cell">
<pre>library(statforbiology)
beetGrowth &lt;- getAgroData(&quot;beetGrowth&quot;)

# nls fit
model.1 &lt;- nls(Infested ~ NLS.L3(DAE, b, d, e), data = beetGrowth)
model.2 &lt;- nls(Infested ~ NLS.G3(DAE, b, d, e), data = beetGrowth)
model.3 &lt;- nls(Infested ~ NLS.E3(DAE, b, d, e), data = beetGrowth)
AIC(model.1, model.2, model.3)</pre>
<div class="cell-output cell-output-stdout">
<pre>        df      AIC
model.1  4 250.2906
model.2  4 250.7596
model.3  4 250.8456</pre>
</div>
<pre>summary(model.1)</pre>
<div class="cell-output cell-output-stdout">
<pre>
Formula: Infested ~ NLS.L3(DAE, b, d, e)

Parameters:
   Estimate Std. Error t value Pr(&gt;|t|)    
b 1.188e-01  1.874e-02   6.338 1.33e-05 ***
d 2.512e+03  1.277e+02  19.671 4.01e-12 ***
e 5.803e+01  1.823e+00  31.836 3.46e-15 ***
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error: 222 on 15 degrees of freedom

Number of iterations to convergence: 6 
Achieved convergence tolerance: 4.299e-06</pre>
</div>
<pre># drm fit
model &lt;- drm(Infested ~ DAE, fct = L.3(), data = beetGrowth)
summary(model)</pre>
<div class="cell-output cell-output-stdout">
<pre>
Model fitted: Logistic (ED50 as parameter) with lower limit fixed at 0 (3 parms)

Parameter estimates:

                Estimate Std. Error t-value   p-value    
b:(Intercept)   -0.11876    0.01832  -6.483 1.033e-05 ***
d:(Intercept) 2511.95664  127.95600  19.631 4.131e-12 ***
e:(Intercept)   58.03099    1.83458  31.632 3.788e-15 ***
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error:

 221.9644 (15 degrees of freedom)</pre>
</div>
</div>
<div class="cell" data-layout-align="center">
<div class="cell-output-display">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://i0.wp.com/www.statforbiology.com/posts/nls_modelFitting_files/figure-html/unnamed-chunk-16-1.png?w=450&#038;ssl=1" class="img-fluid quarto-figure quarto-figure-center figure-img"  data-recalc-dims="1"></p>
</figure>
</div>
</div>
</div>
</section>
<section id="example-9" class="level2">
<h2 class="anchored" data-anchor-id="example-9">Example 9</h2>
<p>The dataset ‘brassica’ in the ‘statforbiology’ package reports the results of a short-term pot bioassay to determine the phytotoxicity of imazethapyr in hydroponic solution (Onofri, 1994). The response variable is the weight of the test plant (<em>Brassica rapa</em>), as affected by the herbicide concentration in the nutrient solution, which requires a decreasing sigmoidal curve. In the code below, we fit both a 4-parameter log-logistic and a 3-parameter log-logistic (with <img src="https://latex.codecogs.com/png.latex?c%20=%200">) function and graphically compare the two fits.</p>
<div class="cell">
<pre>library(statforbiology)
brassica &lt;- getAgroData(&quot;brassica&quot;)
model.1 &lt;- drm(FW ~ Dose, fct = LL.4(), data = brassica)
model.2 &lt;- drm(FW ~ Dose, fct = LL.3(), data = brassica)</pre>
</div>
<div class="cell" data-layout-align="center">
<div class="cell-output-display">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://i2.wp.com/www.statforbiology.com/posts/nls_modelFitting_files/figure-html/unnamed-chunk-18-1.png?w=450&#038;ssl=1" class="img-fluid quarto-figure quarto-figure-center figure-img"  data-recalc-dims="1"></p>
</figure>
</div>
</div>
</div>
</section>
</section>
<section id="curve-maxima" class="level1">
<h1>Curves with maxima/minima</h1>
<p>Curves with maxima are most often used to model phenomena where the response variable reaches a maximum value at a certain level of the <img src="https://latex.codecogs.com/png.latex?X"> variable and decreases afterwards. In a previous post, we showed four possible functions, namely the sigmoidal peaked function, the Bragg function, the Lorentz function, and the beta function, with the following equations, respectively. The numbering refers to the post <a href="https://www.statforbiology.com/posts/nls_usefulEquations.html#maxima-fun" rel="nofollow" target="_blank">at this link</a>, where you can find further information on model parameters and their biological meaning.</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><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><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>
<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>The sigmoidal peaked function (Eq. 23) can be fitted with <code>drm()</code>, by using the self-starter ‘BC.5()’. Another self-starter is available to impose the constraint <img src="https://latex.codecogs.com/png.latex?c%20=%200"> in Eq. 23, namely <code>BC.4()</code>. For the Bragg function, self-starters are available in ‘statforbiology’, which can be used to fit Eq. 24a with both <code>nls()</code> and <code>drm()</code>, namely <code>NLS.Bragg.4()</code> and <code>DRC.Bragg.4()</code>. <code>NLS.Bragg.3()</code> and <code>DRC.Bragg.3()</code> allow us to constrain <img src="https://latex.codecogs.com/png.latex?c%20=%200">. Finally, for the Lorentz equation, the self-starters are <code>NLS.Lorentz.4()</code> and <code>DRC.Lorentz.4()</code>, as well as, for the constrained version, <code>NLS.Lorentz.3()</code> and <code>DRC.Lorentz.3()</code>.</p>
<p>Curves with maxima have been used in bioassay studies to describe the stimulation of growth at low doses and in seed germination studies to describe the effect of temperature on the germination rates of seed lots.</p>
<section id="example-10" class="level2">
<h2 class="anchored" data-anchor-id="example-10">Example 10</h2>
<p>The dataset ‘SOLNI-hormesis’ in the ‘statforbiology’ package reports the results of a pot bioassay study evaluating the efficacy of rimsulfuron against <em>Solanum nigrum</em> at the 4-leaf stage. The response curve shows clear signs of stimulation at low herbicide doses (hormesis), which needs to be described by using a peaked sigmoidal function.</p>
<div class="cell">
<pre>library(statforbiology)
dataset &lt;- getAgroData(&quot;SOLNI_hormesis&quot;)
model &lt;- drm(FW ~ Dose, fct = BC.5(),
            data = dataset)
summary(model)</pre>
<div class="cell-output cell-output-stdout">
<pre>
Model fitted: Brain-Cousens (hormesis) (5 parms)

Parameter estimates:

              Estimate Std. Error t-value   p-value    
b:(Intercept)  3.57034    1.25309  2.8492 0.0082868 ** 
c:(Intercept)  3.76335    0.85964  4.3778 0.0001619 ***
d:(Intercept) 14.14991    1.36933 10.3334 6.992e-11 ***
e:(Intercept)  2.85405    0.76931  3.7099 0.0009485 ***
f:(Intercept)  5.26894    3.38238  1.5578 0.1309350    
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error:

 2.97547 (27 degrees of freedom)</pre>
</div>
</div>
<div class="cell" data-layout-align="center">
<div class="cell-output-display">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://i2.wp.com/www.statforbiology.com/posts/nls_modelFitting_files/figure-html/unnamed-chunk-20-1.png?w=450&#038;ssl=1" class="img-fluid quarto-figure quarto-figure-center figure-img"  data-recalc-dims="1"></p>
</figure>
</div>
</div>
</div>
</section>
<section id="example-11" class="level2">
<h2 class="anchored" data-anchor-id="example-11">Example 11</h2>
<p>The dataset ‘Hordeum_GR’ reports the germination rates of <em>Hordeum spontaneum</em> as affected by environmental temperatures. We clearly see that the response reaches a maximum value at intermediate temperature levels.</p>
<div class="cell">
<pre>library(statforbiology)
dataset &lt;- getAgroData(&quot;Hordeum_GR&quot;)
model &lt;- drm(GR50 ~ Temp, fct = DRC.bragg.4(),
            data = dataset)
summary(model)</pre>
<div class="cell-output cell-output-stdout">
<pre>
Model fitted: Bragg equation with four parameters

Parameter estimates:

                Estimate Std. Error t-value   p-value    
b:(Intercept)  0.0052849  0.0036063  1.4654 0.2804269    
c:(Intercept)  0.0039006  0.0131491  0.2966 0.7947090    
d:(Intercept)  0.0290870  0.0010552 27.5646 0.0013135 ** 
e:(Intercept) 18.0013282  0.5220972 34.4789 0.0008401 ***
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error:

 0.001544712 (2 degrees of freedom)</pre>
</div>
</div>
<div class="cell" data-layout-align="center">
<div class="cell-output-display">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://i1.wp.com/www.statforbiology.com/posts/nls_modelFitting_files/figure-html/unnamed-chunk-22-1.png?w=450&#038;ssl=1" class="img-fluid quarto-figure quarto-figure-center figure-img"  data-recalc-dims="1"></p>
</figure>
</div>
</div>
</div>
</section>
</section>
<section id="conclusions" class="level1">
<h1>Conclusions</h1>
<p>Here we are; I hope that this deep dive into nonlinear regression was useful. 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>Onofri, A., 2026. Field Research Methods in Agriculture: An Introduction with R. Springer Nature Switzerland, Cham. https://doi.org/10.1007/978-3-032-08199-5</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 Miguez F (2025). <em>nlraa: Nonlinear Regression for Agricultural Applications</em>. doi:10.32614/CRAN.package.nlraa <a href="https://doi.org/10.32614/CRAN.package.nlraa" class="uri" rel="nofollow" target="_blank">https://doi.org/10.32614/CRAN.package.nlraa</a>, R package version 1.9.10, <a href="https://cran.r-project.org/package=nlraa" class="uri" rel="nofollow" target="_blank">https://CRAN.R-project.org/package=nlraa</a>.</li>
</ol>
<p>This post was originally published in this blog on 2020-02-26.</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_modelFitting.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/a-collection-of-self-starters-for-nonlinear-regression-in-r-3/">A collection of self-starters for nonlinear regression in R</a>]]></content:encoded>
					
		
		<enclosure url="" length="0" type="" />

		<post-id xmlns="com-wordpress:feed-additions:1">402845</post-id>	</item>
		<item>
		<title>Outcomes from EuroBioC2026 Tidyomics Hackathon</title>
		<link>https://www.r-bloggers.com/2026/07/outcomes-from-eurobioc2026-tidyomics-hackathon/</link>
		
		<dc:creator><![CDATA[Juan Henao]]></dc:creator>
		<pubDate>Mon, 20 Jul 2026 00:00:00 +0000</pubDate>
				<category><![CDATA[R bloggers]]></category>
		<guid isPermaLink="false">https://tidyomics.github.io/tidyomicsBlog/posts/2026-07-20-eurobioc2026-tidyomics-hackathon-results/</guid>

					<description><![CDATA[<div style = "width:60%; display: inline-block; float:left; ">
<p>Two days, four participants, four aims<br />
The first Tidyomics community hackathon took place on 1st and 2nd June in Turku, Finland, as part of the EuroBioC2026 conference pre-events. Here, four researchers from around the globe joined efforts to e...</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/outcomes-from-eurobioc2026-tidyomics-hackathon/">Outcomes from EuroBioC2026 Tidyomics Hackathon</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://tidyomics.github.io/tidyomicsBlog/posts/2026-07-20-eurobioc2026-tidyomics-hackathon-results/"> tidyomicsBlog</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="two-days-four-participants-four-aims" class="level1">
<h1>Two days, four participants, four aims</h1>
<p>The first <code>Tidyomics</code> community hackathon took place on 1st and 2nd June in Turku, Finland, as part of the <strong>EuroBioC2026</strong> conference pre-events. Here, four researchers from around the globe joined efforts to extend the capabilities of tidy operations for omics data, focusing on solving current bugs.</p>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://i2.wp.com/tidyomics.github.io/tidyomicsBlog/posts/2026-07-20-eurobioc2026-tidyomics-hackathon-results/participants.jpg?w=578&#038;ssl=1" class="img-fluid figure-img" data-recalc-dims="1"></p>
<figcaption>Participants of the first Tidyomics community hackathon (from left to right): Jasper Spitzer, Carissa Chen, Marco Geigges, Stevie Pederson</figcaption>
</figure>
</div>
<p>Concretely, the hackathon focused on four key aspects:</p>
<ol type="1">
<li>Development</li>
<li>Bugs</li>
<li>Enhancements</li>
<li>Learning</li>
</ol>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://i1.wp.com/tidyomics.github.io/tidyomicsBlog/posts/2026-07-20-eurobioc2026-tidyomics-hackathon-results/nanobanana2.png?w=578&#038;ssl=1" class="img-fluid figure-img" data-recalc-dims="1"></p>
<figcaption>Schematic representation of the Tidyomics hackathon aims</figcaption>
</figure>
</div>
</section>
<section id="whats-new" class="level1">
<h1>What’s new?</h1>
<p>The advances produced during this hackathon are available and described in detail in the <a href="https://osf.io/preprints/biohackrxiv/cd9s6_v1" rel="nofollow" target="_blank">BioHackrXiv</a> publication. In summary:</p>
<ol type="1">
<li><code>tidyAnnData</code> has been introduced as a new package to provide tidy operations for AnnData objects generated by the <code>anndataR</code> package</li>
<li>Information access to core <code>Tidyomics</code> packages was inconsistent and some links were broken in the main GitHub page; taking advantage of this hackathon, access to correct information was restored</li>
<li>The <code>DFplyr</code> package was enhanced by improving current methods (e.g. <code>GroupedDataFrame</code> and <code>count.DataFrame</code>) and making them suitable for universal column names</li>
<li>The <code>tidybulk</code> package was enhanced to adjust the <code>lfcShrink()</code> function to use the different available methods (<code>apeglm</code> and <code>ashr</code>) and to generate a reduced dimensionality-based plot (PCA) for visual inspection of e.g. batch effects and outlier detection</li>
<li>A standardised vignette for <code>tidySingleCellExperiment</code> has been developed to provide an extensive and concise guide for new users, encompassing both examples comparable to base R code and best practices on single-cell analysis using tidy operations</li>
</ol>
</section>
<section id="whats-next" class="level1">
<h1>What’s next?</h1>
<p>Five major contributions in two productive days is all a win!</p>
<p>Beyond this wonderful experience, there is work to do: finalising the development of <code>tidyAnnData</code> to make it publicly available, fixing additional bugs and enhancing current packages, and standardising the rest of the <code>Tidyomics</code> packages’ vignettes. These efforts open the doors for future events and continuing open-science work.</p>
<p>We look forward to seeing you at the coming <code>Tidyomics</code> hackathon events to speed up software development, bug fixing, and new material development from <a href="https://github.com/orgs/tidyomics/projects/1" rel="nofollow" target="_blank">open problems in Tidyomics</a>, or to work on your own ideas for providing tidy operations in omics data analysis.</p>


</section>

<p>
© 2025 tidyomics. 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://tidyomics.github.io/tidyomicsBlog/posts/2026-07-20-eurobioc2026-tidyomics-hackathon-results/"> tidyomicsBlog</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/outcomes-from-eurobioc2026-tidyomics-hackathon/">Outcomes from EuroBioC2026 Tidyomics Hackathon</a>]]></content:encoded>
					
		
		<enclosure url="https://tidyomics.github.io/tidyomicsBlog/posts/2026-07-20-eurobioc2026-tidyomics-hackathon-results/thumbnail.jpg" length="0" type="image/jpeg" />

		<post-id xmlns="com-wordpress:feed-additions:1">402806</post-id>	</item>
		<item>
		<title>Reading &#8216;Radical Uncertainty&#8217;</title>
		<link>https://www.r-bloggers.com/2026/07/reading-radical-uncertainty/</link>
		
		<dc:creator><![CDATA[datascienceconfidential - r]]></dc:creator>
		<pubDate>Sun, 19 Jul 2026 00:00:00 +0000</pubDate>
				<category><![CDATA[R bloggers]]></category>
		<guid isPermaLink="false">https://datascienceconfidential.github.io/r/economics/book-reviews/2026/07/19/reading-radical-undertainty.html</guid>

					<description><![CDATA[<p>I recently read John Kay and Mervyn King’s book Radical Uncertainty as part of an economics book club and I thought I would share some thoughts on the book here.</p>
<p>I’ve never read anything by John Kay before, but this is the second book by King which I ...</p>
<strong>Continue reading</strong>: <a href="https://www.r-bloggers.com/2026/07/reading-radical-uncertainty/">Reading ‘Radical Uncertainty’</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://datascienceconfidential.github.io/r/economics/book-reviews/2026/07/19/reading-radical-undertainty.html"> datascienceconfidential - 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>I recently read John Kay and Mervyn King’s book <em>Radical Uncertainty</em> as part of an economics book club and I thought I would share some thoughts on the book here.</p>

<p>I’ve never read anything by John Kay before, but this is the second book by King which I have read, after <a href="https://en.wikipedia.org/wiki/The_End_of_Alchemy" rel="nofollow" target="_blank"><em>The End of Alchemy</em></a>, which is about banking regulation. <em>Radical Uncertainty</em> is about statistics, and especially about the problems with assuming that we can make probabilistic calculations while neglecting the possibility of things which we haven’t even contemplated happening. I was pretty fascinated by the first half of the book, but it does become quite long-winded in the second half, and repeats many of its points over and over again.</p>

<p>The book makes a lot of good points, but I would also like to point out some mistakes which it makes when talking about statistical modelling.</p>

<p>In the language of the book, Radical Uncertainty means Knightian Uncertainty. Knightian Uncertainty is named after Frank Knight, who made a distinction between uncertainty and risk. The basic idea is that you have a probability space $(X, \mu, \Sigma)$ where $X$ is a set, $\mu$ is a probability measure on $X$ and $\Sigma$ is the sigma-algebra of events. There’s absolutely no reason not to assume that $X$ is finite, so really we have a finite set $X$ and a probability $\mu(x)$ attached to each element $x \in X$. Suppose we make a draw from $X$</p>

\[x \sim (X, \mu)\]

<p>According to Knight’s definition, risk is “we don’t know $x$” and uncertainty is “we don’t know $X$”. One point which the book likes to hammer on is that in a lot of real-life situations, we really can’t possibly know $X$. So probability calculations (such as those made by bankers prior to 2008) are invariably wrong since they ignore “off-model events”. In 2008, this led to disastrous consequences.</p>

<p>I would like to mention at this point that there is a third kind of uncertainty. What if you know $X$ but don’t know $\mu$? This kind of uncertainty arises in a lot of gambling problems, for example when a bookmaker wants to make odds on the World Cup. You know exactly which outcomes are possible (all possible tournament brackets) but you need to assign a probability to each one. I was not able to find a name for this kind of uncertainty, but since it is exactly the situation faced in Bayesian statistics, it could be called Bayesian Uncertainty.</p>

<p>Kay and King make a pretty convincing case that Knightian uncertainty is important. However, I do think they slip up when talking about probability. For example, describing <a href="https://math.stackexchange.com/questions/270093/bayes-theorem-example-in-nate-silvers-the-signal-and-the-noise" rel="nofollow" target="_blank">a calculation by Nate Silver</a> of the probability of the 9/11 attacks, they say (Chapter 11)</p>

<blockquote>
  <p>So Silver’s calculation of probability was meaningless.</p>
</blockquote>

<p>It doesn’t make sense to say that a probability calculation is meaningless. Every probability calculation is conditional on a probability model $(X, \mu)$. Given a model, you can calculate the probability of any subset of $X$ (or any event in $\Sigma$ in the continuous case). So you could say that Silver’s <em>model</em> was meaningless. But, in the context of the model, any probability he calculated makes perfect sense.</p>

<p>There is a temptation (to which Kay and King appear to succumb) to assume that there are some sort of “true” probabilities of things which modellers are attempting to calculate. But there are no such true probabilities, because there are no true probability models. A probability model is just an expression of what you don’t know. Different people can have different models because they are ignorant of different things. Thus, they can assign different probabilities to the same event, and this is fine. In some toy examples, such as rolling a die, everybody probably agrees more or less on the same probability model. But not so in the real world.</p>

<p>A similar error crops up when describing Keynes’ objection to the Principle of Indifference in Chapter 1</p>

<blockquote>
  <p>If, to take an example, we have no information whatever as to the area or population of the countries of the world, a man is as likely to be an inhabitant of Great Britain as of France, there being no reason to prefer one alternative to the other. He is also as likely to be an inhabitant of Ireland as of France. And on the same principle he is as likely to be an inhabitant of the British Isles as of France. And yet these conclusions are plainly inconsistent. For our first two propositions together yield the conclusion that he is twice as likely to be an inhabitant of the British Isles as of France. Unless we argue, as I do not think we can, that the knowledge that the British Isles composed of Great Britain and Ireland is a ground for supposing that a man is more likely to inhabit them than France, there is no way out of the contradiction.</p>
</blockquote>

<p>Here the original probability model is</p>

\[p(\text{France}) = p(\text{Ireland}) = p(\text{GB}) = \cdots\]

<p>If you add the knowledge that the British Isles consists of GB + Ireland, the of course $p(\text{British Isles}) = 2p(\text{France})$. There is no contradiction here, but merely a failure to imagine that you could be ignorant of the fact that BI = GB + Ireland in the first place. New knowledge leads you to update your model, as it should.</p>

<p>It also seems that Kay and King may not be familiar with Bayesian statistics. For example, right at the end of the book they quote Savage:</p>

<blockquote>
  <p>There is some temptation to introduce probabilities of a second order so that the person would find himself saying such things as ‘the probability that B is more probable than C is greater than the probability that F is more probable than G.’ But such a program seems to meet insurmountable difficulties […] once second order probabilities are introduced, the introduction of an endless hierarchy seems inescapable. Such a hierarchy seems very difficult to interpret, and it seems at best to make the theory less realistic, not more.</p>
</blockquote>

<p>Well, the prior distribution used in every Bayesian statistics problem is a probability distribution over probability distributions, so you definitely <em>can</em> consider probabilities of probabilities!</p>

<p>Anyway, these are minor points. Kay and King make a convincing argument, at great length, that in general you don’t know $X$ and therefore can’t construct a very good probability model. I don’t have any problem with this. But what should you do if you can’t make a probability model? To their credit, they propose an alternative approach, which they describe as choosing a “reference narrative” and essentially acting as though it is going to happen, while also taking some time to think about what you will do if the reference narrative doesn’t happen.</p>

<p>This process of choosing a reference narrative could also be described in terms of probability. In this case, instead of trying to construct the whole probability space $(X, \mu)$, you simply consider some set of plausible outcomes $X$, choose whichever $x \in X$ is the most probable and assign a probability weight of $1$ to it. In other words, you just choose the likeliest outcome and assume that it’s going to happen. This is much easier than constructing a probability space, and I think that Kay and King make a convincing case/ that this is generally how people act in real life. As Stigler says in <a href="https://arxiv.org/pdf/0804.2996" rel="nofollow" target="_blank">The Epic Story of Maximum Likelihood</a></p>

<blockquote>
  <p>At a superficial level, the idea of maximum likelihood must be prehistoric[…]</p>
</blockquote>

<p>I wondered whether I could understand <em>why</em> this approach works. Why would it be better, in a world of radical uncertainty, to take the likeliest outcome and run with it rather than trying to be a Bayesian?</p>

<p>To make a calculation, we need some sort of measure of how well a model performs versus reality. I found a very interesting <a href="https://www.sciencedirect.com/science/article/pii/S0039368125000159" rel="nofollow" target="_blank">paper</a> by Süskind which makes a distinction between probability (the degree to which we believe something) and verisimilitude (the degree to which something is actually true). Probability is conditional on a probability model; verisimilitude is a property of the model itself. One of Süskind’s examples concerns black swans. Suppose there are 99 white swans for every black swan. The model “all swans are white” is wrong, but it makes a correct prediction 99 out of 100 times. The model “all swans are green” never makes a correct prediction. Therefore, “all swans are white” is not a great model, but it does have high verisimilitude.</p>

<p>Süskind is at pains to point out that verisimilitude is not the same as predictive accuracy. For example, assuming that <a href="https://en.wikipedia.org/wiki/Paul_Daniels" rel="nofollow" target="_blank">Paul Daniels</a> has magical powers predicts the outcome of his tricks very well, but it is <a href="https://www.youtube.com/watch?v=nnz7LApE0PY" rel="nofollow" target="_blank">not a model with high verisimilitude</a> because it is not close to the truth. This is sort-of similar to the idea in machine learning where accuracy often doesn’t measure the thing which you’re actually interested in, and it’s better to use other measures of predictive performance instead.</p>

<p>Let’s suppose the true world has $4$ possible states with true probabilities $(p_1, p_2, p_3, 0)$ (the reason for adding a fourth state is to have a “junk” state which a model is allowed to predict but which actually never happens).<sup><a href="https://datascienceconfidential.github.io/r/economics/book-reviews/2026/07/19/reading-radical-undertainty.html#myfootnote1" rel="nofollow" target="_blank">1</a></sup> Suppose $p_2 > p_1$. Suppose that observers have only observed states $1$ and $2$ in the past (due to non-stationarity, aka data drift, state $3$ has never happened yet, but in fact is quite likely). A Bayesian would get the probability distribution</p>

\[(p_1/(p_1+p_2), p_2/(p_1+p_2), 0, 0).\]

<p>A maximum-likelihoodist would get the distribution $(0, 1, 0, 0)$. And a conservative maximum-likelihoodist who assumes that their reference narrative (state $2$) is likely to happen but they should also make allowances for the unknowable might choose the distribution $(0, 1/2, 0, 1/2)$.</p>

<p>Now suppose we decide to measure the verisimilitude of a our probability model $(x_1, x_2, x_3, x_4)$ by</p>

\[V(x) = 1 &#8211; \sum_{i=1}^4 (x_i – p_i)^2.\]

<p>You can check that the Bayesian always does better than the maximum-likelihoodist. But the conservative maximum-likelihoodist who follows the Kay-King recipe (follow your reference narrative while trying to hedge against the unknowable) can actually get a higher verisimilitude than the Bayesian who fails to take radical uncertainty into account, for example if $p_1=1/30, p_2=2/30$.</p>

<pre>p1 &lt;- 1/30
p2 &lt;- 2/30
p_true &lt;- c(p1, p2, 1-p1-p2, 0)
1-sum((c(p1/(p1+p2), p2/(p1+p2), 0, 0) - p_true)^2) # -0.26
1-sum((c(0, 1, 0, 0) - p_true)^2) # -0.68 (worse)
1-sum((c(0, 0.5, 0, 0.5) - p_true)^2) # -0.25 (better!)
</pre>

<p>Although this example is rather contrived, hopefully it does show that in the presence of Knightian Uncertainty, it can indeed be better just to take the likeliest outcome and run with it (while looking over your shoulder at the same time).</p>

<h1 id="economic-forecasts">Economic Forecasts</h1>

<p>As you would expect, the book is particularly focussed on economics. One of its conclusions is that you can’t expect to make reliable economic forecasts due to radical uncertainty. Your forecast has to be “I don’t know” and your actions have to be in accordance with whatever scenario you think is likeliest, given whatever set of scenarios you can imagine.</p>

<p>This all seems very reasonable. Countless studies have shown that <a href="https://newsroom.haas.berkeley.edu/why-forecasts-by-elite-economists-are-usually-wrong/" rel="nofollow" target="_blank">long-range economic forecasts are no better than random guessing</a>. So why do we believe them? What are forecasts <em>for</em>?</p>

<p>An interesting answer to this problem is suggested in <a href="https://www.hup.harvard.edu/books/9780674088825" rel="nofollow" target="_blank">a book by Jens Beckert</a>. The key idea is that economic activity depends on coordination. People can’t coordinate their actions unless they can agree on the future. It doesn’t matter what number they agree on; they just have to agree on <em>something</em>. Economic forecasts, even when they are meaningless, give people something to agree about. Ancient priests predicted the future using divination. They probably got it wrong most of the time, which leads to the question of why people didn’t simply get rid of the priests or switch to a new religion? Why didn’t incidents like <a href="https://en.wikipedia.org/wiki/Battle_of_Drepana" rel="nofollow" target="_blank">the sacred chickens being thrown overboard</a> happen more often?</p>

<p>One possible answer is that it didn’t matter whether their predictions were true. It also didn’t matter whether people really believed their predictions. All that mattered was that people acted <em>as if</em> the predictions were true. The purpose of a long-range economic forecast is not, for example, to give an accurate guess at China’s benchmark interest rate in 2036. Everyone knows that the guess is wrong.<sup><a href="https://datascienceconfidential.github.io/r/economics/book-reviews/2026/07/19/reading-radical-undertainty.html#myfootnote2" rel="nofollow" target="_blank">2</a></sup> But lots of people making deals and plans involving China in 2036 have to agree on a number, and it might as well be the one obtained by some arcane economic modelling exercise with relatively high academic stature. In this sense, it would not be right to say that economic forecasts serve a quasi-religious role in our society. Rather, it seems that forecasting literally <em>is</em> a religion. It works because people have faith in it. Or rather, not because people have faith in it, but because people agree to act as if they do. If people could be convinced to have faith in a computer which spits out random numbers, that would probably work just as well (and, intriguingly, be more economically efficient).<sup><a href="https://datascienceconfidential.github.io/r/economics/book-reviews/2026/07/19/reading-radical-undertainty.html#myfootnote3" rel="nofollow" target="_blank">3</a></sup></p>

<hr />

<p><small>
<a name="myfootnote1">1</a>: I know above I said there were no true probability models, but this is just a theoretical world.
</small></p>

<p><small>
<a name="myfootnote2">2</a>: Most predictive models would result in extremely wide confidence/credible intervals if uncertainty was properly taken into account. For example, when I worked in public health, models were based on <a href="https://www.simid.be/masterthesis2/" rel="nofollow" target="_blank">“contact matrices”</a> which had been compiled “using surveys”. There was no uncertainty in these matrices; they were just taken as-is as a model input. Even so, the modellers insisted on using 80% (or sometimes even 50%) credible intervals for their predictions because the 95% intervals were so wide that they were just silly. In practice, the end user don’t care about intervals anyway. The intervals are only for academic papers. All the public wants is a point prediction.
</small></p>

<p><small>
<a name="myfootnote3">3</a>: If you take this point of view, astrology begins to make a lot of sense. Why did astrology used to be such a popular form of divination? Perhaps because everybody could agree on the raw data from which the predictions were being made (namely, the positions of the stars and planets). At the same time, the predictions themselves were constructed by following arcane mathematical rules such as those described in the early editions of W. W. Rouse Ball’s <a href="https://www.gutenberg.org/ebooks/26839" rel="nofollow" target="_blank"><em>Mathematical Recreations</em></a>. These rules were difficult to follow, and variances in predictions from the same raw material could therefore be explained by errors in following the recipe. So astrology itself behaved as a sort of seedable random number generator which produced predictions upon which everyone could agree, which also leaving open the possibility that the predictions could be wrong. Perhaps this is why economic forecasting <em>has</em> to be complicated. If it wasn’t, then it would be too easy for everyone to realise that it doesn’t work?
</small></p>

<hr />

<p>A comment on comments: I recently removed the Disqus-powered comments section from the blog because it started injecting ads. I may replace it by an alternative such as <a href="https://chocapikk.com/posts/2025/setting-up-giscus-comments/" rel="nofollow" target="_blank">Giscus</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://datascienceconfidential.github.io/r/economics/book-reviews/2026/07/19/reading-radical-undertainty.html"> datascienceconfidential - 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/reading-radical-uncertainty/">Reading ‘Radical Uncertainty’</a>]]></content:encoded>
					
		
		<enclosure url="" length="0" type="" />

		<post-id xmlns="com-wordpress:feed-additions:1">402678</post-id>	</item>
		<item>
		<title>Tabular Foundation Models: A First Look with TabICL</title>
		<link>https://www.r-bloggers.com/2026/07/tabular-foundation-models-a-first-look-with-tabicl/</link>
		
		<dc:creator><![CDATA[R&#039;tichoke]]></dc:creator>
		<pubDate>Sat, 18 Jul 2026 18:30:00 +0000</pubDate>
				<category><![CDATA[R bloggers]]></category>
		<guid isPermaLink="false">https://rtichoke.netlify.app/posts/tabular-foundation-models-tabicl.html</guid>

					<description><![CDATA[<p>Tabular foundation models are a new category of machine learning model that can perform zero-shot (i.e., without any gradient updates) prediction on tabular datasets. They are pretrained on a distribution of synthetic tables and can transfer to n...</p>
<strong>Continue reading</strong>: <a href="https://www.r-bloggers.com/2026/07/tabular-foundation-models-a-first-look-with-tabicl/">Tabular Foundation Models: A First Look with TabICL</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://rtichoke.netlify.app/posts/tabular-foundation-models-tabicl.html"> R&#039;tichoke</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>Tabular foundation models are a new category of machine learning model that can perform zero-shot (i.e., without any gradient updates) prediction on tabular datasets. They are pretrained on a distribution of synthetic tables and can transfer to new datasets using in-context learning. TabICL is one of the strongest open-source tabular foundation models, and this post explores how it works and compares its performance to XGBoost on a credit-risk dataset, all from R using the <code>reticulate</code> package to call Python.</p>
<section id="what-is-a-tabular-foundation-model" class="level2">
<h2 class="anchored" data-anchor-id="what-is-a-tabular-foundation-model">What is a tabular foundation model?</h2>
<p>A foundation model has three ingredients, and the tabular version satisfies them in specific ways:</p>
<ol type="1">
<li><strong>Pretrained on many datasets</strong>, not one. You don’t train on your specific table; you train on a <em>distribution</em> of tables.</li>
<li><strong>Transfers to a new dataset in context</strong> — no gradient steps on the new dataset. The model “reads” the training rows and predicts on test rows in a single forward pass.</li>
<li><strong>The model is a sequence transformer.</strong> Same architecture family as LLMs, just operating over rows of a table instead of tokens.</li>
</ol>
<p>Ingredient #1 is where tabular FMs diverge from text/vision FMs. There is no corpus of labeled tables to scrape. Instead, TabICL uses <strong>synthetic data</strong>: millions of tabular datasets drawn from structured priors. The pretraining task is “given some rows of a synthetic table, predict the target for held-out rows.” After seeing millions of these, the transformer learns a general <em>procedure</em> for in-context tabular prediction, not a specific dataset.</p>
</section>
<section id="how-does-tabicl-work" class="level2">
<h2 class="anchored" data-anchor-id="how-does-tabicl-work">How does TabICL work?</h2>
<p>Two stages, in order:</p>
<ol type="1">
<li><strong>Column-then-row attention.</strong> Each column is processed independently to produce a fixed-dimensional embedding of that column’s values; then rows attend across columns to produce a fixed-dimensional <em>row embedding</em>. This decouples the model from the schema. A 10-column table and a 200-column table both produce row embeddings of the same dimension.</li>
<li><strong>Transformer ICL over rows.</strong> Row embeddings (training + test) are fed to a transformer that uses standard self-attention. Training rows with labels act as “context”; test rows get predicted in a single forward pass. No gradient updates at inference.</li>
</ol>
<p>That’s the whole idea. The pretraining objective — “predict held-out targets given in-context rows” — is exactly what the model does at inference, so zero-shot transfer is structurally built in. The two-stage design is what lets TabICL scale to larger training sets than TabPFNv2, which alternates column- and row-wise attention and gets expensive past 10K rows.</p>
</section>
<section id="setup-python-env-via-reticulate" class="level2">
<h2 class="anchored" data-anchor-id="setup-python-env-via-reticulate">Setup: Python env via reticulate</h2>
<p>TabICL is Python-first. From R, use <code>reticulate</code>. Assuming you have a Python env from the <a href="https://rtichoke.netlify.app/posts/getting-started-with-reticulate.html" rel="nofollow" target="_blank">previous post</a>:</p>
<div class="cell">
<pre>library(reticulate)
py_install(c(&quot;tabicl&quot;, &quot;torch&quot;, &quot;pandas&quot;, &quot;scikit-learn&quot;), pip = TRUE, pip_options = &quot;--force-reinstall --no-cache-dir&quot;)</pre>
</div>
<p><code>tabicl</code> downloads a pretrained checkpoint (a few hundred MB) from Hugging Face on the first <code>fit()</code> call and caches it locally.</p>
</section>
<section id="a-first-example-predicting-credit-default-with-tabicl" class="level2">
<h2 class="anchored" data-anchor-id="a-first-example-predicting-credit-default-with-tabicl">A first example: predicting credit default with TabICL</h2>
<p>We’ll use a LendingClub-style credit dataset (10,000 rows, ~150 features) that’s already in the repo. The target is <code>bad_flag</code> (1 = default / charge-off, 0 = paid). First, a little R-side prep:</p>
<div class="cell">
<pre>library(readr)
library(dplyr)
library(rsample)

# Load the credit sample (path is relative to the project root, not this post)
credit &lt;- read.csv(&quot;https://bit.ly/42ypcnJ&quot;)

# Keep a focused subset — mostly numeric features plus a few categoricals
keep_cols &lt;- c(
  &quot;loan_amnt&quot;, &quot;int_rate&quot;, &quot;installment&quot;, &quot;grade&quot;, &quot;sub_grade&quot;,
  &quot;annual_inc&quot;, &quot;dti&quot;, &quot;revol_util&quot;, &quot;total_acc&quot;, &quot;open_acc&quot;,
  &quot;delinq_2yrs&quot;, &quot;pub_rec&quot;, &quot;fico_range_low&quot;, &quot;inq_last_6mths&quot;,
  &quot;home_ownership&quot;, &quot;verification_status&quot;, &quot;purpose&quot;, &quot;term&quot;,
  &quot;bad_flag&quot;
)

df &lt;- credit |&gt;
  select(all_of(keep_cols)) |&gt;
  mutate(across(where(is.character), as.factor)) |&gt;
  mutate(bad_flag = factor(bad_flag))

# Train / test split (stratified on the target since it's imbalanced)
set.seed(42)
split &lt;- initial_split(df, prop = 0.8, strata = &quot;bad_flag&quot;)
train &lt;- training(split)
test  &lt;- testing(split)

# Quick class balance sanity check
prop.table(table(train$bad_flag))</pre>
<div class="cell-output cell-output-stdout">
<pre>
        0         1 
0.8838605 0.1161395 </pre>
</div>
</div>
<p>Now call TabICL through reticulate. One gotcha: pass features as a data frame, <strong>not</strong> a matrix — TabICL detects categorical columns by dtype and ordinal-encodes them internally. Coercing to a matrix makes everything character and loses that handling.</p>
<div class="cell">
<pre>library(reticulate)

# Import the Python classifier
tabicl &lt;- import(&quot;tabicl&quot;)
clf &lt;- tabicl$TabICLClassifier(random_state = 42L)

# Keep X as a data frame — reticulate auto-converts to a pandas DataFrame,
# preserving dtypes so TabICL can detect categoricals.
X_train &lt;- train[, setdiff(names(train), &quot;bad_flag&quot;)]
y_train &lt;- as.character(train$bad_flag)
X_test  &lt;- test[,  setdiff(names(test),  &quot;bad_flag&quot;)]

# TabICL's &quot;fit&quot; is cheap — it just stashes the training data.
# The actual prediction happens in the forward pass at predict() time.
clf$fit(X_train, y_train)</pre>
<div class="cell-output cell-output-stdout">
<pre>TabICLClassifier()</pre>
</div>
<pre># Predicted probabilities for the positive class
proba &lt;- clf$predict_proba(X_test)
pred_prob &lt;- as.numeric(proba[, 2])</pre>
</div>
<p>A couple of things worth noting if you’ve only ever used R-native models:</p>
<ul>
<li><strong><code>fit()</code> returns almost instantly.</strong> TabICL doesn’t train on your data; it just stores it. The work happens at <code>predict()</code> time — the transformer’s single forward pass over (train + test) rows together. Your training rows <em>are</em> the context.</li>
<li><strong>The first <code>fit()</code> downloads the pretrained checkpoint.</strong> Subsequent uses load from cache.</li>
</ul>
</section>
<section id="evaluation-tabicl-vs-xgboost-on-the-same-split" class="level2">
<h2 class="anchored" data-anchor-id="evaluation-tabicl-vs-xgboost-on-the-same-split">Evaluation: TabICL vs XGBoost on the same split</h2>
<div class="cell">
<pre>library(tidymodels)
library(tictoc)

# XGBoost with a modest tuning grid — a realistic &quot;I spent 10 minutes&quot; baseline
xgb_spec &lt;- boost_tree(
  trees = 500,
  tree_depth = tune(),
  min_n = tune(),
  learn_rate = 0.01
) |&gt;
  set_engine(&quot;xgboost&quot;) |&gt;
  set_mode(&quot;classification&quot;)

xgb_grid &lt;- grid_regular(
  tree_depth(range = c(4, 10)),
  min_n(range = c(2, 20)),
  levels = 3
)

xgb_wf &lt;- workflow() |&gt;
  add_model(xgb_spec) |&gt;
  add_formula(bad_flag ~ .)

folds &lt;- vfold_cv(train, v = 5, strata = &quot;bad_flag&quot;)

tic(&quot;XGBoost tuning&quot;)
xgb_res &lt;- tune_grid(
  xgb_wf,
  resamples = folds,
  grid = xgb_grid,
  metrics = metric_set(roc_auc)
)
toc(log = TRUE)</pre>
<div class="cell-output cell-output-stdout">
<pre>XGBoost tuning: 81.94 sec elapsed</pre>
</div>
<pre>best_xgb &lt;- select_best(xgb_res, metric = &quot;roc_auc&quot;)
xgb_final &lt;- finalize_workflow(xgb_wf, best_xgb) |&gt;
  fit(train)

xgb_prob &lt;- predict(xgb_final, test, type = &quot;prob&quot;)$.pred_1</pre>
</div>
<p>Now TabICL on the clock:</p>
<div class="cell">
<pre>tic(&quot;TabICL fit + predict&quot;)
clf$fit(X_train, y_train)</pre>
<div class="cell-output cell-output-stdout">
<pre>TabICLClassifier()</pre>
</div>
<pre>tabicl_prob &lt;- as.numeric(clf$predict_proba(X_test)[, 2])
toc(log = TRUE)</pre>
<div class="cell-output cell-output-stdout">
<pre>TabICL fit + predict: 110.86 sec elapsed</pre>
</div>
</div>
<p>Compare:</p>
<div class="cell">
<pre>library(pROC)

xgb_auc &lt;- auc(test$bad_flag, xgb_prob)
tabicl_auc &lt;- auc(test$bad_flag, tabicl_prob)

results &lt;- tibble(
  model = c(&quot;XGBoost (tuned, 5-fold CV)&quot;, &quot;TabICL (zero-shot)&quot;),
  roc_auc = c(xgb_auc, tabicl_auc)
)
results</pre>
<div class="cell-output cell-output-stdout">
<pre># A tibble: 2 × 2
  model                      roc_auc
  &lt;chr&gt;                        &lt;dbl&gt;
1 XGBoost (tuned, 5-fold CV)   0.648
2 TabICL (zero-shot)           0.701</pre>
</div>
</div>
</section>
<section id="some-observations" class="level2">
<h2 class="anchored" data-anchor-id="some-observations">Some observations</h2>
<p>From running this on the credit sample (8K-row training set, 18 features, ~12% positive rate):</p>
<ul>
<li><strong>TabICL is a serious challenger</strong> Zero-shot ROC AUC landed around <strong>0.70</strong> comparable to a modestly tuned XGBoost on the same split</li>
<li><strong>The win is “no tuning loop.”</strong> XGBoost requires a grid search with multi-fold CV. TabICL requires none of that, <code>fit</code> and <code>predict</code> and you’re done. Useful for quick baselines, cold starts, or benchmark before you engineer features.</li>
<li><strong>TabICL is not free.</strong> First run downloads a checkpoint. On very wide tables (500+ columns), inference cost climbs. Not the right tool for every tabular job.</li>
</ul>
</section>
<section id="when-tabicl-is-and-isnt-a-good-fit" class="level2">
<h2 class="anchored" data-anchor-id="when-tabicl-is-and-isnt-a-good-fit">When TabICL is (and isn’t) a good fit</h2>
<p><strong>Reach for TabICL when:</strong></p>
<ul>
<li>You want a strong baseline on a new dataset without a tuning loop.</li>
<li>The dataset is small-to-medium (hundreds to tens of thousands of rows) the regime where in-context learning shines</li>
<li>You’re sweeping many datasets quickly and want a zero-shot default</li>
<li>The task is classification (v1 was classification-only; v2 adds regression and time-series forecasting via <code>TabICLForecaster</code>).</li>
</ul>
<p><strong>Don’t reach for TabICL when:</strong></p>
<ul>
<li><strong>Monotonicity or regulatory interpretability is non-negotiable.</strong> XGBoost/LightGBM have native monotonic constraints and SHAP-tree; TabICL is a transformer with no native monotonic constraints. In a credit-scoring pipeline under model risk management review, that’s a real blocker.</li>
<li><strong>The dataset is very large (500K+ rows).</strong> TabICL scales that far with CPU/disk offloading but accuracy may degrade. Tuned GBDT remains the safer bet at scale.</li>
<li><strong>You need custom missing-value imputation.</strong> TabICL handles missing values internally, but if your domain has a specific convention (sentinel values, MICE), preprocessing would be required.</li>
<li><strong>Regression with an unusual target distribution.</strong> v2’s regression support is newer than classification; check the <a href="https://tabicl.readthedocs.io/" rel="nofollow" target="_blank">docs</a>.</li>
</ul>
</section>
<section id="takeaway" class="level2">
<h2 class="anchored" data-anchor-id="takeaway">Takeaway</h2>
<p>Tabular foundation models don’t replace XGBoost they add a strong zero-shot baseline that needs no tuning and runs in a single forward pass. For small-to-medium tabular classification, TabICL is a credible challenger to the GBDT default. Using it to benchmark before committing to a tuning loop would be a good idea. GBDTs are the way to go when the dataset is large, the constraints are regulatory, or native interpretability is required.</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://rtichoke.netlify.app/posts/tabular-foundation-models-tabicl.html"> R&#039;tichoke</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/tabular-foundation-models-a-first-look-with-tabicl/">Tabular Foundation Models: A First Look with TabICL</a>]]></content:encoded>
					
		
		<enclosure url="https://rtichoke.netlify.app/images/tabicl-thumbnail.png" length="0" type="image/png" />

		<post-id xmlns="com-wordpress:feed-additions:1">402687</post-id>	</item>
		<item>
		<title>Mapping U.S. Rents by County in R with tidycensus, sf and ggplot2</title>
		<link>https://www.r-bloggers.com/2026/07/mapping-u-s-rents-by-county-in-r-with-tidycensus-sf-and-ggplot2/</link>
		
		<dc:creator><![CDATA[Lukas Halvorsen]]></dc:creator>
		<pubDate>Sat, 18 Jul 2026 12:08:14 +0000</pubDate>
				<category><![CDATA[R bloggers]]></category>
		<guid isPermaLink="false">https://datascienceplus.com/?p=32667</guid>

					<description><![CDATA[<div style = "width:60%; display: inline-block; float:left; "> The U.S. Census Bureau publishes the rent that a typical household pays in every county in the country, updated every year, and gives it…</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/mapping-u-s-rents-by-county-in-r-with-tidycensus-sf-and-ggplot2/">Mapping U.S. Rents by County in R with tidycensus, sf and ggplot2</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://datascienceplus.com/mapping-u-s-rents-by-county-in-r-with-tidycensus-sf-and-ggplot2/"> R Programming – DataScience+</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 U.S. Census Bureau publishes the rent that a typical household pays in every county in the country, updated every year, and gives it away through a free API. With the <code>tidycensus</code> package you can pull that data — numbers <em>and</em> the map polygons to draw it — in a single function call, then turn it into a national map in about twenty lines. Here we map median gross rent by county to see where renting is expensive and where it is cheap.</p>
<h2 id="getting-the-data">Getting the data</h2>
<p>The data comes from the <strong>American Community Survey (ACS)</strong>, the Census Bureau’s rolling survey of about 3.5 million addresses a year. We use the <strong>5-year</strong> estimates (here 2019–2023), which pool five years of responses so that even small, rural counties get a reliable number. The variable we want is <code>B25064_001</code>: <strong>median gross rent</strong> in dollars — contract rent plus utilities — for renter-occupied housing.</p>
<p><code>tidycensus</code> talks to the ACS API, and the API needs a <strong>free key</strong>. Request one at <a href="https://api.census.gov/data/key_signup.html" rel="nofollow" target="_blank">api.census.gov/data/key_signup.html</a>; it arrives by email in a minute. Activate it, then install it into R once — after that <code>tidycensus</code> finds it automatically in every session, so you never put it in a script you share:</p>
<pre>library(tidycensus)
census_api_key(&quot;YOUR_KEY_HERE&quot;, install = TRUE)  # run once; writes to ~/.Renviron
</pre>
<p>With the key set, load the packages we need:</p>
<pre>library(tidycensus)
library(tigris)     # shift_geometry(): repositions Alaska & Hawaii
library(dplyr)
library(sf)
library(ggplot2)
library(scales)     # dollar labels
library(patchwork)  # combine the small-multiple maps

options(tigris_use_cache = TRUE)  # cache boundary files after first download
</pre>
<p>Now one call does everything. We ask for the rent variable at <code>geography = &quot;county&quot;</code>, and — this is what makes <code>tidycensus</code> special — set <code>geometry = TRUE</code> so it also downloads the county boundaries and returns them joined to the data as an <code>sf</code> object. Leaving <code>state</code> unset gives us <strong>every county in the country</strong>; <code>shift_geometry()</code> then tucks Alaska and Hawaii under the lower 48 so the whole nation fits one frame.</p>
<pre>us &lt;- get_acs(
  geography  = &quot;county&quot;,
  variables  = &quot;B25064_001&quot;,   # median gross rent (dollars)
  year       = 2023,
  survey     = &quot;acs5&quot;,
  geometry   = TRUE,
  resolution = &quot;20m&quot;           # generalized boundaries: smaller, faster, fine for a national map
)

us &lt;- shift_geometry(us)
</pre>
<p>The result is a tidy <code>sf</code> data frame — one row per county, the value in <code>estimate</code>, its 90% margin of error in <code>moe</code>, and a <code>geometry</code> column. Always look before drawing:</p>
<pre>us                       # an sf object: data + polygons together
## Simple feature collection with 3222 features and 5 fields
## Geometry type: GEOMETRY
## Dimension:     XY
## Bounding box:  xmin: -3112200 ymin: -1697728 xmax: 2258154 ymax: 1558935
## Projected CRS: USA_Contiguous_Albers_Equal_Area_Conic
## First 10 features:
##    GEOID                         NAME   variable estimate moe
## 1  13027       Brooks County, Georgia B25064_001      752  79
## 2  31095   Jefferson County, Nebraska B25064_001      659  50
## 3  51683      Manassas city, Virginia B25064_001     1835  62
## 4  56021      Laramie County, Wyoming B25064_001     1080  29
## 5  13135     Gwinnett County, Georgia B25064_001     1713  16
## 6  20001         Allen County, Kansas B25064_001      685  60
## 7  27065    Kanabec County, Minnesota B25064_001     1003  83
## 8  28107   Panola County, Mississippi B25064_001      859  44
## 9  31185        York County, Nebraska B25064_001      885  49
## 10 42063 Indiana County, Pennsylvania B25064_001      786  28
##                          geometry
## 1  MULTIPOLYGON (((1163909 -64...
## 2  MULTIPOLYGON (((-115252.6 3...
## 3  MULTIPOLYGON (((1580860 292...
## 4  MULTIPOLYGON (((-765818.2 5...
## 5  MULTIPOLYGON (((1073286 -32...
## 6  MULTIPOLYGON (((41912.94 35...
## 7  MULTIPOLYGON (((192562.6 95...
## 8  MULTIPOLYGON (((527838.1 -3...
## 9  MULTIPOLYGON (((-152283 398...
## 10 MULTIPOLYGON (((1383131 460...

summary(us$estimate)     # the spread of county rents
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max.     NAs 
##   253.0   742.0   848.5   928.4  1021.0  2893.0      10

sum(is.na(us$estimate))  # counties with no published estimate
## [1] 10
</pre>
<p>Two things to note. A handful of counties come back <code>NA</code> — mostly tiny populations the Bureau suppresses for privacy; we’ll let them render in grey. And that <code>moe</code> column is a reminder these are <em>survey estimates</em>, not a census: a county’s rent is “$1,200 ± $80,” not exactly $1,200. For a national map the uncertainty is small relative to the range, but it’s there.</p>
<h2 id="map-it">Map it</h2>
<p>Rent is a sequential quantity — low to high — so we fill with a sequential palette (viridis’s <code>plasma</code>), which is colorblind-safe and reads clearly in print. <code>geom_sf()</code> draws the polygons; everything else is labels and a clean, map-friendly theme.</p>
<pre>ggplot(us) +
  geom_sf(aes(fill = estimate), color = NA) +
  scale_fill_viridis_c(
    option   = &quot;plasma&quot;,
    labels   = label_dollar(),
    na.value = &quot;grey85&quot;,
    name     = &quot;Medianngross rent&quot;
  ) +
  labs(
    title    = &quot;Median gross rent by county, United States&quot;,
    subtitle = &quot;American Community Survey, 2019–2023 5-year estimates&quot;,
    caption  = &quot;Source: U.S. Census Bureau ACS, via the R tidycensus package&quot;
  ) +
  theme_void(base_size = 13) +
  theme(plot.title = element_text(face = &quot;bold&quot;),
        legend.position = c(0.92, 0.3))
</pre>
<figure class="code-plot"><img decoding="async" src="https://i1.wp.com/datascienceplus.com/wp-content/uploads/2026/07/map-1-1.png?w=578&#038;ssl=1" alt="plot of chunk map" data-recalc-dims="1" /></figure>
<h2 id="reading-the-map">Reading the map</h2>
<p>The typical county’s median rent is about <strong>$848</strong> — but the map is a story of a few bright clusters against a wide, darker interior. Rent runs from <strong>$253</strong> in Issaquena County up to <strong>$2,893</strong> in San Mateo County, an elevenfold spread. Only about <strong>6%</strong> of counties top $1,500, and they are not scattered randomly: they concentrate in coastal California and the Bay Area, the Washington–Boston corridor, and pockets around Seattle, Denver, and the mountain-resort West. Because every number in this paragraph is computed from the same object we mapped, the text always matches the picture — re-knit it next year and both update together.</p>
<p>The priciest counties make the coastal concentration concrete:</p>
<pre>d |&gt;
  arrange(desc(estimate)) |&gt;
  transmute(County = NAME, `Median rent` = scales::dollar(estimate)) |&gt;
  head(8) |&gt;
  knitr::kable()
</pre>
<div class="table-wrap">
<table>
<thead>
<tr>
<th align="left">County</th>
<th align="left">Median rent</th>
</tr>
</thead>
<tbody>
<tr>
<td align="left">San Mateo County, California</td>
<td align="left">$2,893</td>
</tr>
<tr>
<td align="left">Santa Clara County, California</td>
<td align="left">$2,814</td>
</tr>
<tr>
<td align="left">Marin County, California</td>
<td align="left">$2,584</td>
</tr>
<tr>
<td align="left">San Francisco County, California</td>
<td align="left">$2,419</td>
</tr>
<tr>
<td align="left">Orange County, California</td>
<td align="left">$2,352</td>
</tr>
<tr>
<td align="left">Contra Costa County, California</td>
<td align="left">$2,322</td>
</tr>
<tr>
<td align="left">Alameda County, California</td>
<td align="left">$2,318</td>
</tr>
<tr>
<td align="left">Loudoun County, Virginia</td>
<td align="left">$2,317</td>
</tr>
</tbody>
</table>
</div>
<h2 id="zooming-into-the-states">Zooming into the states</h2>
<p>A national map flattens what happens <em>inside</em> each state. The <code>state =</code> argument fixes that — it accepts a vector, so one call pulls several states at once. Here we grab the four most populous, then draw each on <strong>its own colour scale</strong> to bring out where rent concentrates within each one.</p>
<pre>states &lt;- c(&quot;California&quot;, &quot;Texas&quot;, &quot;Florida&quot;, &quot;New York&quot;)

sc &lt;- get_acs(geography = &quot;county&quot;, variables = &quot;B25064_001&quot;, state = states,
              year = 2023, survey = &quot;acs5&quot;, geometry = TRUE, resolution = &quot;20m&quot;)
sc$state &lt;- sub(&quot;.*, &quot;, &quot;&quot;, sc$NAME)   # pull the state name out of &quot;County, State&quot;

one_state &lt;- function(st) {
  ggplot(filter(sc, state == st)) +
    geom_sf(aes(fill = estimate), color = &quot;grey92&quot;, linewidth = 0.05) +
    scale_fill_viridis_c(option = &quot;plasma&quot;, labels = label_dollar(),
                         na.value = &quot;grey85&quot;, name = NULL) +
    labs(title = st) +
    theme_void(base_size = 12) +
    theme(plot.title = element_text(face = &quot;bold&quot;, hjust = 0.5),
          legend.key.width = unit(0.35, &quot;cm&quot;), legend.text = element_text(size = 8))
}

(one_state(&quot;California&quot;) | one_state(&quot;Texas&quot;)) /
(one_state(&quot;Florida&quot;)   | one_state(&quot;New York&quot;)) +
  plot_annotation(
    title   = &quot;Median gross rent by county — each state on its own colour scale&quot;,
    caption = &quot;Source: U.S. Census Bureau ACS, via the R tidycensus package&quot;,
    theme   = theme(plot.title = element_text(face = &quot;bold&quot;, size = 15)))
</pre>
<figure class="code-plot"><img decoding="async" src="https://i1.wp.com/datascienceplus.com/wp-content/uploads/2026/07/states-1.png?w=578&#038;ssl=1" alt="plot of chunk states" data-recalc-dims="1" /></figure>
<p>The pattern repeats with variations. California is expensive along almost its entire coast, with the Bay Area at the top of its range. New York is the sharpest split — downstate (New York City, Long Island, Westchester) against a uniformly inexpensive upstate. Florida’s money is on the water: the southeast around Miami, the southwest around Naples, the interior far cheaper. Texas is mostly its metros — Austin and Houston — but note the bright cluster out west, the Permian Basin oil counties, where a housing crunch has nothing to do with a big city.</p>
<p>One caution about reading these together: because each panel has its own scale, the same colour means different rents in different states — a “bright” Texas county (around $1,500) rents for far less than a bright California one (near (2,800). Per-state scales reveal internal *pattern*; for cross-state *levels*, use one shared scale (`limits = range(sc)estimate, na.rm = TRUE)`) instead.</p>
<h2 id="make-it-your-own">Make it your own</h2>
<p>Nothing above is specific to rent. Change one variable code and you map something else entirely; change <code>geography</code> and you change the resolution:</p>
<ul>
<li><code>B19013_001</code> — median household income</li>
<li><code>B25077_001</code> — median home value</li>
<li><code>DP02_0154PE</code> — households with a broadband subscription (percent)</li>
<li><code>geography = &quot;tract&quot;</code> with a <code>state</code> and <code>county</code> — a neighborhood-level map of a single metro</li>
</ul>
<p>To find a variable, browse the full ACS table with <code>load_variables(2023, &quot;acs5&quot;)</code> and search it — there are tens of thousands. The pattern stays the same: <code>get_acs()</code> with <code>geometry = TRUE</code>, then <code>geom_sf()</code>.</p>
<p>That’s all. You now have a script that pulls an authoritative national dataset, joins it to its own geography, and maps it — and re-points at any variable or place with a one-line change.</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://datascienceplus.com/mapping-u-s-rents-by-county-in-r-with-tidycensus-sf-and-ggplot2/"> R Programming – DataScience+</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/mapping-u-s-rents-by-county-in-r-with-tidycensus-sf-and-ggplot2/">Mapping U.S. Rents by County in R with tidycensus, sf and ggplot2</a>]]></content:encoded>
					
		
		<enclosure url="" length="0" type="" />

		<post-id xmlns="com-wordpress:feed-additions:1">402668</post-id>	</item>
		<item>
		<title>Mapping Live U.S. Wildfire Smoke in R with sf and ggplot2</title>
		<link>https://www.r-bloggers.com/2026/07/mapping-live-u-s-wildfire-smoke-in-r-with-sf-and-ggplot2/</link>
		
		<dc:creator><![CDATA[Lukas Halvoorsen]]></dc:creator>
		<pubDate>Fri, 17 Jul 2026 22:18:05 +0000</pubDate>
				<category><![CDATA[R bloggers]]></category>
		<guid isPermaLink="false">https://datascienceplus.com/?p=32655</guid>

					<description><![CDATA[<div style = "width:60%; display: inline-block; float:left; "> NOAA analysts trace wildfire smoke plumes from satellite imagery every day and publish them as open GIS shapefiles. The files live at a predictable,…</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/mapping-live-u-s-wildfire-smoke-in-r-with-sf-and-ggplot2/">Mapping Live U.S. Wildfire Smoke in R with sf and ggplot2</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://datascienceplus.com/mapping-live-u-s-wildfire-smoke-in-r-with-sf-and-ggplot2/"> R Programming – DataScience+</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>NOAA analysts trace wildfire smoke plumes from satellite imagery every day and publish them as open GIS shapefiles. The files live at a predictable, date-based URL, so you can pull the current day’s smoke map straight into R and plot it over the U.S. in about 30 lines. We use <code>sf</code> to read the spatial data and <code>ggplot2</code> to draw it.</p>
<h2 id="the-data-source">The data source</h2>
<p>The <a href="https://www.ospo.noaa.gov/products/land/hms.html" rel="nofollow" target="_blank">Hazard Mapping System (HMS)</a>, run by NOAA/NESDIS, is a daily analysis where operators trace smoke over North America from GOES satellite imagery. Each plume is a polygon with four attributes: the satellite, a start and end time, and a <strong>density</strong> class — <code>Light</code>, <code>Medium</code>, or <code>Heavy</code>. The daily shapefile is posted here:</p>
<pre>.../Smoke_Polygons/Shapefile/YYYY/MM/hms_smokeYYYYMMDD.zip
</pre>
<p>Because the filename is just the date, we can build the URL programmatically and always get the latest map. Note that HMS finalizes a given day’s analysis the following morning (Eastern time), so today’s file may not exist until then — the robust helper at the end handles that.</p>
<p><strong>Related posts on DataScience+:</strong></p><ul><li><a href="https://datascienceplus.com/building-heatmaps-in-r/" rel="nofollow" target="_blank">Building Heatmaps in R with ggplot2 package</a></li><li><a href="https://datascienceplus.com/visualising-thefts-using-heatmaps-in-ggplot2/" rel="nofollow" target="_blank">Visualising Thefts using Heatmaps in ggplot2</a></li><li><a href="https://datascienceplus.com/how-happy-is-your-country-visualized/" rel="nofollow" target="_blank">How Happy is Your Country? — Happy Planet Index Visualized</a></li></ul><h2 id="packages">Packages</h2>
<pre>library(sf)
library(dplyr)
library(ggplot2)
library(maps)
</pre>
<h2 id="get-the-data">Get the data</h2>
<p>We format the date into the URL, download and unzip the shapefile into a temp folder, and read it with <code>st_read()</code>. HMS names files by calendar date, so <code>Sys.Date()</code> gives us today’s map.</p>
<pre>day &lt;- Sys.Date()
ymd &lt;- format(day, &quot;%Y%m%d&quot;)
url &lt;- sprintf(
  &quot;https://satepsanone.nesdis.noaa.gov/pub/FIRE/web/HMS/Smoke_Polygons/Shapefile/%s/%s/hms_smoke%s.zip&quot;,
  format(day, &quot;%Y&quot;), format(day, &quot;%m&quot;), ymd)

zip &lt;- file.path(tempdir(), basename(url))
dir &lt;- file.path(tempdir(), paste0(&quot;hms_&quot;, ymd))
download.file(url, zip, mode = &quot;wb&quot;, quiet = TRUE)
unzip(zip, exdir = dir)

smoke &lt;- st_read(dir, quiet = TRUE)
</pre>
<h2 id="inspect-what-we-got">Inspect what we got</h2>
<p>Always look at the data before plotting it. <code>st_read()</code> returns an <code>sf</code> object — a data frame with a <code>geometry</code> column — so the usual tools work.</p>
<pre>smoke                    # note the CRS line: WGS 84 / EPSG:4326
## Simple feature collection with 98 features and 4 fields
## Geometry type: POLYGON
## Dimension:     XY
## Bounding box:  xmin: -144.505 ymin: 12.23946 xmax: -11.87108 ymax: 85.46261
## Geodetic CRS:  WGS 84
## First 10 features:
##    Satellite        Start          End Density                       geometry
## 1  GOES-WEST 2026198 1200 2026198 1500   Light POLYGON ((-71.21715 19.0450...
## 2  GOES-WEST 2026198 1200 2026198 1500   Light POLYGON ((-71.99762 18.4664...
## 3  GOES-WEST 2026198 1200 2026198 1500   Light POLYGON ((-71.50895 18.6244...
## 4  GOES-WEST 2026198 1200 2026198 1500   Light POLYGON ((-76.61889 20.6635...
## 5  GOES-WEST 2026198 1200 2026198 1500   Light POLYGON ((-77.00836 21.2569...
## 6  GOES-WEST 2026198 1200 2026198 1500   Light POLYGON ((-80.49727 26.2337...
## 7  GOES-WEST 2026198 1200 2026198 1500   Light POLYGON ((-80.88491 26.4339...
## 8  GOES-WEST 2026198 1200 2026198 1500   Light POLYGON ((-82.60996 32.8358...
## 9  GOES-WEST 2026198 1200 2026198 1500   Light POLYGON ((-123.1322 42.0559...
## 10 GOES-WEST 2026198 1200 2026198 1500   Light POLYGON ((-103.8145 37.1463...

table(smoke$Density)     # how many plumes of each density today
## 
##  Heavy  Light Medium 
##     35     29     34
</pre>
<p>Two things to notice. First, the CRS is already <strong>EPSG:4326</strong> (plain longitude/latitude), so no reprojection is needed. Second, <code>Density</code> takes three values — <code>Light</code>, <code>Medium</code>, <code>Heavy</code> — which is the variable we’ll color by. The <code>Start</code>/<code>End</code> fields use a <code>YYYYDDD HHMM</code> UTC format (day-of-year), but we won’t need them here.</p>
<h2 id="tidy-the-density-classes">Tidy the density classes</h2>
<p>We coerce <code>Density</code> to an ordered factor and <code>arrange()</code> on it so heavy plumes are drawn <em>last</em> (on top of lighter ones), and call <code>st_make_valid()</code> because hand-drawn polygons occasionally self-intersect and would otherwise break the crop.</p>
<pre>smoke &lt;- smoke %&gt;%
  filter(Density %in% c(&quot;Light&quot;, &quot;Medium&quot;, &quot;Heavy&quot;)) %&gt;%
  mutate(Density = factor(Density, levels = c(&quot;Light&quot;, &quot;Medium&quot;, &quot;Heavy&quot;))) %&gt;%
  st_make_valid() %&gt;%
  arrange(Density)
</pre>
<h2 id="map-it">Map it</h2>
<p>State outlines come from the <code>maps</code> package (pure CRAN, no API key). We crop the smoke to a lower-48 bounding box so the plot isn’t dominated by plumes over Canada and the oceans, then layer states underneath and smoke on top, colored by density.</p>
<pre>states   &lt;- st_as_sf(map(&quot;state&quot;, plot = FALSE, fill = TRUE))
bbox     &lt;- st_bbox(c(xmin = -125, xmax = -66, ymin = 24, ymax = 50), crs = 4326)
smoke_us &lt;- st_crop(smoke, bbox)

ggplot() +
  geom_sf(data = states, fill = &quot;grey97&quot;, color = &quot;grey80&quot;, linewidth = 0.2) +
  geom_sf(data = smoke_us, aes(fill = Density), color = NA, alpha = 0.6) +
  scale_fill_manual(values = c(Light = &quot;#FFD24D&quot;, Medium = &quot;#FB8C00&quot;, Heavy = &quot;#C62828&quot;)) +
  coord_sf(xlim = c(-125, -66), ylim = c(24, 50), expand = FALSE) +
  labs(
    title    = &quot;Wildfire smoke over the U.S.&quot;,
    subtitle = format(day, &quot;NOAA HMS smoke plumes, %B %d, %Y&quot;),
    fill     = &quot;Smoke density&quot;,
    caption  = &quot;Source: NOAA/NESDIS Hazard Mapping System (HMS)&quot;
  ) +
  theme_minimal(base_size = 13) +
  theme(axis.text = element_blank(), panel.grid = element_blank(),
        plot.title = element_text(face = &quot;bold&quot;))
</pre>
<figure class="code-plot"><img decoding="async" src="https://i1.wp.com/datascienceplus.com/wp-content/uploads/2026/07/map-1.png?w=578&#038;ssl=1" alt="plot of chunk map" data-recalc-dims="1" /></figure>
<h2 id="reading-the-map">Reading the map</h2>
<p>Today’s analysis has <strong>98 smoke plumes</strong> over North America, 35 of them classed as heavy, and 57 intersecting the lower 48. The map turns that table into geography: where the polygons stack up and darken, smoke is thicker, and the plumes trace the path the smoke has travelled from its source fires — often hundreds of miles downwind. Re-run the code on a different day and both the numbers and the picture change; that is the point of building the URL from <code>Sys.Date()</code>.</p>
<p>Because the counts and the map are generated from the same object, the paragraph above always describes the map you see — nothing is hard-coded.</p>
<h2 id="a-robust-download">A robust download</h2>
<p>Run this early in the morning and today’s file may not be posted yet. This helper walks back day by day until it finds one that exists, so the script never dies on a missing date:</p>
<pre>get_hms_smoke &lt;- function(day = Sys.Date(), max_back = 3) {
  for (d in seq(0, max_back)) {
    date &lt;- day - d
    ymd  &lt;- format(date, &quot;%Y%m%d&quot;)
    url  &lt;- sprintf(
      &quot;https://satepsanone.nesdis.noaa.gov/pub/FIRE/web/HMS/Smoke_Polygons/Shapefile/%s/%s/hms_smoke%s.zip&quot;,
      format(date, &quot;%Y&quot;), format(date, &quot;%m&quot;), ymd)
    zip &lt;- file.path(tempdir(), basename(url))
    ok  &lt;- tryCatch({ download.file(url, zip, mode = &quot;wb&quot;, quiet = TRUE); TRUE },
                    error = function(e) FALSE)
    if (ok &#038;&#038; file.exists(zip) &#038;&#038; file.size(zip) &gt; 0) {
      dir &lt;- file.path(tempdir(), paste0(&quot;hms_&quot;, ymd))
      unzip(zip, exdir = dir)
      message(&quot;Using HMS smoke for &quot;, date)
      return(st_read(dir, quiet = TRUE))
    }
  }
  stop(&quot;No HMS smoke file found in the last &quot;, max_back, &quot; days.&quot;)
}
</pre>
<h2 id="caveat-smoke-aloft-vs-smoke-you-breathe">Caveat: smoke aloft vs. smoke you breathe</h2>
<p>HMS is a <strong>satellite</strong> product — it maps smoke seen from above, at any altitude. A thick plume on the map can sit five kilometers up and leave ground-level air clear, so HMS is a measure of smoke <em>transport</em>, not of what people are breathing. For surface air quality, pair it with ground PM2.5 from the EPA/USFS <a href="https://fire.airnow.gov/" rel="nofollow" target="_blank">AirNow Fire and Smoke Map</a>, which also has an API — a natural follow-up analysis.</p>
<p>That’s all. You now have a script that pulls a hand-analyzed satellite product and turns it into a national map, and re-runs itself for any day you like.</p>
<hr><p><em>This article was first published on <a href="https://datascienceplus.com/mapping-live-u-s-wildfire-smoke-in-r-with-sf-and-ggplot2/" rel="nofollow" target="_blank">DataScience+</a>, a community of R and Python tutorial authors. Have a data-science technique worth sharing? <a href="https://datascienceplus.com/write-for-us/" rel="nofollow" target="_blank">Write for us</a> — no pitch required.</em></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://datascienceplus.com/mapping-live-u-s-wildfire-smoke-in-r-with-sf-and-ggplot2/"> R Programming – DataScience+</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/mapping-live-u-s-wildfire-smoke-in-r-with-sf-and-ggplot2/">Mapping Live U.S. Wildfire Smoke in R with sf and ggplot2</a>]]></content:encoded>
					
		
		<enclosure url="" length="0" type="" />

		<post-id xmlns="com-wordpress:feed-additions:1">402776</post-id>	</item>
		<item>
		<title>Five pre-flight checks for your dashboard</title>
		<link>https://www.r-bloggers.com/2026/07/five-pre-flight-checks-for-your-dashboard/</link>
		
		<dc:creator><![CDATA[The Jumping Rivers Blog]]></dc:creator>
		<pubDate>Thu, 16 Jul 2026 23:59:00 +0000</pubDate>
				<category><![CDATA[R bloggers]]></category>
		<guid isPermaLink="false">https://www.jumpingrivers.com/blog/five-preflight-checks-dashboard/</guid>

					<description><![CDATA[<div style = "width:60%; display: inline-block; float:left; ">
<p>So you’ve built your data pipeline, you’ve designed your dashboard and you’ve connected the two through a real app. The screenshots match the designs and you can show it off and wow the stakeholders. Ready to launch, right? Well, maybe. In this post we’ll cover five ...</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/five-pre-flight-checks-for-your-dashboard/">Five pre-flight checks for your dashboard</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/five-preflight-checks-dashboard/"> 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/five-preflight-checks-dashboard/">
<img src="https://www.jumpingrivers.com/blog/five-preflight-checks-dashboard/" width="400" style="width:400px" class="image-center" style="display: block; margin: auto;" />
</a>
</p>
<style>
.blog-content :is(img, video) {
display: block;
width: 100%;
max-width: 100%
}
.blog-content ol li {
margin-bottom: 0;
}
figure {
margin-inline: auto;
display: flex;
flex-direction: column-reverse;
align-items: start;
row-gap: 0.3rem;
}
.w300 {
width: 300px;
max-width: 100%;
}
.w450 {
width: 450px;
max-width: 100%;
}
.w600 {
width: 600px;
max-width: 100%;
}
[id="modals-initial"] {
display: flex;
justify-content: center;
align-items: center;
column-gap: 2rem;
row-gap: 1rem;
flex-wrap: wrap;
}
aside:not(.advert) {
background-color: #222;
color: var(--off-white);
padding: 1rem;
border-radius: 0.5rem;
}
kbd {
font-family: 'Space Mono', monospace;
font-size: 0.85em;
padding: 0.15em 0.5em;
border-radius: 4px;
background-color: var(--off-white);
color: var(--dark-blue);
border: 1px solid var(--light-brown);
box-shadow: 0 1px 0 1px var(--light-brown);
white-space: nowrap;
}
</style>
<p>So you’ve built your data pipeline, you’ve designed your dashboard and you’ve connected the two through a real app. The screenshots match the designs and you can show it off and wow the stakeholders. Ready to launch, right? Well, maybe. In this post we’ll cover five things that are easy to overlook: some worth a quick check, some you might not have thought to add.</p>
<aside class="advert">
<p>Our Front-end Dashboard Health Check puts your app through a rigorous 19-point usability review. <a href="https://www.jumpingrivers.com/contact" data-subject="Dashboard Health Check" rel="nofollow" target="_blank">Contact us</a> to find out more.</p>
</aside>
<h2 id="sample-dashboard">Sample Dashboard</h2>
<p>Before we dive into those five things, however, I’ll introduce the <a href="https://www.jumpingrivers.com/misc/nyc-departures-dashboard-base/" rel="nofollow" target="_blank">sample dashboard</a>. It uses data from the <a href="https://nycflights13.tidyverse.org/" rel="nofollow" target="_blank"><code>{nycflights13}</code></a> R package developed by Hadley Wickham but is otherwise built entirely without R. Instead it’s built using standard frontend web technologies: HTML, CSS and JavaScript, with data coming from a single monolithic gzipped JSON file. The JavaScript then adds some noise to the data, so it looks more like live data (and so the dashboard doesn’t appear blessed with 20/20 foresight).</p>
<aside>This is the same dataset as used in our <a href="https://www.jumpingrivers.com/misc/jfk-departures" rel="nofollow" target="_blank">John F. Kennedy Airport Departures Board</a> app. There we focused on design aesthetics. Here our focus is more on usability and accessibility checks.</aside>
<p>The actual visual presentation is that of online departure boards for the three New York/New Jersey airports — John F. Kennedy Intl, La Guardia and Newark Liberty Intl — along with some weather information and some assumed KPIs.</p>
<figure class="w600">
<figcaption>Screenshot of the top of the dashboard for the afternoon of Wednesday July the 3rd, 2013.</figcaption>
<img src="https://www.jumpingrivers.com/blog/five-preflight-checks-dashboard/assets/main-view.webp" alt="The screenshot shows the three airports the user can choose between with weather info, and, for the selected airport, three KPIs and flight data for the current chosen time. The time itself is displayed at the very top of the dashboard.">
</figure>
<p>Each table row and each KPI card is clickable, bringing up a modal with more detailed information. Please note that, spoiler alert, the dashboard does not (yet) function well on mobile. We will get to that shortly.</p>
<div id="modals-initial">
<figure class="w300">
<figcaption>Modal window for the On-time departures KPI.</figcaption>
<img src="https://www.jumpingrivers.com/blog/five-preflight-checks-dashboard/assets/kpi-modal.webp" alt="The modal shows a line graph of on-time departures over the previous 24 hours and some key statistics">
</figure>
<figure class="w300">
<figcaption>Modal window for a flight.</figcaption>
<img src="https://www.jumpingrivers.com/blog/five-preflight-checks-dashboard/assets/flight-modal.webp" alt="The modal shows detailed information about a particular (delayed) JetBlue flight from JFK to BOS.">
</figure>
</div>
<p>Full disclosure: for rapid prototyping, the dashboard was built through an extended prompting session with Claude Code. Most of the issues I’ll cover are genuine problems that came up in the session, but in one case I did ask Claude to leave out a feature it clearly wanted to add, purely for illustrative purposes. This example, in the state it’s in, is meant to represent a dashboard that an intelligence — human, artificial or Martian — might reasonably judge ready to ship. The rest of this post exposes some remaining flaws.</p>
<h2 id="five-things-to-check">Five Things to Check</h2>
<h3 id="does-the-design-work-at-different-screen-dimensions">Does the design work at different screen dimensions?</h3>
<p>This is the easiest one to check and, perhaps, the most important. While dashboards are still primarily <em>built</em> on desktop machines, making them <em>viewable</em> on tablets and mobile phones should be a part of most development plans. Many, probably most (data are inconsistent and highly topic- and region-dependent), humans use mobile devices to consume content on the World Wide Web, and you should have a very good reason for excluding them from your dashboard. It’s not just improvements in mobile hardware pushing people that way; the expansion of fifth-generation mobile network technology (5G) can make the experience much nicer than it used to be, especially when the consumers themselves are mobile.</p>
<p>This screenshot of our sample dashboard quickly highlights a big problem with it: it is literally impossible to bring up the data for La Guardia airport because its “button” (it’s not really a button, which is another issue we’ll come on to later) is off the right side of the page, with no possibility of scrolling to it.</p>
<figure class="w300">
<figcaption>Screenshot of the base sample dashboard from my mobile device.</figcaption>
<img src="https://www.jumpingrivers.com/blog/five-preflight-checks-dashboard/assets/mobile-layout-1.webp" alt="The 'button' for JFK disappears off the right edge while the 'button' for LGA is entirely hidden.">
</figure>
<p>Less critical, but still worth fixing, is the two-way scrolling of the table. This is avoidable by stacking table columns on narrow screens. Both of these fixes are shown in the next screenshot. (The content is much taller now so we show the full page, not just the visible part. On my phone, for example, the top of the table can just be seen without scrolling.)</p>
<figure class="w300">
<figcaption>Screenshot from my phone of a more mobile-friendly layout.</figcaption>
<img src="https://www.jumpingrivers.com/blog/five-preflight-checks-dashboard/assets/mobile-layout-2.webp" alt="Airport 'buttons' are stacked vertically and the contents of table rows are arranged in two-dimensional grid rather than purely horizontally">
</figure>
<p>There’s actually a problem with the layout in both dimensions: on a shorter screen — perhaps a small browser window on a cramped notebook — the table can become unreachable. The problem here is that, in designing for (larger) desktop browsers, the design assumed a minimum browser height and then scrolling <em>only</em> on the table and not on the browser window itself. This works well when the browser window <em>is</em> tall enough, since you get fixed information at the top with no nested scrolling. But when this (arbitrary) minimum height condition isn’t met, the design fails. So that’s another thing that should be fixed prior to launch.</p>
<h3 id="does-the-app-support-touchscreens">Does the app support touchscreens?</h3>
<p>Supporting mobiles and tablets isn’t just about layout. Interactions need to work when the input comes from a finger or stylus rather than a mouse and keyboard. There are actually two things to consider here:</p>
<ol>
<li>Can all interactions be done through touch?</li>
<li>Is it obvious what interactions are actually possible?</li>
</ol>
<p>The base app allows the user to “change time” through a dialog that only opens when pressing the <kbd>T</kbd> key. This, obviously, fails 1). We can fix it by making the clock itself into a tappable object that brings up the same dialog as pressing the T key (this also gives the user access to the pause option that was previously only possible by pressing the <kbd>P</kbd> key). This brings us neatly on to 2): it’s not inherently obvious that the clock is tappable. Nor is it obvious that the cards and rows can be tapped for detailed information. With a mouse at least, these change colour (slightly) when hovered over. We need something more: we can go with a common icon and some explanatory text.</p>
<figure class="w300">
<figcaption>Clickable/tappable indicators added to the design.</figcaption>
<img src="https://www.jumpingrivers.com/blog/five-preflight-checks-dashboard/assets/touchscreen.webp" alt="The indicators are opposing arrows pointing up and to the right and down and to the left. Several indicators are ringed in red, as is the explanatory text.">
</figure>
<h3 id="is-the-app-accessible">Is the app accessible?</h3>
<p>Beyond use on mobile, there are a number of additional accessibility issues with the base version of the app. At least three of these relate to keyboard usage:</p>
<ol>
<li>Button-like interactive elements are not HTML <code>button</code> elements and therefore don’t have appropriate interactions and semantics to meet WCAG requirements;</li>
<li>Not everything that can be clicked/tapped can be interacted with by a keyboard user;</li>
<li>The modal that appears when selecting interactive elements does not implement focus trapping, meaning a keyboard user can lose focus somewhere in the background behind the modal window.</li>
</ol>
<p>We can fix all these issues with better use of HTML elements: <code>buttons</code> for airport selection, KPI-modal launch, and flight modal launch, and the <code>dialog</code> element for the modal windows. On top of this, some text in the base app does not meet colour-contrast requirements, so we also want to fix this.</p>
<figure class="w450">
<figcaption>An example of using the <kbd>Tab</kbd> and <kbd>Enter</kbd> keys to move between interactive elements and open modals.</figcaption>
<video src="assets/keyboard-sequence-web.mp4" controls loop>
</figure>
<p>The keyboard focus indicator uses the yellow accent colour found elsewhere in the app. In hindsight this was probably a mistake. A different colour focus indicator would make it clearer what had keyboard focus as opposed to what had actually been selected (i.e. which airport was currently being shown).</p>
<h3 id="is-the-app-performant">Is the app performant?</h3>
<p>The app is meant to simulate real data but allows the user to select, pause and speed up time. Consequently, the data isn’t passed around in the format it would be if it were a <em>real</em> app tracking <em>live</em> events. But we can still try to optimise how we pass around data in our simulated-data app. The biggest win we found here was converting the data from row-based to column-based. This reduced the size of the data (gzipped) by a third, from 4.8 MB to 3.2 MB, and JSON parsing times from ~550 ms to ~250 ms.</p>
<p>It is, of course, important not to waste time and resources on premature and unnecessary optimisations. So consider the data change above as an example of where one might want to look rather than a change that was strictly necessary.</p>
<p>Another place to look is at the size of images. For dashboards that often means data visualisation. Large, frequently changing raster images sent from the server can lead to performance hits. This is what you get, by default, in Shiny apps when you use <code>renderPlot()/plotOutput()</code>. Packages that render SVG or HTML <code>canvas</code> directly in the browser can greatly reduce the overhead.</p>
<h3 id="does-the-app-feel-like-it-responds-immediately-to-interaction">Does the app feel like it responds immediately to interaction?</h3>
<p>Actual performance is one thing, but perceived performance can also be significant. If a user clicks on a button and nothing happens for a second or two, things “feel” broken even if, in reality, the browser is just processing things silently in the background. In our particular case, there is a simulated delay of ~2 seconds when changing airport. Click or tap on an airport and nothing happens. (Disclosure: this is where I actually had to force Claude not to put something in in order to make my point.) There are a number of options here for how to deal with this. The simplest might be to set the cursor to a value of “wait” in CSS, but this would obviously not help users of touchscreen devices that lack a cursor. A better alternative is to show a loading indicator to everyone. These typically rotate, so we could use an animated GIF or a static image file and CSS animations.</p>
<figure class="w450">
<figcaption>A short video showing the effect of clicking on an airport button first without and then with a loading indicator. In both cases a warping effect around the cursor can be seen. This is <strong>not</strong> visible when using the app but added to the screen recording to show the point at which the click occurred.</figcaption>
<video src="assets/click-sequence-web.mp4" controls loop>
</figure>
<p>For longer waits, a progress indicator would be a better option if it were possible to actually estimate progress. This would ensure it didn’t look like the page had got stuck. For a wait of a second or two, this is not necessary; the requirement is only that the user sees that their action of clicking on an airport had an effect immediately.</p>
<h2 id="summary">Summary</h2>
<p>You can see all the fixes discussed in this post (and some more we had to skip over for brevity) in the <a href="https://www.jumpingrivers.com/misc/nyc-departures-dashboard-final/" rel="nofollow" target="_blank">final version of the dashboard</a>. Hopefully this article has illustrated that there can be quite a few issues with a newly designed dashboard that may be subtle or hidden, particularly if you’re only testing with a mouse on a desktop computer. The goal here wasn’t to scare you away from publishing entirely, so hopefully I haven’t done that, but to highlight that the devices via which a dashboard is developed and consumed are often quite different: remember to design for the latter. Similarly, just because you know something works and will load eventually does not mean you can expect your users to be as patient and forgiving.</p>
<p>
For updates and revisions to this article, see the <a href = "https://www.jumpingrivers.com/blog/five-preflight-checks-dashboard/">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/five-preflight-checks-dashboard/"> 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/07/five-pre-flight-checks-for-your-dashboard/">Five pre-flight checks for your dashboard</a>]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">402638</post-id>	</item>
		<item>
		<title>How much have prices increased?</title>
		<link>https://www.r-bloggers.com/2026/07/how-much-have-prices-increased/</link>
		
		<dc:creator><![CDATA[Jerry Tuttle]]></dc:creator>
		<pubDate>Thu, 16 Jul 2026 14:36:40 +0000</pubDate>
				<category><![CDATA[R bloggers]]></category>
		<guid isPermaLink="false">http://www.r-bloggers.com/?guid=164fa803c3223bc52089bf98286aae95</guid>

					<description><![CDATA[<div style = "width:60%; display: inline-block; float:left; ">
<p>     <br />
  The Consumer Price Index (CPI) is a widely used measure of the prices of goods and services purchased by households. It’s the primary tool for tracking inflation and changes in the cost of living over time. The index is built from monthly price collections on a “basket” of goods ...</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/how-much-have-prices-increased/">How much have prices increased?</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/how-much-have-prices-increased.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://i2.wp.com/blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjEziUjeAEzIW7-s5J-5KrZfpqCYQwP_LJK-6dtmKC72Yk-Ew_eqbjYlgycuK8ENpVpdjXJYSVmxwDG_YvqfxJwEH1LPl5d8lbJZb_ig551G6C2bkPxyB31mpEaiPJrqzjRZDwQg65nnQw2UyBXCkrPOM1gcK74NmNWgTgzvF8KQYBYbKmMBqgPx-ODVLg/s320/rent_bill.png?ssl=1" style="display: block; padding: 1em 0; text-align: center; " rel="nofollow" target="_blank"><img alt="" border="0" data-original-height="1536" data-original-width="450" src="https://i2.wp.com/blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjEziUjeAEzIW7-s5J-5KrZfpqCYQwP_LJK-6dtmKC72Yk-Ew_eqbjYlgycuK8ENpVpdjXJYSVmxwDG_YvqfxJwEH1LPl5d8lbJZb_ig551G6C2bkPxyB31mpEaiPJrqzjRZDwQg65nnQw2UyBXCkrPOM1gcK74NmNWgTgzvF8KQYBYbKmMBqgPx-ODVLg/s320/rent_bill.png?resize=450%2C1536&#038;ssl=1" data-recalc-dims="1"/></a></div>
  
     
  The Consumer Price Index (CPI) is a widely used measure of the prices of goods and services purchased by households. It’s the primary tool for tracking inflation and changes in the cost of living over time. The index is built from monthly price collections on a “basket” of goods and services from a sample of retail and service establishments. Historical CPI data is easy to download<p>
  
    &#038;nbsp 
  A key feature of the CPI is that prices are adjusted for quality changes. If the price of a car’s side mirror rises by $200, but $120 of that increase reflects the mirror becoming “smart” rather than “dumb,” only the remaining $80 is counted as inflation. Similarly, if the price of a medical procedure rises because new equipment improves the quality of care, the portion attributable to improved quality is removed from the inflation calculation. Consumers still pay for these quality improvements, whether they want them or not, so in many cases the CPI understates pure cost increases.<p>
  
    &#038;nbsp
  There are eight major categories of the CPI, and each category has its own index:  
Food &#038; Beverages, Housing, Apparel, Transportation,	Medical Care, Recreation, Education &#038; Communication, and
Other.  These are weighted to form the overall CPI, with the largest weights as Housing at about 44% of the total, Transportation at 17%, Food &#038; Beverages at 14%, and Medical Care at 8%. (Each of these is further sub-divided into its own index; for example, Other includes Personal Care, and Personal Care has seprate indices for Cosmetics, Perfume, Bath, and Nail Preparations.)  Of course the weights will not reflect your percentages of what you buy. <p>
  
    &#038;nbsp
    Downloading historical CPI data from FRED (Federal Reserve Bank of St. Louis) was easier than I expected.  You need an API key which you can get from https://fredaccount.stlouisfed.org/login <p>
  
    &#038;nbsp
    Here is a line graph showing cumulative CPI growth for the overall CPI and each of the eight major categories through June 2026, indexed to December 2016 = 1.00. The overall CPI has risen 37.1% since December 2016. 
  Housing (rent, insurance, energy, etc.) has increased the most at 44.8%. Transportation (vehicle purchases, fuel, maintenance, insurance, public transit fares) is next at 43.5%. Food (groceries and restaurants) is up 39.9%. Medical Care is lower at 25.9%. Medical Care includes out‑of‑pocket spending on providers, hospitals, and insurance, but excludes employer‑paid and government‑paid health insurance premiums. <p>
  
  
  
<div class="separator" style="clear: both;"><a href="https://i0.wp.com/blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh13qOPReWiaIdZB0-xT2t7Y9SKfLwGQpy6pHZySDh3p6BLC41r7jnRXrGDHK2NlfVlpO9iDFdZFN0PLfBY8y0QZKVL6FnPCv-sswtuZnIJp1OR_epstAYZ_Vyw6AqD5s_JfIUiSbbNLe2oFok6FCgHUbRfjF7KmxXH_Rw3PP3Q_1CuR5QlQieIaxLJsAk/s1752/cpi_growth.jpg?ssl=1" style="display: block; padding: 1em 0; text-align: center; " rel="nofollow" target="_blank"><img alt="" border="0" width="450" data-original-height="928" data-original-width="450" src="https://i2.wp.com/blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh13qOPReWiaIdZB0-xT2t7Y9SKfLwGQpy6pHZySDh3p6BLC41r7jnRXrGDHK2NlfVlpO9iDFdZFN0PLfBY8y0QZKVL6FnPCv-sswtuZnIJp1OR_epstAYZ_Vyw6AqD5s_JfIUiSbbNLe2oFok6FCgHUbRfjF7KmxXH_Rw3PP3Q_1CuR5QlQieIaxLJsAk/s600/cpi_growth.jpg?resize=450%2C928&#038;ssl=1" data-recalc-dims="1"/></a></div><p>

     
   The CPIs exclude a lot of things like the quality changes I mentioned above, and other items that you may pay but that the government does not classify as personal expenses.  We all feel the cost of our groceries going up &#8211; I discussed this previously in <a href="https://onlinecollegemathteacher.blogspot.com/2026/01/do-prices-feel-like-they-are-rising.html" rel="nofollow" target="_blank">groceries</a> .  Each category has its own reasons why it is increasing;  I will leave that discussion to the economists, except to say that the cost of energy affects a lot of items in the cost of production and delivery. <p>

      
  Like many broad measures, the CPI is an attempt to estimate the overall cost of goods and services. But what ultimately matters to you is the actual cost of the things <b>you</b> buy. <p>
  
      
  Here is my R code:<p>
  
<pre>

library(tidyquant)
library(dplyr)
library(tidyr)
library(lubridate)
library(ggplot2)
library(ggrepel)   # repel overlapping text labels

# Set your API environment variable
Sys.setenv(FRED_API_KEY = &quot;xxxx&quot;)


# Define the official FRED database tracking codes
cpi_series &lt;- c(
  &quot;CPIAUCSL&quot;, &quot;CPIFABSL&quot;, &quot;CPIHOSSL&quot;, &quot;CPIAPPSL&quot;, 
  &quot;CPITRNSL&quot;, &quot;CPIMEDSL&quot;, &quot;CPIRECNS&quot;, &quot;CPIEDUNS&quot;, &quot;CPIOGSNS&quot;
)

# Download and clean data vectors
raw_data &lt;- tq_get(cpi_series, get = &quot;economic.data&quot;)   # get from FRED

# 2. Clean, Filter, and Perform Group-Indexing
cpi_processed &lt;- raw_data %&gt;%
  mutate(
    Year  = year(date),
    Month = month(date)
  ) %&gt;%
  # Keep all Decembers from 2015 onward OR strictly isolate June 2026
  filter((Month == 12 & Year &gt;= 2015) | (Year == 2026 & Month == 6)) %&gt;%
  # Convert raw tracking codes into readable titles
  mutate(Category = case_when(
    symbol == &quot;CPIAUCSL&quot; ~ &quot;Overall CPI&quot;,
    symbol == &quot;CPIFABSL&quot; ~ &quot;1. Food & Bev&quot;,
    symbol == &quot;CPIHOSSL&quot; ~ &quot;2. Housing&quot;,
    symbol == &quot;CPIAPPSL&quot; ~ &quot;3. Apparel&quot;,
    symbol == &quot;CPITRNSL&quot; ~ &quot;4. Transportation&quot;,
    symbol == &quot;CPIMEDSL&quot; ~ &quot;5. Medical Care&quot;,
    symbol == &quot;CPIRECNS&quot; ~ &quot;6. Recreation&quot;,
    symbol == &quot;CPIEDUNS&quot; ~ &quot;7. Education & Comm&quot;,
    symbol == &quot;CPIOGSNS&quot; ~ &quot;8. Other Goods&quot;
  )) %&gt;%
  # Chronologically sort each group, then anchor base-100 to the first row (Dec 2015)
  group_by(Category) %&gt;%
  arrange(date, .by_group = TRUE) %&gt;%
  mutate(Indexed_Value = (price / first(price)) * 100) %&gt;% 
  ungroup() %&gt;%
  # Convert Timeline to ordered categories for a clean discrete X-Axis
  mutate(Period = if_else(Month == 6, paste0(Year, &quot; (June)&quot;), as.character(Year))) %&gt;%
  mutate(Period = factor(Period, levels = unique(Period[order(date)])))

# 3. Isolate final data point rows for the text tags
label_data &lt;- cpi_processed %&gt;%
  group_by(Category) %&gt;%
  filter(date == max(date)) %&gt;%
  ungroup()

# 4. Generate the Chart with the Categorical String Axis Baseline
ggplot(cpi_processed, aes(x = Period, y = Indexed_Value, color = Category, group = Category)) +
  geom_line(aes(linewidth = ifelse(Category == &quot;Overall CPI&quot;, 1.5, 0.8))) +
  geom_point(size = 2) +
  
  # Non-overlapping direct text labels
  geom_text_repel(
    data = label_data,
    aes(label = paste0(Category, &quot; (&quot;, round(Indexed_Value, 1), &quot;)&quot;)),
    nudge_x = 0.5,             
    direction = &quot;y&quot;,          
    hjust = 0,                
    segment.color = &quot;grey50&quot;, 
    segment.size = 0.4,
    force = 2,
    fontface = &quot;bold&quot;,
    size = 4   # millimters
  ) +
  
  # High-contrast visual color mapping matrix
  scale_color_manual(values = c(
    &quot;Overall CPI&quot;         = &quot;#000000&quot;, 
    &quot;1. Food & Bev&quot;       = &quot;#E64B35&quot;, 
    &quot;2. Housing&quot;          = &quot;#56B4E9&quot;, 
    &quot;3. Apparel&quot;          = &quot;#009E73&quot;, 
    &quot;4. Transportation&quot;   = &quot;#4D8805&quot;, 
    &quot;5. Medical Care&quot;     = &quot;#0072B2&quot;, 
    &quot;6. Recreation&quot;       = &quot;#D55E00&quot;, 
    &quot;7. Education & Comm&quot; = &quot;#CC79A7&quot;, 
    &quot;8. Other Goods&quot;      = &quot;#999999&quot;  
  )) +
  
  # Format plot margins to prevent label cropping
  scale_x_discrete(expand = expansion(mult = c(0.05, 0.35))) +
  scale_linewidth_identity() + 
  labs(
    title = &quot;10.5-Year Cumulative CPI Growth Comparison&quot;,
    subtitle = &quot;Base Index: December 2016 = 100&quot;,
    x = &quot;Reporting Period&quot;,
    y = &quot;Indexed Value (Relative to 100)&quot;
  ) +
  theme_minimal(base_size = 12) +
  theme(
    legend.position = &quot;none&quot;,          
    panel.grid.minor = element_blank(),
    text = element_text(face = &quot;bold&quot;),
    plot.title = element_text(face = &quot;bold&quot;, size = 14),
    axis.text = element_text(face = &quot;bold&quot;)
  )

# 5. Save the final graphic output file
# ggsave(&quot;cpi_growth_comparison.png&quot;, width = 12, height = 7, dpi = 300, bg = &quot;white&quot;)

# Extract and print the final 10.5-year cumulative values
final_column_summary &lt;- cpi_processed %&gt;%
  filter(date == max(date)) %&gt;%
  select(Category, Indexed_Value) %&gt;%
  mutate(Indexed_Value = round(Indexed_Value, 2)) %&gt;%
  arrange(desc(Indexed_Value)) # Sorts from highest inflation to lowest

print(as.data.frame(final_column_summary))


</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/how-much-have-prices-increased.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/how-much-have-prices-increased/">How much have prices increased?</a>]]></content:encoded>
					
		
		<enclosure url="" length="0" type="" />

		<post-id xmlns="com-wordpress:feed-additions:1">402651</post-id>	</item>
		<item>
		<title>Repost: Automatically compile Quarto reports when new data lands</title>
		<link>https://www.r-bloggers.com/2026/07/repost-automatically-compile-quarto-reports-when-new-data-lands/</link>
		
		<dc:creator><![CDATA[Stephen Turner]]></dc:creator>
		<pubDate>Wed, 15 Jul 2026 10:15:43 +0000</pubDate>
				<category><![CDATA[R bloggers]]></category>
		<guid isPermaLink="false">http://www.r-bloggers.com/?guid=a9754bddb3935d4cf61ec1274c9d178a</guid>

					<description><![CDATA[<div style = "width:60%; display: inline-block; float:left; "> Reposted from the original at https://blog.stephenturner.us/p/turn-new-data-into-quarto-reports-automaticallyThe {watcher} R package monitors your filesystem and run arbitrary code when files change. You can use this to automate things like creating pa...</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/repost-automatically-compile-quarto-reports-when-new-data-lands/">Repost: Automatically compile Quarto reports when new data lands</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://gettinggeneticsdone.blogspot.com/2026/07/turn-new-data-into-quarto-reports-automatically.html"> Getting Genetics Done</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><b style="background-color: #fcff01;"><span style="font-size: large;">Reposted from the original at <a href="https://blog.stephenturner.us/p/turn-new-data-into-quarto-reports-automatically" rel="nofollow" target="_blank">https://blog.stephenturner.us/p/turn-new-data-into-quarto-reports-automatically</a></span></b></p><p><i>The {watcher} R package monitors your filesystem and run arbitrary code when files change. You can use this to automate things like creating parameterized Quarto reports.</i> </p><p>&#8212;</p><p><span>The </span><strong>watcher</strong><span> R package (</span><a href="https://watcher.r-lib.org/" rel="nofollow" target="_blank">watcher.r-lib.org</a><span>) monitors your filesystem for changes, and can run code automatically when data is created or updated.</span></p><p>A helpful use case for this is to monitor a folder for changes, then render a Quarto report for whatever new data arrived.</p><p>Simple example here starting with an empty data directory and a Quarto template.</p><pre>$ tree
.
├── data
└── report.qmd</pre><p><span>This is a parameterized Quarto template that uses Typst to compile a simple PDF report showing a </span><code>summary()</code><span> of a CSV you read in.</span></p><pre>---
title: &quot;Automatically compiled report&quot;
author: &quot;Stephen Turner&quot;
subtitle: &quot;File: `r basename(params$csv_path)`&quot;
date: today
format: typst
params:
    csv_path: NA
---

Compiled `r format(Sys.time(), &quot;%Y-%m-%d %H:%M:%S %Z&quot;)` from `r params$csv_path`.

```{r}

```

```{r}
df &lt;- read.csv(params$csv_path)
summary(df)
```
</pre><p><span>Now let’s set up the watcher. The watcher monitors a directory for new files, then runs </span><code>quarto_render</code><span> passing in the new file as a parameter.</span><span data-state="closed" style="min-width: 0px;"><a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" href="https://blog.stephenturner.us/p/turn-new-data-into-quarto-reports-automatically#footnote-1" id="footnote-anchor-1" rel="nofollow" target="_blank">1</a></span></p><pre>library(watcher)

render &lt;- function(paths) {
  message(format(Sys.time()), &quot;: &quot;, length(paths), &quot; file(s) changed&quot;)
  message(paths)
  quarto::quarto_render(
    &quot;report.qmd&quot;,
    output_file = basename(paths),
    execute_params = list(csv_path = paths),
    quiet = TRUE
  )
}

w &lt;- watcher(path = &quot;data&quot;, callback = render, latency = 1)
w$start()</pre><p><span>Now whenever new files land in </span><code>data/</code><span> the watcher will automatically render the parameterized Quarto document, which just prints a summary of the data. The </span><code>w$start()</code><span> doesn’t tie up my R console. It’s running in the background.</span></p><p>Now, when I create new CSV files in the data directory, the watcher finds these and renders the reports.</p><pre>&gt; iris |&gt; write.csv(&quot;data/iris.csv&quot;)
2026-07-15 05:45:28: 1 file(s) changed
/Users/sdt5z/Downloads/watcher-test/data/iris.csv

&gt; penguins |&gt; write.csv(&quot;data/penguins.csv&quot;)
2026-07-15 05:45:33: 1 file(s) changed
/Users/sdt5z/Downloads/watcher-test/data/penguins.csv</pre><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img can-restack" data-component-name="Image2ToDOM" href="https://substackcdn.com/image/fetch/$s_!P5re!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc6da06f4-048a-449e-be1b-5b0287567060_3918x2497.png" rel="nofollow" target="_blank"><div class="image2-inset"><picture><source type="image/webp"></source><img loading="lazy" alt="" class="sizing-normal" data-attrs="{"src":"https://substack-post-media.s3.amazonaws.com/public/images/c6da06f4-048a-449e-be1b-5b0287567060_3918x2497.png","srcNoWatermark":null,"fullscreen":null,"imageSize":null,"height":928,"width":1456,"resizeWidth":null,"bytes":1062087,"alt":null,"title":null,"type":"image/png","href":null,"belowTheFold":true,"topImage":false,"internalRedirect":"https://blog.stephenturner.us/i/207133840?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc6da06f4-048a-449e-be1b-5b0287567060_3918x2497.png","isProcessing":false,"align":null,"offset":false}" height="408" src="https://i1.wp.com/substackcdn.com/image/fetch/$s_!P5re!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc6da06f4-048a-449e-be1b-5b0287567060_3918x2497.png?resize=450%2C408&#038;ssl=1" width="450" data-recalc-dims="1" /></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"></div></div></div></a></figure></div><p>With
 this you could start the watcher in a background R process (e.g., 
running under tmux or something), monitoring a shared drive or some 
cloud location. Whenever new data arrives, a report gets compiled 
without you having to do anything.</p><p>More on the watcher package:</p><ul><li><p><span>Posit blog: </span><a href="https://opensource.posit.co/blog/2026-06-29_watcher-0-2-0/" rel="nofollow" target="_blank">https://opensource.posit.co/blog/2026-06-29_watcher-0-2-0/</a></p></li><li><p><span>watcher docs: </span><a href="https://watcher.r-lib.org/" rel="nofollow" target="_blank">https://watcher.r-lib.org/</a></p></li></ul><p> </p><div class="blogger-post-footer">Getting Genetics Done by Stephen Turner is licensed under a Creative Commons Attribution (CC BY) License.</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="http://gettinggeneticsdone.blogspot.com/2026/07/turn-new-data-into-quarto-reports-automatically.html"> Getting Genetics Done</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/repost-automatically-compile-quarto-reports-when-new-data-lands/">Repost: Automatically compile Quarto reports when new data lands</a>]]></content:encoded>
					
		
		<enclosure url="" length="0" type="" />

		<post-id xmlns="com-wordpress:feed-additions:1">402621</post-id>	</item>
		<item>
		<title>Eruption: announcing new R package VolcanoPlotR</title>
		<link>https://www.r-bloggers.com/2026/07/eruption-announcing-new-r-package-volcanoplotr/</link>
		
		<dc:creator><![CDATA[Stephen Royle]]></dc:creator>
		<pubDate>Wed, 15 Jul 2026 09:01:03 +0000</pubDate>
				<category><![CDATA[R bloggers]]></category>
		<guid isPermaLink="false">https://quantixed.org/?p=3798</guid>

					<description><![CDATA[<div style = "width:60%; display: inline-block; float:left; "> This is a short post to announce the release of an R package, VolcanoPlotR. Background Using proteomics, we often want to compare two experimental groups. A popular way to visualise this comparison this is via a volcano plot, where the enrichment of proteins in one condition is towards the right ...</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/eruption-announcing-new-r-package-volcanoplotr/">Eruption: announcing new R package VolcanoPlotR</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/15/eruption-announcing-new-r-package-volcanoplotr/"> 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">This is a short post to announce the release of an R package, VolcanoPlotR.</p>



<ul class="wp-block-list">
<li><a href="https://github.com/quantixed/VolcanoPlotR" rel="nofollow" target="_blank">Code</a></li>



<li><a href="https://quantixed.github.io/VolcanoPlotR/" rel="nofollow" target="_blank">Documentation</a></li>
</ul>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="192" height="192" src="https://i0.wp.com/quantixed.org/wp-content/uploads/2026/07/web-app-manifest-192x192-1.png?resize=192%2C192&#038;ssl=1" alt="" class="wp-image-3808" srcset_temp="https://i0.wp.com/quantixed.org/wp-content/uploads/2026/07/web-app-manifest-192x192-1.png?resize=192%2C192&#038;ssl=1 192w, https://quantixed.org/wp-content/uploads/2026/07/web-app-manifest-192x192-1-150x150.png 150w" sizes="(max-width: 192px) 100vw, 192px" data-recalc-dims="1" /></figure>



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



<p class="wp-block-paragraph">Using proteomics, we often want to compare two experimental groups. A popular way to visualise this comparison this is via a <a href="https://en.wikipedia.org/wiki/Volcano_plot_(statistics)" rel="nofollow" target="_blank">volcano plot</a>, where the enrichment of proteins in one condition is towards the right and their de-enrichment (or their enrichment in the other group) is towards the left. The y-axis denotes the p-value of the comparison. Years ago, I wrote an IGOR package called <a href="https://github.com/quantixed/VolcanoPlot" rel="nofollow" target="_blank">VolcanoPlot</a>, that we have used in our work. For various reasons (see below), I have now ported the package to R.</p>



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



<p class="wp-block-paragraph">The current version takes an output (or multiple outputs) from MaxQuant, processes the data and can generate:</p>



<ul class="wp-block-list">
<li>Volcano Plots</li>



<li>Mean vs mean plots</li>



<li>PCA</li>



<li>Text outputs of the analysis</li>
</ul>



<p class="wp-block-paragraph">It uses <code>{ggplot2}</code> for graphics and therefore they can be combined easily with other plots.</p>



<h2 class="wp-block-heading">Some examples</h2>



<p class="wp-block-paragraph">There is full documentation available <a href="https://quantixed.github.io/VolcanoPlotR/" rel="nofollow" target="_blank">here</a>. But in brief:</p>



<p class="wp-block-paragraph">The package can be installed in the usual way.</p>


<pre>
# install.packages(&quot;pak&quot;)
pak::pak(&quot;quantixed/VolcanoPlotR&quot;)
</pre>


<p class="wp-block-paragraph">There is an example file in the package that can be used for testing.</p>


<pre>
library(VolcanoPlotR)
# get the path to the proteinGroups.txt file included in the package
filepath &lt;- system.file(&quot;extdata&quot;, &quot;proteinGroups.txt&quot;, package = &quot;VolcanoPlotR&quot;)
# get the filename fromt the path
filename &lt;- basename(filepath)
# get the directory name
filedir &lt;- dirname(filepath)
# run the automated procedure we will also tell it which groups to compare so
# we don&#039;t have to select them interactively
workflow_maxquant(file = filename, datadir = filedir,
                  group1 = &quot;WT&quot;, group2 = &quot;Control&quot;)
</pre>


<p class="wp-block-paragraph">Which gives the following volcano plot:</p>



<figure class="wp-block-image size-large"><img loading="lazy" fetchpriority="high" decoding="async" src="https://i1.wp.com/quantixed.org/wp-content/uploads/2026/07/volcano_plot-1024x819.png?w=450&#038;ssl=1" alt="" class="wp-image-3799" srcset_temp="https://i1.wp.com/quantixed.org/wp-content/uploads/2026/07/volcano_plot-1024x819.png?w=450&#038;ssl=1 1024w, https://quantixed.org/wp-content/uploads/2026/07/volcano_plot-300x240.png 300w, https://quantixed.org/wp-content/uploads/2026/07/volcano_plot-768x614.png 768w, https://quantixed.org/wp-content/uploads/2026/07/volcano_plot.png 1500w" sizes="(max-width: 1024px) 100vw, 1024px" data-recalc-dims="1" /></figure>



<p class="wp-block-paragraph">This plot can be styled in several ways by the package, but also restyled using ggplot.</p>



<p class="wp-block-paragraph">Rather than this automated workflow, the data can be loaded in, processed and used in other functions:</p>


<pre>
df &lt;- load_maxquant(file = filename, datadir = filedir)
df &lt;- process_maxquant(df, group1 = &quot;WT&quot;, group2 = &quot;Control&quot;)
# same output as the automated workflow
volcano_plot_maxquant(df)
# mean-mean plot with no labelling
mean_plot_maxquant(df)
# PCA plots to show the structure of the data
pca_plot_maxquant(df)
pca_plot_maxquant(df, by_protein = TRUE)
</pre>


<figure class="wp-block-gallery has-nested-images columns-default is-cropped wp-block-gallery-1 is-layout-flex wp-block-gallery-is-layout-flex">
<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" data-id="3801" src="https://i2.wp.com/quantixed.org/wp-content/uploads/2026/07/mean_plot-1024x819.png?w=450&#038;ssl=1" alt="" class="wp-image-3801" srcset_temp="https://i2.wp.com/quantixed.org/wp-content/uploads/2026/07/mean_plot-1024x819.png?w=450&#038;ssl=1 1024w, https://quantixed.org/wp-content/uploads/2026/07/mean_plot-300x240.png 300w, https://quantixed.org/wp-content/uploads/2026/07/mean_plot-768x614.png 768w, https://quantixed.org/wp-content/uploads/2026/07/mean_plot.png 1500w" sizes="(max-width: 1024px) 100vw, 1024px" data-recalc-dims="1" /></figure>



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



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



<h2 class="wp-block-heading">Why write an R package for volcano plots?</h2>



<p class="wp-block-paragraph">The best tool for analysing MaxQuant data is the Windows program Perseus. As wonderful as Perseus is, its graphics are terrible. This prompted me to write VolcanoPlot for IGOR years ago. The other motivation was that I wanted to make sure the analysis was correct (I felt back then that Perseus was too “black box” but I no longer hold that view). R is the main language we use in the lab these days and because IGOR is closed source and is no longer developed for mac, I am ported VolcanoPlot to R.</p>



<p class="wp-block-paragraph">I wrote a while back about how I could <a href="https://quantixed.org/2023/06/16/step-by-step-recreating-a-volcano-plot-in-r/" rel="nofollow" target="_blank">recreate the look of VolcanoPlot in R</a>, and the logical next step was to make a package, so that we no longer relied on VolcanoPlot. Potentially VolcanoPlotR could be expanded into a full-blown Perseus substitute, especially since PerseusR has been abandoned.</p>



<p class="wp-block-paragraph">It’s true that there are several R packages out there, so why write anothere. There’s <code>{EnhancedVolcano}</code> and proteomics data analysis available in Bioconductor, as well as Joachim Goedhart’s <a href="https://github.com/JoachimGoedhart/VolcaNoseR" rel="nofollow" target="_blank">shiny app</a>. None of these suit our needs, for example VolcanoPlotR will combine multiple MaxQuant datasets, and I was also keen to keep the look of our graphics the same for consistency between papers.</p>



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



<p class="wp-block-paragraph">The post title comes from “Eruption” by Van Halen from the Van Halen album. It’s an Eddie Van Halen instrumental which has broken the spirit of many a young guitar-slinger who’s tried to play it.</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://quantixed.org/2026/07/15/eruption-announcing-new-r-package-volcanoplotr/"> 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/eruption-announcing-new-r-package-volcanoplotr/">Eruption: announcing new R package VolcanoPlotR</a>]]></content:encoded>
					
		
		<enclosure url="" length="0" type="" />

		<post-id xmlns="com-wordpress:feed-additions:1">402617</post-id>	</item>
		<item>
		<title>From Peer Review to Mentorship: My rOpenSci Story</title>
		<link>https://www.r-bloggers.com/2026/07/from-peer-review-to-mentorship-my-ropensci-story/</link>
		
		<dc:creator><![CDATA[rOpenSci]]></dc:creator>
		<pubDate>Tue, 14 Jul 2026 00:00:00 +0000</pubDate>
				<category><![CDATA[R bloggers]]></category>
		<guid isPermaLink="false">https://ropensci.org/blog/2026/07/14/15yo-eunseop-kim/</guid>

					<description><![CDATA[<p>Getting Involved with rOpenSci<br />
I first came to rOpenSci in 2022, though at the time I barely knew what it was.<br />
I was getting a statistical package of mine ready to submit to the Journal of Statistical Software, and that is how I was pointed toward rO...</p>
<strong>Continue reading</strong>: <a href="https://www.r-bloggers.com/2026/07/from-peer-review-to-mentorship-my-ropensci-story/">From Peer Review to Mentorship: My rOpenSci Story</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/07/14/15yo-eunseop-kim/"> 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>
Getting Involved with rOpenSci
</h2><p>I first came to rOpenSci in 2022, though at the time I barely knew what it was.
I was getting a statistical package of mine ready to submit to the Journal of Statistical Software, and that is how I was pointed toward <a href="https://ropensci.org/software-review/" rel="nofollow" target="_blank">rOpenSci review</a>: the journal directs authors to rOpenSci’s statistical software standards, so going through the review looked like a convenient step along the way.
At the time, my focus was on polishing the software for the journal submission, not on rOpenSci itself.</p>
<p>What I did not expect was how much the process itself would change my perspective.
Coming from an academic background, the <a href="https://github.com/ropensci/software-review/issues/550" rel="nofollow" target="_blank">open review on GitHub</a> felt very different from the closed, anonymous process I was used to.
It was rigorous without being adversarial.
An editor and two reviewers carefully examined the package, and their feedback was constructive and grounded in <a href="https://stats-devguide.ropensci.org/standards.html" rel="nofollow" target="_blank">rOpenSci’s well-defined standards and guidelines</a>.
The review improved the package, and it also gave me a greater appreciation for the collaborative approach behind open-source software review.</p>
<p>I was later <a href="https://github.com/ropensci/software-review/issues/728" rel="nofollow" target="_blank">invited to review a package myself</a>.
The experience gave me a different perspective on the review process.
As a reviewer, I saw that the goal was not simply to determine whether a package met some standards or merits, but to help authors improve their software through constructive feedback.
When applications opened for the <a href="https://ropensci.org/champions/" rel="nofollow" target="_blank">Champions Program</a>, mentoring felt like a natural next step.
Having experienced rOpenSci as both a software author and a reviewer, it seemed like a meaningful way to contribute to the community.</p>
<h2>
Mentoring in the Champions Program
</h2><p>I was matched with <a href="https://ropensci.org/author/yi-chin-sunny-tseng/" rel="nofollow" target="_blank">Sunny Tseng</a> as her mentor.
Over the program, Sunny built <a href="https://sunnytseng.github.io/bbsTaiwan/" rel="nofollow" target="_blank">bbsTaiwan</a>, an R package that makes Taiwan’s Breeding Bird Survey data much easier to access and analyze.
It was a real package solving a real problem for people who study Taiwan’s birds, which made it a pleasure to work on together.</p>
<p>Mostly, what I gave was time and attention.
We worked through package scope, unit testing, version control, and the other practical aspects of building an R package.
Many of our conversations were not about solving a particular technical problem, but about discussing trade-offs, identifying useful resources, and thinking through the next steps.
Those conversations ended up being one of my favorite parts of the program.</p>
<p>What I valued most, though, was seeing how Sunny’s work was used after the project.
It is easy to think of a package as code made available for others to use, but in this case it became a tool that supported people working with the same data.
While visiting Taiwan, she also ran a session introducing it to members of that community.
This reinforced my view that open-source software is not just code shared in public, but a way of bringing people together around shared work.</p>
<h2>
Looking Back
</h2><p>More than anything, my time with rOpenSci has left me with an appreciation for how thoughtfully it is run.
Its initiatives, from peer review to mentorship, are organized with real care, and they are built to do more than improve software.
They are designed to connect people, bring contributors together, and keep community at the center of open science.</p>
<p>Fifteen years in, what strikes me about rOpenSci is that it has always been more about people than about packages.
What began as a convenient step on the way to a journal turned into one of the more rewarding parts of my work, and I have found value in each perspective I have seen as an author, a reviewer, and a mentor.</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/07/14/15yo-eunseop-kim/"> 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/07/from-peer-review-to-mentorship-my-ropensci-story/">From Peer Review to Mentorship: My rOpenSci Story</a>]]></content:encoded>
					
		
		<enclosure url="" length="0" type="" />

		<post-id xmlns="com-wordpress:feed-additions:1">402582</post-id>	</item>
		<item>
		<title>My last R posts: How conformalization helps weak models, fast conformal prediction with jackknife+ (and no refitting), and sklearn in R</title>
		<link>https://www.r-bloggers.com/2026/07/my-last-r-posts-how-conformalization-helps-weak-models-fast-conformal-prediction-with-jackknife-and-no-refitting-and-sklearn-in-r/</link>
		
		<dc:creator><![CDATA[T. Moudiki]]></dc:creator>
		<pubDate>Mon, 13 Jul 2026 00:00:00 +0000</pubDate>
				<category><![CDATA[R bloggers]]></category>
		<guid isPermaLink="false">https://thierrymoudiki.github.io//blog/2026/07/13/r/my-last-R-posts</guid>

					<description><![CDATA[<div style = "width:60%; display: inline-block; float:left; "> My last R posts: How conformalization helps weak models, fast conformal prediction with jackknife+ (and no refitting), and sklearn in 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/07/my-last-r-posts-how-conformalization-helps-weak-models-fast-conformal-prediction-with-jackknife-and-no-refitting-and-sklearn-in-r/">My last R posts: How conformalization helps weak models, fast conformal prediction with jackknife+ (and no refitting), and sklearn 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="https://thierrymoudiki.github.io//blog/2026/07/13/r/my-last-R-posts"> 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 is mainly (but not only) a test, because I had a broken xml feed for my R posts, and I wanted to see if it was fixed.</p>

<p>It’s about my last R posts from june and july, which are:</p>

<ul>
  <li>Using scikit-learn models in R easily with the <code>tisthemachinelearner</code> R package</li>
  <li>How conformalization helps weak models</li>
  <li>Fast Conformal Prediction for Some Machine Learning Models (jackknife+ and no refitting)</li>
</ul>

<h1 id="using-scikit-learn-models-in-r-easily-with-the-tisthemachinelearner-r-package">Using scikit-learn models in R easily with the <code>tisthemachinelearner</code> R package</h1>

<p>This post is about the <a href="https://github.com/Techtonique/tisthemachinelearner_r/tree/main" rel="nofollow" target="_blank"><code>tisthemachinelearner</code> R package</a>, that allows to use scikit-learn models in R. It is a wrapper around the <a href="https://github.com/Techtonique/tisthemachinelearner/tree/main" rel="nofollow" target="_blank">tisthemachinelearner Python package</a>. Prediction intervals can be computed using either split conformal prediction, surrogate methods or the bootstrap.</p>

<p>Read: <a href="https://thierrymoudiki.github.io/blog/2026/06/21/r/tisthemllearner" rel="nofollow" target="_blank">https://thierrymoudiki.github.io/blog/2026/06/21/r/tisthemllearner</a></p>

<h1 id="how-conformalization-helps-weak-models">How conformalization helps weak models</h1>

<p>In this post, we compare <a href="https://en.wikipedia.org/wiki/Conformal_prediction" rel="nofollow" target="_blank">split conformal prediction</a>
across several predictive models, using <a href="https://cran.r-project.org/web/packages/mlS3/index.html" rel="nofollow" target="_blank">R package mlS3</a>.</p>

<p>Read: <a href="https://thierrymoudiki.github.io/blog/2026/06/07/r/conformalization-helps-weak-models" rel="nofollow" target="_blank">https://thierrymoudiki.github.io/blog/2026/06/07/r/conformalization-helps-weak-models</a></p>

<h1 id="fast-conformal-prediction-for-some-machine-learning-models-jackknife-and-no-refitting">Fast Conformal Prediction for Some Machine Learning Models (jackknife+ and no refitting)</h1>

<p>It’s surprisingly fast to obtain conformal <a href="https://projecteuclid.org/journalArticle/Download?urlId=10.1214%2F20-AOS1965" rel="nofollow" target="_blank">jackknife+</a> prediction intervals for Machine Learning models of the form \(\hat{y} = Sy\) (including Ordinary
Least Squares, Ridge Regression, Random Vector Functional Link Networks,
Kernel Ridge Regression, smoothing splines, and local polynomial regression). <strong>No refitting involved, just Linear Algebra</strong>. Read <a href="https://www.researchgate.net/publication/408161842_Fast_Conformal_Prediction_for_Some_Machine_Learning_Models_via_Closed-Form_Jackknife" rel="nofollow" target="_blank">https://www.researchgate.net/publication/408161842_Fast_Conformal_Prediction_for_Some_Machine_Learning_Models_via_Closed-Form_Jackknife</a>.</p>

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

<p><a href="https://colab.research.google.com/github/Techtonique/mlsauce/blob/master/mlsauce/demo/thierrymoudiki-2026-06-27_jackknife_plus_smoothers.ipynb" rel="nofollow" target="_blank">
  <img src="https://colab.research.google.com/assets/colab-badge.svg" alt="Open In Colab" style="max-width: 100%; height: auto; width: 120px;" />
</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://thierrymoudiki.github.io//blog/2026/07/13/r/my-last-R-posts"> 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/my-last-r-posts-how-conformalization-helps-weak-models-fast-conformal-prediction-with-jackknife-and-no-refitting-and-sklearn-in-r/">My last R posts: How conformalization helps weak models, fast conformal prediction with jackknife+ (and no refitting), and sklearn in R</a>]]></content:encoded>
					
		
		<enclosure url="" length="0" type="" />

		<post-id xmlns="com-wordpress:feed-additions:1">402574</post-id>	</item>
		<item>
		<title>Tabler Server A minimal framework to create web dashboards in R</title>
		<link>https://www.r-bloggers.com/2026/07/tabler-server-a-minimal-framework-to-create-web-dashboards-in-r/</link>
		
		<dc:creator><![CDATA[https://pacha.dev/blog]]></dc:creator>
		<pubDate>Sun, 12 Jul 2026 23:00:00 +0000</pubDate>
				<category><![CDATA[R bloggers]]></category>
		<guid isPermaLink="false">https://pacha.dev/blog/2026/07/13/index.html</guid>

					<description><![CDATA[<p>I started working on a deliberately tiny alternative to Shiny</p>
<strong>Continue reading</strong>: <a href="https://www.r-bloggers.com/2026/07/tabler-server-a-minimal-framework-to-create-web-dashboards-in-r/">Tabler Server A minimal framework to create web dashboards 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="https://pacha.dev/blog/2026/07/13/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><strong>All of this is a very early work.</strong></p>
<p>I have been using Shiny Server for around 8 years and R for almost 11 years.</p>
<p>At some point I created the tabler R package, whose current CRAN version is a layer between Shiny and <a href="https://tabler.io/admin-template" rel="nofollow" target="_blank">Tabler</a> to offer a refreshed look for dashboards.</p>
<p>The <em>experimental</em> tabler version on <a href="https://github.com/pachadotdev/tabler" rel="nofollow" target="_blank">GitHub</a> completely drops Shiny usage on its codebase and it is also compatible with widgets created for Shiny such as <a href="https://github.com/pachadotdev/d3po" rel="nofollow" target="_blank">d3po</a>.</p>
<p>Besides local apps, I have been working on <a href="https://github.com/pachadotdev/tabler-server" rel="nofollow" target="_blank">Tabler Server</a> to manage tabler apps on a Linux machine.</p>
<p>Nothing of this is particularly novel. Most of this was done <em>standing on the shoulders of giants</em> to combine R and Linux tools efficiently.</p>
<p>Here is a simple example:</p>
<pre>pak::pkg_install(&quot;pachadotdev/tabler&quot;)

library(tabler)

ui &lt;- page(
  title = &quot;Example 1&quot;,
  layout = &quot;boxed&quot;,
  navbar = list(
    top = topbar(title = &quot;Example 1&quot;)
  ),
  body = body(
    h2(&quot;Example 1&quot;),
    p(&quot;Type your name and it is echoed back below.&quot;),
    textInput(&quot;name&quot;, &quot;Your name&quot;, value = &quot;world&quot;),
    textOutput(&quot;greeting&quot;)
  )
)

server &lt;- function(input, output, session) {
  output$greeting &lt;- renderText({
    paste0(&quot;Hello, &quot;, input$name, &quot;!&quot;)
  })

  syncUrl(session) # syncUrl(session, exclude = c(&quot;exclude&quot;, &quot;this&quot;))
}

tablerApp(ui, server)</pre>
<p>A highlight for this project is that it that it simplifies URLs. Moving the sliders, dropdowns or text inputs updates the URL and changing the URL also modified the state app. For example, http://127.0.0.1:3000/?name=John can be changed to http://127.0.0.1:3000/?name=George, and then the text entry can be changed to “Paul” to print “Hello, Paul!” to then set it to “Ringo” or another value. Unlike Shiny, the URL does not use quotes and allows for cleaner inputs like <code>?year=2000&country=gbr&lang=en</code> instead of <code>?year=2000&country=%22gbr%22&lang=%22en%22</code>.</p>
<p>Both tabler and tabler server are released under the Apache License 2.0, a permissive license for commercial and non-commercial projects.</p>
<p>I hope you like this. Please feel free to test tabler, open issues or contribute to the codebase. If you find this useful, please consider donating on <a href="https://buymeacoffee.com/pacha" rel="nofollow" target="_blank">Buy Me A Coffee</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://pacha.dev/blog/2026/07/13/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/tabler-server-a-minimal-framework-to-create-web-dashboards-in-r/">Tabler Server A minimal framework to create web dashboards in R</a>]]></content:encoded>
					
		
		<enclosure url="" length="0" type="" />

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