<?xml version="1.0" encoding="UTF-8"?>
<rss  xmlns:atom="http://www.w3.org/2005/Atom" 
      xmlns:media="http://search.yahoo.com/mrss/" 
      xmlns:content="http://purl.org/rss/1.0/modules/content/" 
      xmlns:dc="http://purl.org/dc/elements/1.1/" 
      version="2.0">
<channel>
<title>Dr. Brown Codes</title>
<link>https://drbrowncodes.com/</link>
<atom:link href="https://drbrowncodes.com/index.xml" rel="self" type="application/rss+xml"/>
<description>R, HLA informatics, and the tools behind them</description>
<generator>quarto-1.10.18</generator>
<lastBuildDate>Thu, 10 Sep 2026 04:00:00 GMT</lastBuildDate>
<item>
  <title>immunogenetr since the paper: what changed from 1.0.1 to 1.5.0</title>
  <dc:creator>Nicholas K. Brown</dc:creator>
  <link>https://drbrowncodes.com/posts/immunogenetr-since-the-paper/</link>
  <description><![CDATA[ 





<p>The immunogenetr manuscript appeared in <em>Human Immunology</em> in December 2025 (<a href="https://doi.org/10.1016/j.humimm.2025.111619">Coskun and Brown, 2026</a>), and it described the package as it stood at version 1.0.1. Since then there have been five releases, 1.1.0 through 1.5.0, with the current version published on CRAN on August 19, 2026. Anyone who learned the package from the paper will find that the workflows described there still run without modification. However, a good deal has happened underneath, and some of it changes what the functions accept and what they return, so the same code may now give different answers. This post summarizes those changes by theme rather than by version, so that readers can find the parts that matter to their own work. The version-by-version detail lives in the <a href="https://immunogenetr.org/news/index.html">changelog</a> on immunogenetr.org.</p>
<section id="clearer-errors-and-a-place-to-start" class="level2">
<h2 class="anchored" data-anchor-id="clearer-errors-and-a-place-to-start">Clearer errors and a place to start</h2>
<p>The first release after the manuscript, 1.1.0, was mostly about making the package easier to use correctly. Every exported function now validates its inputs before doing any work, so passing a data frame where a character vector was expected produces a message naming the problem instead of a cryptic failure several layers down. All error messages were standardized on the cli package, which is why they now look the same across the package. Moreover, the package gained a Getting Started vignette that walks through the main workflows (tabular data to GL Strings, splitting GL Strings by locus, mismatch and match calculation, and reading HML files), and a package-level help page, <code>?immunogenetr</code>, that groups the exported functions by category. If you have only ever read the paper, the vignette is the natural next stop.</p>
<p>The same release fixed a real bug in <code>read_HML</code>, which had assumed a hard-coded XML namespace prefix. It now discovers the namespace from the file, so HML exports from different vendors read correctly.</p>
</section>
<section id="genotype-level-match-summaries" class="level2">
<h2 class="anchored" data-anchor-id="genotype-level-match-summaries">Genotype-level match summaries</h2>
<p>Version 1.2.0 added a <code>scope</code> argument to <code>HLA_match_summary_HCT</code>. The default, <code>"locus"</code>, keeps the original behavior: for a bidirectional summary, the function takes the worse of the two directions at each locus and then sums. The new <code>"genotype"</code> scope instead computes the graft-versus-host and host-versus-graft totals separately and reports the better of the two. The two conventions differ only when one side is homozygous at a locus where the other is not, but in that situation they disagree, and different programs have different expectations.</p>
<div class="cell">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb1" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb1-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">library</span>(immunogenetr)</span>
<span id="cb1-2"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">library</span>(dplyr)</span>
<span id="cb1-3"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">library</span>(stringr)</span>
<span id="cb1-4"></span>
<span id="cb1-5">recipient <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"HLA-A*01:01+HLA-A*02:01^HLA-B*07:02+HLA-B*08:01^HLA-C*07:01+HLA-C*07:02^HLA-DRB1*03:01+HLA-DRB1*15:01"</span></span>
<span id="cb1-6">donor     <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"HLA-A*01:01+HLA-A*01:01^HLA-B*07:02+HLA-B*08:01^HLA-C*07:01+HLA-C*07:02^HLA-DRB1*03:01+HLA-DRB1*15:01"</span></span>
<span id="cb1-7"></span>
<span id="cb1-8"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">HLA_match_summary_HCT</span>(recipient, donor, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">match_grade =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Xof8"</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">direction =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"bidirectional"</span>)</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>[1] 7</code></pre>
</div>
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb3" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb3-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">HLA_match_summary_HCT</span>(recipient, donor, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">match_grade =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Xof8"</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">direction =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"bidirectional"</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">scope =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"genotype"</span>)</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>[1] 8</code></pre>
</div>
</div>
</section>
<section id="a-performance-rewrite" class="level2">
<h2 class="anchored" data-anchor-id="a-performance-rewrite">A performance rewrite</h2>
<p>Version 1.3.0 was the largest release since the manuscript, and almost none of it is visible from the outside. The package was written on top of tidyr and dplyr pipelines, which are clear to read but expensive when called once per cell of a typing table. Profiling showed that <code>HLA_prefix_remove</code>, which many other functions call internally, expanded every GL String into an ambiguity table, edited it, and reassembled it. Replacing that round trip with a few direct regular expression passes made the function roughly 100 times faster, and every caller inherited the speedup. Most of the other heavy functions were reworked along the same lines.</p>
<table class="caption-top table">
<caption>Representative timings from the 1.3.0 release notes.</caption>
<colgroup>
<col style="width: 25%">
<col style="width: 25%">
<col style="width: 25%">
<col style="width: 25%">
</colgroup>
<thead>
<tr class="header">
<th>Function</th>
<th>Workload</th>
<th>Before</th>
<th>After</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td><code>HLA_columns_to_GLstring</code></td>
<td>10,000 rows</td>
<td>~272 s</td>
<td>~1.3 s</td>
</tr>
<tr class="even">
<td><code>HLA_prefix_remove</code></td>
<td>100,000 inputs</td>
<td></td>
<td>~100× faster</td>
</tr>
<tr class="odd">
<td><code>HLA_mismatch_base</code></td>
<td>10,000 pairs</td>
<td></td>
<td>~11× faster, ~1000× less memory</td>
</tr>
<tr class="even">
<td><code>GLstring_expand_longer</code></td>
<td>varies</td>
<td></td>
<td>20 to 43× faster</td>
</tr>
<tr class="odd">
<td><code>HLA_truncate</code></td>
<td>1,000 alleles</td>
<td></td>
<td>~5× faster</td>
</tr>
</tbody>
</table>
<p>In practical terms, converting a 10,000-row typing table to GL Strings went from a coffee break to about a second. Importantly, the rewrite was checked against a new round-trip test suite, which asserts that expanding a GL String to an ambiguity table and collapsing it again reproduces the original for a representative pool of strings. The same release trimmed the dependency list, dropping glue and magrittr and adding stringi as a direct import.</p>
</section>
<section id="serologic-and-molecular-typing-in-the-same-column" class="level2">
<h2 class="anchored" data-anchor-id="serologic-and-molecular-typing-in-the-same-column">Serologic and molecular typing in the same column</h2>
<p>Real typing tables are messy. A column labeled <code>Cw</code> often holds a mix of serologic values (<code>7</code>) and molecular ones (<code>*07:01</code>), depending on when and how the sample was typed. Version 1.4.0 fixed <code>HLA_columns_to_GLstring</code> producing the invalid locus name <code>HLA-Cw*07:01</code> for molecular values in serologic-named columns, and restored the rule that a bare leading <code>*</code> marks a serologic value (<code>*17</code> becomes <code>HLA-Cw17</code>). All spellings of a locus are now grouped together, so a <code>C</code> column and a <code>Cw</code> column never end up split across a <code>^</code> delimiter.</p>
<div class="cell">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb5" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb5-1">typing <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">tibble</span>(</span>
<span id="cb5-2">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">patient =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"P1"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"P2"</span>),</span>
<span id="cb5-3">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">A1  =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"2"</span>,      <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"24"</span>),</span>
<span id="cb5-4">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">A2  =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"3"</span>,      <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"*01:01"</span>),</span>
<span id="cb5-5">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">Cw1 =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"*07:01"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"7"</span>),</span>
<span id="cb5-6">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">Cw2 =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"*17:01"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"*17"</span>)</span>
<span id="cb5-7">)</span>
<span id="cb5-8"></span>
<span id="cb5-9"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">HLA_columns_to_GLstring</span>(typing, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">HLA_typing_columns =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"A1"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"A2"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Cw1"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Cw2"</span>))</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>[1] "HLA-A2+HLA-A3^HLA-C*07:01+HLA-C*17:01" "HLA-A24+HLA-A*01:01^HLA-Cw7+HLA-Cw17" </code></pre>
</div>
</div>
<p>The same release added a <code>nomenclature</code> argument for callers who already know whether a column is molecular or serologic and would rather say so than rely on auto-detection. Of note, the relabeling is structural only: no allele-to-antigen translation is attempted, since that is a job for a different tool.</p>
</section>
<section id="gl-string-searches-that-understand-expression-suffixes" class="level2">
<h2 class="anchored" data-anchor-id="gl-string-searches-that-understand-expression-suffixes">GL String searches that understand expression suffixes</h2>
<p>The most consequential change for existing users is in <code>GLstring_regex</code>, and it arrived in 1.5.0. The function builds a regular expression that finds an allele in a GL String at any resolution, and it is the workhorse behind allele searches across a cohort. Before 1.5.0, the pattern could not match an allele carrying a WHO expression suffix (N, Q, L, S, C, or A) or a G or P group letter. A search for <code>HLA-A*01:01</code> silently missed <code>HLA-A*01:01:03N</code>, and worse, a name truncated with <code>HLA_truncate</code>, which keeps the suffix, could not find the allele it came from.</p>
<p>The rules are now as follows. An allele supplied without a suffix matches regardless of expression status and also matches G and P group names. An allele supplied with a suffix matches only alleles carrying that same letter, at the same or higher resolution. Consequently, <code>HLA-A*01:01N</code> matches <code>HLA-A*01:01:03N</code> but never <code>HLA-A*01:01:03</code> or <code>HLA-A*01:01:03Q</code>. The <code>HLA-</code> prefix is also optional now, on both sides of the search, because wild-caught GL Strings very often omit it.</p>
<div class="cell">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb7" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb7-1">gl <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"HLA-A*01:01:03N+HLA-A*24:02:01:01^HLA-B*08:01:01+HLA-B*44:02:01:01"</span></span>
<span id="cb7-2"></span>
<span id="cb7-3"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">str_detect</span>(gl, <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">GLstring_regex</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"HLA-A*01:01N"</span>))</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>[1] TRUE</code></pre>
</div>
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb9" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb9-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">str_detect</span>(gl, <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">GLstring_regex</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"HLA-A*01:01"</span>))</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>[1] TRUE</code></pre>
</div>
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb11" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb11-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">str_detect</span>(gl, <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">GLstring_regex</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"A*24:02"</span>))</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>[1] TRUE</code></pre>
</div>
</div>
<p>A second change in the same function will be welcome to anyone who has used it with <code>str_extract</code> or <code>str_replace</code>. The text matched by the pattern is now the full allele name as it appears in the GL String, not the search string. Previously a lower-resolution pattern replaced only the leading fields, leaving dangling fields behind and corrupting the GL String.</p>
<div class="cell">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb13" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb13-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">str_extract</span>(gl, <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">GLstring_regex</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"HLA-B*44:02"</span>))</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>[1] "HLA-B*44:02:01:01"</code></pre>
</div>
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb15" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb15-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">str_replace</span>(gl, <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">GLstring_regex</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"HLA-B*44:02"</span>), <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"HLA-B*44:03"</span>)</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>[1] "HLA-A*01:01:03N+HLA-A*24:02:01:01^HLA-B*08:01:01+HLA-B*44:03"</code></pre>
</div>
</div>
<p>Notably, code that relied on suffixed alleles being invisible to unsuffixed searches will see new matches after upgrading. For the cases where that older behavior was actually wanted, 1.5.0 also added <code>GLstring_drop_non_expressed</code>, which removes non-expressed alleles from a GL String before searching. The default drops N, S, and C alleles, which produce no cell-surface protein, and keeps L, Q, and A alleles, which do. Removal is structural: an ambiguity list narrows, a gene copy with nothing expressed collapses, an empty locus disappears along with its delimiter, and a GL String with nothing left becomes <code>NA</code>.</p>
<div class="cell">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb17" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb17-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">GLstring_drop_non_expressed</span>(gl)</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>[1] "HLA-A*24:02:01:01^HLA-B*08:01:01+HLA-B*44:02:01:01"</code></pre>
</div>
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb19" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb19-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">GLstring_drop_non_expressed</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"HLA-A*01:01N+HLA-A*02:01Q"</span>)</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>[1] "HLA-A*02:01Q"</code></pre>
</div>
</div>
</section>
<section id="missing-typing-and-malformed-gl-strings" class="level2">
<h2 class="anchored" data-anchor-id="missing-typing-and-malformed-gl-strings">Missing typing and malformed GL Strings</h2>
<p>Finally, the matching and mismatching family (<code>HLA_mismatch_number</code>, <code>HLA_mismatch_logical</code>, <code>HLA_match_number</code>, <code>HLA_match_summary_HCT</code>, and their relatives) became more tolerant of the kind of input a real cohort produces. A pair with missing typing on either side used to abort the entire calculation with a misleading “missing these loci” error. It now returns <code>NA</code> for that pair and processes the rest of the cohort normally.</p>
<div class="cell">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb21" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb21-1">pairs <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">tibble</span>(</span>
<span id="cb21-2">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">recipient =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"HLA-A*01:01+HLA-A*02:01"</span>, <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">NA</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"HLA-A*03:01+HLA-A*11:01"</span>),</span>
<span id="cb21-3">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">donor     =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"HLA-A*01:01+HLA-A*03:01"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"HLA-A*01:01+HLA-A*02:01"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"HLA-A*03:01+HLA-A*11:01"</span>)</span>
<span id="cb21-4">)</span>
<span id="cb21-5"></span>
<span id="cb21-6">pairs <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb21-7">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">mutate</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">mismatches =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">HLA_mismatch_number</span>(recipient, donor, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">loci =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"HLA-A"</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">direction =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"bidirectional"</span>))</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code># A tibble: 3 × 3
  recipient               donor                   mismatches
  &lt;chr&gt;                   &lt;chr&gt;                        &lt;int&gt;
1 HLA-A*01:01+HLA-A*02:01 HLA-A*01:01+HLA-A*03:01          1
2 &lt;NA&gt;                    HLA-A*01:01+HLA-A*02:01         NA
3 HLA-A*03:01+HLA-A*11:01 HLA-A*03:01+HLA-A*11:01          0</code></pre>
</div>
</div>
<p>In the other direction, the same functions now reject GL Strings containing the <code>~</code> (haplotype) and <code>?</code> (possible gene location) delimiters, which were previously accepted and silently mis-tokenized. A <code>?</code>-joined pair of DRB3/4/5 alleles, for example, was being read as a single allele and produced wrong match counts. Ambiguous GL Strings containing <code>|</code> or <code>/</code> were already rejected; the error now names all four delimiters. Two smaller additions round out the release: a <code>take_first_allele</code> argument for <code>HLA_validate</code> and <code>HLA_columns_to_GLstring</code>, for callers who would rather have a GL String landing in a single-allele column raise an error than be quietly truncated, and <code>ambiguity_table_to_GLstring</code> returning <code>character(0)</code> for an empty table so that expand, filter, and reassemble pipelines compose without special cases.</p>
</section>
<section id="take-homes" class="level2">
<h2 class="anchored" data-anchor-id="take-homes">Take-homes</h2>
<ol type="1">
<li>Upgrade with <code>install.packages("immunogenetr")</code>. The code in the paper still runs, and large tables now convert in seconds rather than minutes. Items 2 and 3 below are the places where results can change.</li>
<li>If you search GL Strings for alleles, re-check any logic that assumed null alleles would not match. Use <code>GLstring_drop_non_expressed</code> first if that assumption was deliberate.</li>
<li>If you use <code>str_extract</code> or <code>str_replace</code> with <code>GLstring_regex</code>, the match is now the whole allele, which is almost certainly what you wanted.</li>
<li>Cohorts with missing typing no longer need to be filtered before matching; the <code>NA</code> values propagate.</li>
</ol>
<p>The full changelog is on <a href="https://immunogenetr.org/news/index.html">immunogenetr.org</a>, and each release has notes on <a href="https://github.com/k96nb01/immunogenetr_package/releases">GitHub</a>. Bug reports and feature requests are welcome in the <a href="https://github.com/k96nb01/immunogenetr_package/issues">issue tracker</a>; most of the changes above started as one.</p>


</section>

 ]]></description>
  <category>immunogenetr</category>
  <category>R</category>
  <category>HLA</category>
  <guid>https://drbrowncodes.com/posts/immunogenetr-since-the-paper/</guid>
  <pubDate>Thu, 10 Sep 2026 04:00:00 GMT</pubDate>
</item>
</channel>
</rss>
