<?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>Technical Blog</title>
<link>https://al-garik.github.io/ks-blog/</link>
<atom:link href="https://al-garik.github.io/ks-blog/index.xml" rel="self" type="application/rss+xml"/>
<description>Articles about R programming, and clinical data analysis and reporting</description>
<generator>quarto-1.9.37</generator>
<lastBuildDate>Sun, 12 Jul 2026 21:00:00 GMT</lastBuildDate>
<item>
  <title>How Long Are You Ready to Wait for Your Clinical Tables?</title>
  <dc:creator>Igor Aleschenkov (KeyStat Solutions)</dc:creator>
  <link>https://al-garik.github.io/ks-blog/posts/2026-07-13-reporter-vs-ksTFL-performance/</link>
  <description><![CDATA[ 




<p>When you’re creating a few tables for a publication or an exploratory analysis, report generation time usually isn’t something you think about. If a table takes a couple of seconds to produce, you simply move on to the next task.</p>
<p>Clinical trial reporting is different.</p>
<p>A typical CSR may contain hundreds of Tables, Figures and Listings (TFLs). Interim analyses, reruns after database updates, quality control cycles, programming reviews, and production runs — and suddenly those “few extra seconds” become hours of waiting.</p>
<p>Performance is no longer just a nice-to-have feature — it directly affects programmer productivity.</p>
<p>To see how much difference the reporting engine itself can make, I compared one of the most widely used clinical reporting packages in R, <em>Reporter</em>, with the newly released <em>ksTFL</em> package.</p>
<section id="benchmark-setup" class="level2">
<h2 class="anchored" data-anchor-id="benchmark-setup">Benchmark setup</h2>
<p>The goal was to compare the document generation engines rather than data preparation or statistical computation.</p>
<p>A realistic laboratory listing dataset was generated with dummy data containing: 10 investigative sites, 20 subjects per site, Subject demographics (Age and Sex), Laboratory category (Chemistry and Hematology), Laboratory parameter, Assessment date, Visit, Laboratory result, Unit, and Low / Normal / High indicator</p>
<pre><code>   SITE         USUBJID AGE SEX     LBCAT     LBTEST      LBDTC     VISIT LBORRES LBORRESU LBNRIND
1   001 ABC-101-001-001  31   M Chemistry        ALT 2024-02-20 Screening   124.0      U/L  NORMAL
2   001 ABC-101-001-001  31   M Chemistry        AST 2024-02-20 Screening    66.0      U/L  NORMAL
3   001 ABC-101-001-001  31   M Chemistry        ALP 2024-02-20 Screening   111.9      U/L  NORMAL
4   001 ABC-101-001-001  31   M Chemistry  Bilirubin 2024-02-20 Screening   130.5   umol/L  NORMAL
5   001 ABC-101-001-001  31   M Chemistry    Albumin 2024-02-20 Screening    89.2      g/L  NORMAL
6   001 ABC-101-001-001  31   M Chemistry Creatinine 2024-02-20 Screening   124.0   umol/L  NORMAL
7   001 ABC-101-001-001  31   M Chemistry       Urea 2024-02-20 Screening   140.0   mmol/L     LOW
8   001 ABC-101-001-001  31   M Chemistry    Glucose 2024-02-20 Screening   113.6   mmol/L  NORMAL
9   001 ABC-101-001-001  31   M Chemistry        ALT 2024-06-03  Baseline   101.8      U/L  NORMAL
10  001 ABC-101-001-001  31   M Chemistry        AST 2024-06-03  Baseline   115.6      U/L  NORMAL</code></pre>
<p>The following functions were created to run with the <code>bench</code> package.</p>
<section id="reporter" class="level3">
<h3 class="anchored" data-anchor-id="reporter">Reporter</h3>
<div class="cell">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb2" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb2-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">library</span>(reporter)</span>
<span id="cb2-2"></span>
<span id="cb2-3">reporter_bench <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">function</span>(nrows) {</span>
<span id="cb2-4"></span>
<span id="cb2-5">tbl <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;">create_table</span>(lab <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">head</span>(nrows)) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb2-6">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">page_by</span>(SITE,   <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">label=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Site: "</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb2-7">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">define</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'SITE'</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">visible =</span> F) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb2-8">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">define</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'USUBJID'</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">dedupe =</span> T)</span>
<span id="cb2-9"></span>
<span id="cb2-10">rpt <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span></span>
<span id="cb2-11">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">create_report</span>(</span>
<span id="cb2-12">        <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Reporter_LabListing.rtf"</span>,  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">output_type=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"RTF"</span>,</span>
<span id="cb2-13">        <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">font=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Courier"</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">font_size=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">8</span></span>
<span id="cb2-14">    ) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb2-15">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">page_header</span>(</span>
<span id="cb2-16">        <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">left=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"ABC-101"</span>,</span>
<span id="cb2-17">        <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">center=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Laboratory Listing"</span>,</span>
<span id="cb2-18">        <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">right=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"CSR"</span></span>
<span id="cb2-19">    ) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb2-20">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">titles</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Listing 14.3.1"</span>,<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Laboratory Results Listings by Site"</span>   ) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb2-21">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">add_content</span>(tbl) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb2-22">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">footnotes</span>(</span>
<span id="cb2-23">        <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"LOW = Below reference range"</span>,</span>
<span id="cb2-24">        <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"HIGH = Above reference range"</span></span>
<span id="cb2-25">    ) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb2-26">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">page_footer</span>(</span>
<span id="cb2-27">        <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">left=</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">format</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">Sys.Date</span>()),</span>
<span id="cb2-28">        <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">center=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Confidential"</span>,</span>
<span id="cb2-29">        <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">right=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Page [pg] of [tpg]"</span></span>
<span id="cb2-30">    )</span>
<span id="cb2-31"></span>
<span id="cb2-32">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">write_report</span>(rpt)</span>
<span id="cb2-33">    </span>
<span id="cb2-34">}</span></code></pre></div></div>
</div>
</section>
<section id="kstfl" class="level3">
<h3 class="anchored" data-anchor-id="kstfl">ksTFL</h3>
<div class="cell">
<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;">library</span>(ksTFL)</span>
<span id="cb3-2"></span>
<span id="cb3-3">ksTFL_bench <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">function</span>(nrows) {</span>
<span id="cb3-4"></span>
<span id="cb3-5">data <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> lab <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">head</span>(nrows)</span>
<span id="cb3-6"></span>
<span id="cb3-7">listing <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;">create_table</span>(data) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb3-8">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">add_header</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;">"ABC-101"</span>,<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Laboratory Listing"</span>,<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"CSR"</span>)) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb3-9">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">add_footer</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">format</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">Sys.Date</span>()), <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Confidential"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Page {PAGE} of {NUMPAGES}"</span>)) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb3-10">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">add_title</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;">"Listing 14.3.1"</span>,   <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Laboratory Results Listings by Site"</span>)) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb3-11">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">add_subtitle</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Site: #ByGroup1"</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb3-12">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">add_footnote</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;">"LOW = Below reference range"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"HIGH = Above reference range"</span>)) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb3-13">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">define_cols</span>(SITE, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">isVisible =</span> F, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">isGrouping =</span> T) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb3-14">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">define_cols</span>(USUBJID, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">dedupe =</span> T)</span>
<span id="cb3-15"></span>
<span id="cb3-16">rep <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;">create_report</span>(listing)</span>
<span id="cb3-17"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">write_doc</span>(rep, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'ksTFL_LabListing'</span>)</span>
<span id="cb3-18"></span>
<span id="cb3-19">}</span></code></pre></div></div>
</div>
<p>Both packages generated essentially the same report:</p>
<ul>
<li>Laboratory data listing</li>
<li>Paginated by Site Number</li>
<li>Standard clinical titles</li>
<li>Dynamic subtitle with Site Number</li>
<li>Page headers and footers</li>
<li>Footnotes</li>
<li>Default formatting</li>
</ul>
<p>Here are the side-by-side view of the first page of the created documents:</p>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="images/documents.png" class="lightbox" data-gallery="quarto-lightbox-gallery-1"><img src="https://al-garik.github.io/ks-blog/posts/2026-07-13-reporter-vs-ksTFL-performance/images/documents.png" class="img-fluid quarto-figure quarto-figure-center figure-img"></a></p>
</figure>
</div>
<p>The benchmark was repeated using datasets containing 1000, 3000, 10000, and 20000 listing records. Each benchmark was executed twice, and the median execution time was reported.</p>
<div class="cell">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb4" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb4-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">library</span>(bench)</span>
<span id="cb4-2"></span>
<span id="cb4-3">sizes <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;">c</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1000</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3000</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10000</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">20000</span>)</span>
<span id="cb4-4"></span>
<span id="cb4-5">results <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span></span>
<span id="cb4-6">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">bind_rows</span>(</span>
<span id="cb4-7">        <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">lapply</span>(sizes, <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">function</span>(n) {</span>
<span id="cb4-8">            </span>
<span id="cb4-9">            <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">cat</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Benchmarking"</span>, n, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"rows...</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\n</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span>)</span>
<span id="cb4-10">            </span>
<span id="cb4-11">            x <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span></span>
<span id="cb4-12">                bench<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">mark</span>(</span>
<span id="cb4-13">                    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">Reporter =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">reporter_bench</span>(n),</span>
<span id="cb4-14">                    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">ksTFL    =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">ksTFL_bench</span>(n),</span>
<span id="cb4-15">                    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">iterations =</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>,</span>
<span id="cb4-16">                    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">check =</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">FALSE</span>,</span>
<span id="cb4-17">                    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">memory =</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">TRUE</span>,</span>
<span id="cb4-18">                    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">time_unit =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"s"</span></span>
<span id="cb4-19">                )</span>
<span id="cb4-20">            </span>
<span id="cb4-21">            x<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>nrows <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> n</span>
<span id="cb4-22">            </span>
<span id="cb4-23">            x</span>
<span id="cb4-24">        })</span>
<span id="cb4-25">    )</span></code></pre></div></div>
</div>
<p>Here are the results:</p>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="images/results_table.png" class="lightbox" data-gallery="quarto-lightbox-gallery-2"><img src="https://al-garik.github.io/ks-blog/posts/2026-07-13-reporter-vs-ksTFL-performance/images/results_table.png" class="img-fluid quarto-figure quarto-figure-center figure-img"></a></p>
</figure>
</div>
</section>
</section>
<section id="what-stands-out" class="level2">
<h2 class="anchored" data-anchor-id="what-stands-out">What stands out?</h2>
<p>The difference is immediately noticeable.</p>
<p>Even for a relatively small listing of <strong>1,000 rows</strong>, <strong>ksTFL</strong> completed report generation in just over <strong>100 milliseconds</strong>, while <strong>Reporter</strong> required almost <strong>3 seconds</strong>.</p>
<p>As the listing size increased, the performance gap widened considerably.</p>
<p>For <strong>20,000 rows</strong>, Reporter required more than <strong>one and a half minutes</strong> to generate the report, whereas ksTFL completed the same task in just over <strong>one second</strong>.</p>
<p>More interestingly, the advantage isn’t constant—it increases dramatically with report size. Rather than maintaining a fixed performance lead, ksTFL’s advantage actually <em>grows</em> as datasets become larger, as illustrated below:</p>
<div class="cell">
<div class="cell-output-display">
<div>
<figure class="figure">
<p><a href="index_files/figure-html/unnamed-chunk-4-1.png" class="lightbox" data-gallery="quarto-lightbox-gallery-3"><img src="https://al-garik.github.io/ks-blog/posts/2026-07-13-reporter-vs-ksTFL-performance/index_files/figure-html/unnamed-chunk-4-1.png" class="img-fluid figure-img" width="672"></a></p>
</figure>
</div>
</div>
</div>
<p>The chart reveals a consistent upward trend: at 1,000 rows, ksTFL is <strong>28× faster</strong>; this advantage grows to <strong>41×</strong> at 3,000 rows, <strong>50×</strong> at 10,000 rows, and <strong>73×</strong> at 20,000 rows. This non-linear relationship is the hallmark of a reporting engine that scales with computational efficiency.</p>
</section>
<section id="memory-usage-tells-an-even-bigger-story" class="level2">
<h2 class="anchored" data-anchor-id="memory-usage-tells-an-even-bigger-story">Memory usage tells an even bigger story</h2>
<p>Execution time is only part of the picture.</p>
<p>The amount of memory allocated during report generation increases rapidly for Reporter as the listing becomes larger. For the largest benchmark Reporter allocated nearly <strong>50 GB</strong> of memory while ksTFL required <strong>only 38 MB</strong>.</p>
<p>This dramatic disparity grows more severe as dataset size increases:</p>
<div class="cell">
<div class="cell-output-display">
<div>
<figure class="figure">
<p><a href="index_files/figure-html/unnamed-chunk-5-1.png" class="lightbox" data-gallery="quarto-lightbox-gallery-4"><img src="https://al-garik.github.io/ks-blog/posts/2026-07-13-reporter-vs-ksTFL-performance/index_files/figure-html/unnamed-chunk-5-1.png" class="img-fluid figure-img" width="672"></a></p>
</figure>
</div>
</div>
</div>
<p>As shown in the chart, Reporter’s memory consumption grows exponentially with dataset size—scaling from 125 MB at 1,000 rows to over 50 GB at 20,000 rows. In contrast, ksTFL’s memory footprint remains consistently modest across all tested sizes, growing from less than 1 MB to just 38 MB.</p>
<p>Lower memory consumption isn’t just an interesting benchmark statistic. It means:</p>
<ul>
<li><p>reduced risk of exhausting available memory,</p></li>
<li><p>better performance on virtual machines and shared servers,</p></li>
<li><p>and the ability to generate multiple reports in parallel without competing for system resources.</p></li>
</ul>
</section>
<section id="why-does-this-matter" class="level2">
<h2 class="anchored" data-anchor-id="why-does-this-matter">Why does this matter?</h2>
<p>In real-world clinical reporting, the document generation step is only one part of the overall workflow. Data preparation, derivations and statistical analyses often account for a large proportion of the total runtime.</p>
<p>However, once the analysis datasets are ready, the reporting engine becomes the final stage and sometimes repeated over and over again.</p>
<p>During study development, programmers regenerate reports after every change, QC programmers independently recreate the same outputs, and complete production runs are repeated for interim analyses, database updates and final deliverables.</p>
<p>A study containing a few hundred outputs may therefore generate <strong>thousands of report files</strong> over its lifetime.</p>
<p>Even if each individual report saves only a few seconds, those savings accumulate into hours of reduced waiting time for programmers and much faster production cycles.</p>
</section>
<section id="final-thoughts" class="level2">
<h2 class="anchored" data-anchor-id="final-thoughts">Final thoughts</h2>
<p>Performance isn’t the only criterion when selecting a reporting framework. Functionality, output quality, flexibility and ease of use are equally important.</p>
<p>Nevertheless, report generation speed becomes increasingly valuable as studies become larger and reporting workflows become more automated.</p>
<p>One particularly interesting observation from this benchmark is that <strong>the performance advantage of ksTFL grows as report size increases</strong>. Rather than maintaining a constant lead, ksTFL becomes progressively faster relative to Reporter while simultaneously requiring dramatically less memory.</p>
<p>Although this benchmark focuses on a laboratory listing, the results indicate that the underlying document generation engine scales efficiently and remains responsive even for substantially larger reports.</p>
<p>If your reporting workflow involves generating hundreds of outputs throughout the lifetime of a clinical trial, those gains can translate into noticeably shorter development cycles, faster production runs, and a smoother experience for the programming team.</p>
<hr>
<p><em>Benchmark environment:</em> Both packages were executed on the same machine using the same input data and comparable report layouts. Each benchmark was run <strong>twice</strong>, with the <strong>median execution time</strong> reported. The benchmark was designed to measure the performance of the reporting engine itself, not the time required for data preparation or statistical analyses. The measurements were done using <code>reporter</code> version 1.4.7, and <code>ksTFL</code> version 0.11.9.</p>
<hr>
<pre><code>Aleschenkov I, Larchenko V (2026). _ksTFL: Framework for Clinical Tables,
  Figures, and Listings_. R package version 0.11.9,
  &lt;https://crow16384.github.io/ksTFL/,https://crow16384.r-universe.dev/ksTFL&gt;</code></pre>
<p><em>This post was originally published on the KeyStat Solutions R Technical Blog. <a href="https://www.r-bloggers.com">Visit R-Bloggers</a> to discover more R content.</em></p>


</section>

 ]]></description>
  <category>R</category>
  <category>ksTFL</category>
  <category>clinical trial</category>
  <category>r-package</category>
  <category>Clinical Reporting</category>
  <guid>https://al-garik.github.io/ks-blog/posts/2026-07-13-reporter-vs-ksTFL-performance/</guid>
  <pubDate>Sun, 12 Jul 2026 21:00:00 GMT</pubDate>
  <media:content url="https://al-garik.github.io/ks-blog/posts/2026-07-13-reporter-vs-ksTFL-performance/images/post-logo.png" medium="image" type="image/png" height="81" width="144"/>
</item>
<item>
  <title>Non-standard Applications of ksformat R-Package in Clinical Trials and Other Tasks</title>
  <dc:creator>Vladimir Larchenko (KeyStat Solutions)</dc:creator>
  <link>https://al-garik.github.io/ks-blog/posts/2026-07-09-non-standard-applications-of-ksformat/</link>
  <description><![CDATA[ 




<section id="overview" class="level1">
<h1>Overview</h1>
<p><code>ksformat</code> is usually described as a <strong>SAS PROC FORMAT-like tool</strong> for ordinary value-to-label lookup. In practice, the package is useful in places where a clinical trial workflow needs more than a plain dictionary:</p>
<ul>
<li>protocol-defined visit windows</li>
<li>subject- or arm-specific bucketing rules</li>
<li>composite keys built from multiple columns</li>
<li>reverse lookups for data cleaning and QC</li>
<li>report-ready numeric display for listings and summaries</li>
</ul>
<p>This article shows a few non-standard uses that come up in clinical trials and adjacent data tasks.</p>
</section>
<section id="protocol-windows-and-subject-specific-buckets" class="level1">
<h1>1. Protocol windows and subject-specific buckets</h1>
<p>A common clinical-trials task is mapping visit-day values into protocol-defined windows. The same idea extends to arm-specific rules, where one stratum has a slightly different window structure from another.</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">windows <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;">fmap_strata</span>(</span>
<span id="cb1-2">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">stratum =</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;">"ARM_A"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"ARM_A"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"ARM_A"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"ARM_B"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"ARM_B"</span>),</span>
<span id="cb1-3">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">low     =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>,        <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">7</span>,       <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">28</span>,      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>,       <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">14</span>),</span>
<span id="cb1-4">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">high    =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">7</span>,        <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">28</span>,      <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">Inf</span>,     <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">14</span>,      <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">Inf</span>),</span>
<span id="cb1-5">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">label   =</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;">"Baseline"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Wk1-3"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Wk4+"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Baseline"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Wk2+"</span>),</span>
<span id="cb1-6">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">inc_high =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(<span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">FALSE</span>, <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">FALSE</span>, <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">TRUE</span>, <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">FALSE</span>, <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">TRUE</span>)</span>
<span id="cb1-7">)</span>
<span id="cb1-8"></span>
<span id="cb1-9"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">fnew</span>(</span>
<span id="cb1-10">  windows,</span>
<span id="cb1-11">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">type =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"stratified_range"</span>,</span>
<span id="cb1-12">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">name =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"visit_window"</span>,</span>
<span id="cb1-13">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">.other =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Outside window"</span></span>
<span id="cb1-14">)</span>
<span id="cb1-15"></span>
<span id="cb1-16">visit_df <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="cb1-17">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">arm =</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;">"ARM_A"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"ARM_A"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"ARM_B"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"ARM_B"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"ARM_C"</span>),</span>
<span id="cb1-18">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">day =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">35</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">40</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span>)</span>
<span id="cb1-19">) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">mutate</span>(</span>
<span id="cb1-20">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">window =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">fputk</span>(arm, day, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">format =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"visit_window"</span>),</span>
<span id="cb1-21">)</span>
<span id="cb1-22"></span>
<span id="cb1-23">visit_df</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code># A tibble: 5 × 3
  arm     day window        
  &lt;chr&gt; &lt;dbl&gt; &lt;chr&gt;         
1 ARM_A     3 Baseline      
2 ARM_A    35 Wk4+          
3 ARM_B     5 Baseline      
4 ARM_B    40 Wk2+          
5 ARM_C    10 Outside window</code></pre>
</div>
</div>
<p>This is useful for:</p>
<ul>
<li>visit window derivation in ADaM outputs</li>
<li>protocol deviation checks</li>
<li>windowed endpoint calculations</li>
</ul>
</section>
<section id="composite-keys-for-clinical-mappings" class="level1">
<h1>2. Composite keys for clinical mappings</h1>
<p>Clinical trial data often uses multi-column logic: lab category + test code + unit, or population + analysis flag + visit type. <code>fputk()</code> can build a lookup from multiple fields without manually concatenating in the analysis step.</p>
<div class="cell">
<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;">fnew</span>(</span>
<span id="cb3-2">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">fmap</span>(</span>
<span id="cb3-3">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">paste</span>(</span>
<span id="cb3-4">      <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;">"BLOOD CHEMISTRY"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"COAGULOGRAM"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"COAGULATION PANEL"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"COAGULOGRAM"</span>),</span>
<span id="cb3-5">      <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;">"BLOOD"</span>,           <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"BLOOD"</span>,        <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"BLOOD"</span>,             <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"BLOOD"</span>),</span>
<span id="cb3-6">      <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;">"ALB"</span>,             <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"FIBRINO"</span>,      <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"INR"</span>,               <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"INR"</span>),</span>
<span id="cb3-7">      <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;">"g/L"</span>,             <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"g/L"</span>,           <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">NA</span>,                  <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">NA</span>),</span>
<span id="cb3-8">      <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">sep =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"|"</span></span>
<span id="cb3-9">    ),</span>
<span id="cb3-10">    <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;">"ALB"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"FIBRINO"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"INR"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"INR"</span>)</span>
<span id="cb3-11">  ),</span>
<span id="cb3-12">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">type =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"character"</span>,</span>
<span id="cb3-13">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">name =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"lb_param"</span>,</span>
<span id="cb3-14">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">ignore_case =</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">TRUE</span>,</span>
<span id="cb3-15">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">.other =</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">NA</span></span>
<span id="cb3-16">)</span>
<span id="cb3-17"></span>
<span id="cb3-18">lab_df <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="cb3-19">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">LBCAT =</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;">"BLOOD CHEMISTRY"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"COAGULOGRAM"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"COAGULATION PANEL"</span>),</span>
<span id="cb3-20">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">LBSPEC =</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;">"BLOOD"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"BLOOD"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"BLOOD"</span>),</span>
<span id="cb3-21">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">LBTESTCD =</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;">"ALB"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"INR"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"INR"</span>),</span>
<span id="cb3-22">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">LBSTRESU =</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;">"g/L"</span>, <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">NA</span>, <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">NA</span>)</span>
<span id="cb3-23">) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">mutate</span>(</span>
<span id="cb3-24">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">PARAMCD =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">fputk</span>(LBCAT, LBSPEC, LBTESTCD, LBSTRESU, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">format =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"lb_param"</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">na_as_string =</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">TRUE</span>)</span>
<span id="cb3-25">)</span>
<span id="cb3-26"></span>
<span id="cb3-27">lab_df</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code># A tibble: 3 × 5
  LBCAT             LBSPEC LBTESTCD LBSTRESU PARAMCD
  &lt;chr&gt;             &lt;chr&gt;  &lt;chr&gt;    &lt;chr&gt;    &lt;chr&gt;  
1 BLOOD CHEMISTRY   BLOOD  ALB      g/L      ALB    
2 COAGULOGRAM       BLOOD  INR      &lt;NA&gt;     INR    
3 COAGULATION PANEL BLOOD  INR      &lt;NA&gt;     INR    </code></pre>
</div>
</div>
<p>The same pattern is useful for:</p>
<ul>
<li>AE grouping by term + severity + relation</li>
<li>CM coding by medication + route + dose form</li>
<li>endpoint derivations from multiple source fields</li>
</ul>
</section>
<section id="reverse-lookup-for-qc-and-cleaning" class="level1">
<h1>3. Reverse lookup for QC and cleaning</h1>
<p><code>finputk()</code> is helpful when raw labels must be normalized back to codes. In clinical programming, that makes it suitable for QC checks, mapping vendor text, and validating reviewer-facing labels.</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"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">finput</span>(</span>
<span id="cb5-2">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">fmap</span>(</span>
<span id="cb5-3">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">paste</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;">"PLACEBO"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"DRUG A"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"DRUG B"</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;">"PBO"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"A50"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"B100"</span>), <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">sep =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"|"</span>),</span>
<span id="cb5-4">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>L, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>L, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>L)</span>
<span id="cb5-5">  ),</span>
<span id="cb5-6">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">target_type =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"integer"</span>,</span>
<span id="cb5-7">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">name =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"trt_code_inv"</span></span>
<span id="cb5-8">)</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>KS Invalue: trt_code_inv
Target Type: integer 
Mappings:
  PLACEBO|PBO =&gt; 1
  DRUG A|A50 =&gt; 2
  DRUG B|B100 =&gt; 3</code></pre>
</div>
<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">trt_df <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="cb7-2">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">ARMN =</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;">"PLACEBO"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"DRUG A"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"DRUG B"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"UNKNOWN"</span>),</span>
<span id="cb7-3">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">TRTCD =</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;">"PBO"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"A50"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"B100"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"X"</span>)</span>
<span id="cb7-4">) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">mutate</span>(</span>
<span id="cb7-5">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">TRTSEQ =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">finputk</span>(ARMN, TRTCD, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">invalue_name =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"trt_code_inv"</span>)</span>
<span id="cb7-6">)</span>
<span id="cb7-7"></span>
<span id="cb7-8">trt_df</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code># A tibble: 4 × 3
  ARMN    TRTCD TRTSEQ
  &lt;chr&gt;   &lt;chr&gt;  &lt;int&gt;
1 PLACEBO PBO        1
2 DRUG A  A50        2
3 DRUG B  B100       3
4 UNKNOWN X         NA</code></pre>
</div>
</div>
<p>Typical uses include:</p>
<ul>
<li>deriving internal codes from decoded labels in QC datasets</li>
<li>validating data entry against controlled terminology</li>
<li>reconciling spreadsheet exports back to source codes</li>
</ul>
</section>
<section id="report-ready-numeric-formatting" class="level1">
<h1>4. Report-ready numeric formatting</h1>
<p><code>ksformat</code> can also be used where report output needs consistent numeric presentation. This is not a lookup table; it is a pattern-driven formatter.</p>
<div class="cell">
<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;">fnew</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"$%,.2f"</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">type =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"numeric"</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">name =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"currency"</span>)</span>
<span id="cb9-2"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">fnew</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"%.1f%%"</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">type =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"numeric"</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">name =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"pct"</span>)</span>
<span id="cb9-3"></span>
<span id="cb9-4">summary_df <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="cb9-5">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">metric =</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;">"Cost"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Response rate"</span>),</span>
<span id="cb9-6">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">raw =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1234.56</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.153</span>)</span>
<span id="cb9-7">) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">mutate</span>(</span>
<span id="cb9-8">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">display =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">fputn</span>(raw[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>], <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"currency"</span>), <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">fputn</span>(raw[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>] <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">100</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"pct"</span>))</span>
<span id="cb9-9">)</span>
<span id="cb9-10"></span>
<span id="cb9-11">summary_df</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code># A tibble: 2 × 3
  metric             raw display  
  &lt;chr&gt;            &lt;dbl&gt; &lt;chr&gt;    
1 Cost          1235.    $1,234.56
2 Response rate    0.153 15.3%    </code></pre>
</div>
</div>
<p>Same result could be achieved using expression labels, but in base R, <code>sprintf()</code> itself does not support thousands separators such as commas. We can use <code>formatC</code> for the formatting purposes. <strong>Pattern-driven formatter</strong> looks simplier for such case.</p>
<div class="cell">
<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">stat_fmt <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;">fnew</span>(</span>
<span id="cb11-2">  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">#"currency"   = "sprintf('$%,.2f', .x1)", # Will not work!</span></span>
<span id="cb11-3">  <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"currency"</span>   <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"formatC(.x1, digits = 2, big.mark = ',', format = 'f', decimal.mark = '.')"</span>,</span>
<span id="cb11-4">  <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"pct"</span> <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"sprintf('%.1f%%', .x1 * 100)"</span>,</span>
<span id="cb11-5">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">name =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"stat"</span>,</span>
<span id="cb11-6">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">type =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"character"</span></span>
<span id="cb11-7">)</span>
<span id="cb11-8"></span>
<span id="cb11-9">summary_df <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="cb11-10">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">metric =</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;">"Cost"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Response rate"</span>),</span>
<span id="cb11-11">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">raw =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1234.56</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.153</span>),</span>
<span id="cb11-12">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">format =</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;">"currency"</span>,<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"pct"</span>)</span>
<span id="cb11-13">) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">mutate</span>(</span>
<span id="cb11-14">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">display =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">fput</span>(format, stat_fmt, raw)</span>
<span id="cb11-15">)</span>
<span id="cb11-16"></span>
<span id="cb11-17">summary_df</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code># A tibble: 2 × 4
  metric             raw format   display 
  &lt;chr&gt;            &lt;dbl&gt; &lt;chr&gt;    &lt;chr&gt;   
1 Cost          1235.    currency 1,234.56
2 Response rate    0.153 pct      15.3%   </code></pre>
</div>
</div>
<p>This is useful for:</p>
<ul>
<li>CSR and TLF output generation</li>
<li>QA listings for counts and rates</li>
<li>ad hoc review tables where consistent display matters</li>
</ul>
</section>
<section id="bucketing-dates-into-operational-periods" class="level1">
<h1>5. Bucketing dates into operational periods</h1>
<p>Clinical teams often work with periods such as screening, treatment, follow-up, and analysis cut-offs. <code>date_range</code> and <code>datetime_range</code> let you keep those rules in one place instead of duplicating them in ad hoc code.</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;">fparse</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">text =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span></span>
<span id="cb13-2"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">VALUE study_period (date_range)</span></span>
<span id="cb13-3"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">  [2024-01-01, 2024-02-01) = "Screening"</span></span>
<span id="cb13-4"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">  [2024-02-01, 2024-06-01) = "Treatment"</span></span>
<span id="cb13-5"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">  [2024-06-01, HIGH]       = "Follow-up"</span></span>
<span id="cb13-6"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">  .missing                 = "No date"</span></span>
<span id="cb13-7"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb13-8"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span>)</span>
<span id="cb13-9"></span>
<span id="cb13-10">obs_dates <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;">as.Date</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;">"2024-01-15"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"2024-03-10"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"2024-07-01"</span>, <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">NA</span>))</span>
<span id="cb13-11"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">tibble</span>(</span>
<span id="cb13-12">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">date =</span> obs_dates,</span>
<span id="cb13-13">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">period =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">fput</span>(obs_dates, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"study_period"</span>)</span>
<span id="cb13-14">)</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code># A tibble: 4 × 2
  date       period   
  &lt;date&gt;     &lt;chr&gt;    
1 2024-01-15 Screening
2 2024-03-10 Treatment
3 2024-07-01 Follow-up
4 NA         No date  </code></pre>
</div>
</div>
</section>
<section id="text-generation-for-listings-and-narratives" class="level1">
<h1>6. Text generation for listings and narratives</h1>
<p>Expression labels make <code>ksformat</code> useful for building small text fragments in reports. In clinical settings, that can be handy for reviewer comments, summary phrases, or footnotes.</p>
<div class="cell">
<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;">fnew</span>(</span>
<span id="cb15-2">  <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"high"</span> <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"sprintf('Above threshold: %s', .x1)"</span>,</span>
<span id="cb15-3">  <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"low"</span> <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"sprintf('Below threshold: %s', .x1)"</span>,</span>
<span id="cb15-4">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">name =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"thr_note"</span></span>
<span id="cb15-5">)</span>
<span id="cb15-6"></span>
<span id="cb15-7"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">fput</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;">"high"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"low"</span>), <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"thr_note"</span>, <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">18.2</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">7.4</span>))</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>[1] "Above threshold: 18.2" "Below threshold: 7.4" </code></pre>
</div>
</div>
<p>This is especially useful when the label depends on:</p>
<ul>
<li>a measurement value</li>
<li>a threshold or cohort-specific cutoff</li>
<li>an external text fragment such as a reviewer comment</li>
</ul>
</section>
<section id="practical-cautions" class="level1">
<h1>7. Practical cautions</h1>
<p>These patterns are powerful, but they work best when the mapping rules are stable and owned by the analysis team. A few guardrails help:</p>
<ul>
<li>keep the format definition close to the analysis spec</li>
<li>prefer a named format for rules reused across tables and datasets</li>
<li>use <code>fclear()</code> in examples and tests to avoid leaking state between steps</li>
<li>use <code>na_as_string = TRUE</code> only when the key was built with literal <code>"NA"</code> components from <code>paste()</code></li>
</ul>
</section>
<section id="fparse-syntax-for-all-format-families" class="level1">
<h1>8. <code>fparse()</code> syntax for all format families</h1>
<p>If you want to express <code>fnew()</code>-style rules as text, <code>fparse()</code> supports the same VALUE/INVALUE families as the package parser. The main idea is:</p>
<ul>
<li>use <code>VALUE</code> for forward lookup formats</li>
<li>use <code>INVALUE</code> for reverse lookup formats</li>
<li>use <code>pattern = ...</code> only for date/time/datetime formats</li>
<li>use <code>pattern: ...</code> in the VALUE header for numeric display patterns</li>
<li>use interval syntax for numeric, date, datetime, and stratified ranges</li>
</ul>
<section id="value-blocks-for-discrete-lookup" class="level2">
<h2 class="anchored" data-anchor-id="value-blocks-for-discrete-lookup">VALUE blocks for discrete lookup</h2>
<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;">fparse</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">text =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span></span>
<span id="cb17-2"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">VALUE sex (character)</span></span>
<span id="cb17-3"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">  "M" = "Male"</span></span>
<span id="cb17-4"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">  "F" = "Female"</span></span>
<span id="cb17-5"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">  .missing = "Unknown"</span></span>
<span id="cb17-6"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">  .other = "Other"</span></span>
<span id="cb17-7"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb17-8"></span>
<span id="cb17-9"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">VALUE age_group (numeric)</span></span>
<span id="cb17-10"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">  [0, 18)    = "Child"</span></span>
<span id="cb17-11"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">  [18, 65)   = "Adult"</span></span>
<span id="cb17-12"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">  [65, HIGH] = "Senior"</span></span>
<span id="cb17-13"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb17-14"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span>)</span></code></pre></div></div>
</div>
</section>
<section id="invalue-blocks-for-reverse-lookup" class="level2">
<h2 class="anchored" data-anchor-id="invalue-blocks-for-reverse-lookup">INVALUE blocks for reverse lookup</h2>
<div class="cell">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb18" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb18-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">fparse</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">text =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span></span>
<span id="cb18-2"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">INVALUE sex_inv</span></span>
<span id="cb18-3"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">  "Male" = "M"</span></span>
<span id="cb18-4"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">  "Female" = "F"</span></span>
<span id="cb18-5"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">  .missing = "U"</span></span>
<span id="cb18-6"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb18-7"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span>)</span></code></pre></div></div>
</div>
</section>
<section id="date-time-and-datetime-patterns" class="level2">
<h2 class="anchored" data-anchor-id="date-time-and-datetime-patterns">Date, time, and datetime patterns</h2>
<p>This is the direct <code>fparse()</code> equivalent of <code>fnew_date()</code>. For these blocks, <code>pattern = ...</code> is the right way to specify the display format.</p>
<div class="cell">
<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;">fparse</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">text =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span></span>
<span id="cb19-2"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">VALUE enrldt (date)</span></span>
<span id="cb19-3"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">  pattern = "DATE9."</span></span>
<span id="cb19-4"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">  .missing = "Not Enrolled"</span></span>
<span id="cb19-5"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb19-6"></span>
<span id="cb19-7"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">VALUE visit_time (time)</span></span>
<span id="cb19-8"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">  pattern = "TIME8."</span></span>
<span id="cb19-9"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb19-10"></span>
<span id="cb19-11"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">VALUE stamp (datetime)</span></span>
<span id="cb19-12"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">  pattern = "DATETIME20."</span></span>
<span id="cb19-13"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb19-14"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span>)</span></code></pre></div></div>
</div>
</section>
<section id="numeric-display-patterns" class="level2">
<h2 class="anchored" data-anchor-id="numeric-display-patterns">Numeric display patterns</h2>
<p>Numeric display formatting now has its own parser syntax. Put the pattern in the VALUE header and keep the block otherwise empty except for optional <code>.missing</code> / <code>.other</code> directives.</p>
<div class="cell">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb20" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb20-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">fparse</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">text =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span></span>
<span id="cb20-2"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">VALUE currency (numeric, pattern: "$%,.2f")</span></span>
<span id="cb20-3"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">  .missing = "NO DATA"</span></span>
<span id="cb20-4"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb20-5"></span>
<span id="cb20-6"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">VALUE pct (numeric, pattern: "%.1f%%")</span></span>
<span id="cb20-7"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb20-8"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span>)</span>
<span id="cb20-9"></span>
<span id="cb20-10"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">tibble</span>(</span>
<span id="cb20-11">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">raw =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1234.56</span>, <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">7890.12</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">NA</span>),</span>
<span id="cb20-12">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">currency =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">fputn</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1234.56</span>, <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">7890.12</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</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;">"currency"</span>),</span>
<span id="cb20-13">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">pct =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">fputn</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">12.3</span>, <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">4.5</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;">"pct"</span>)</span>
<span id="cb20-14">)</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code># A tibble: 4 × 3
     raw currency   pct  
   &lt;dbl&gt; &lt;chr&gt;      &lt;chr&gt;
1  1235. $1,234.56  0.0% 
2 -7890. -$7,890.12 12.3%
3     0  $0.00      -4.5%
4    NA  NO DATA    &lt;NA&gt; </code></pre>
</div>
</div>
</section>
<section id="range-formats" class="level2">
<h2 class="anchored" data-anchor-id="range-formats">Range formats</h2>
<p>Range formats are expressed with interval notation. The same syntax works for numeric, <code>date_range</code>, and <code>datetime_range</code> blocks.</p>
<div class="cell">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb22" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb22-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">fparse</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">text =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span></span>
<span id="cb22-2"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">VALUE study_period (date_range)</span></span>
<span id="cb22-3"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">  [2024-01-01, 2024-02-01) = "Screening"</span></span>
<span id="cb22-4"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">  [2024-02-01, 2024-06-01) = "Treatment"</span></span>
<span id="cb22-5"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">  [2024-06-01, HIGH]       = "Follow-up"</span></span>
<span id="cb22-6"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb22-7"></span>
<span id="cb22-8"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">VALUE shift (datetime_range)</span></span>
<span id="cb22-9"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">  [2024-01-15 00:00, 2024-01-15 08:00) = "Night"</span></span>
<span id="cb22-10"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">  [2024-01-15 08:00, 2024-01-15 16:00) = "Day"</span></span>
<span id="cb22-11"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">  [2024-01-15 16:00, 2024-01-16 00:00) = "Evening"</span></span>
<span id="cb22-12"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb22-13"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span>)</span></code></pre></div></div>
</div>
</section>
<section id="stratified-range-formats" class="level2">
<h2 class="anchored" data-anchor-id="stratified-range-formats">Stratified range formats</h2>
<p><code>stratified_range</code> combines a stratum with an inner range. The parser accepts the friendly <code>STRATUM|[low, high)</code> form.</p>
<div class="cell">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb23" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb23-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">fparse</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">text =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span></span>
<span id="cb23-2"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">VALUE visit_window (stratified_range, range_subtype: numeric)</span></span>
<span id="cb23-3"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">  "ARM_A"|[0, 7)     = "Baseline"</span></span>
<span id="cb23-4"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">  "ARM_A"|[7, 28)    = "Wk1-3"</span></span>
<span id="cb23-5"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">  "ARM_B"|[0, 14)    = "Baseline"</span></span>
<span id="cb23-6"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">  .other              = "Outside"</span></span>
<span id="cb23-7"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb23-8"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span>)</span></code></pre></div></div>
</div>
</section>
<section id="when-to-use-fnew-anyway" class="level2">
<h2 class="anchored" data-anchor-id="when-to-use-fnew-anyway">When to use <code>fnew()</code> anyway</h2>
<p><code>fnew()</code> remains the most concise way to create a report-formatting object when you already know you want a display pattern. <code>fparse()</code> is useful when the rule needs to be stored as text, versioned in a spec, or generated from another tool.</p>
<div class="cell">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb24" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb24-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">fnew</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"$%,.2f"</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">type =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"numeric"</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">name =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"currency_direct"</span>)</span>
<span id="cb24-2"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">fputn</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1234.56</span>, <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">7890.12</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>), <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"currency_direct"</span>)</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>[1] "$1,234.56"  "-$7,890.12" "$0.00"     </code></pre>
</div>
</div>
</section>
</section>
<section id="conclusion" class="level1">
<h1>Conclusion</h1>
<p><code>ksformat</code> is not limited to simple code-to-label dictionaries. In clinical trials it can also serve as a compact rule engine for visit windows, composite keys, reverse mappings, report formatting, and small narrative fragments. That makes it useful anywhere repeated conditional logic would otherwise be spread across scripts, spreadsheets, or one-off helper functions.</p>
<div class="cell">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb26" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb26-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">fclear</span>()</span></code></pre></div></div>
<div class="cell-output cell-output-stderr">
<pre><code>All formats cleared from library.</code></pre>
</div>
</div>
<hr>
<pre><code>Larchenko V, Aleschenkov I (2026). _ksformat: 'SAS'-Style 'PROC FORMAT'   for R_. R package version 0.8.3, &lt;https://github.com/crow16384/ksformat&gt;.</code></pre>
<p><em>This post was originally published on the KeyStat Solutions R Technical Blog. <a href="https://www.r-bloggers.com">Visit R-Bloggers</a> to discover more R content.</em></p>


</section>

 ]]></description>
  <category>R</category>
  <category>ksformat</category>
  <category>clinical trial</category>
  <category>r-package</category>
  <category>SAS-format</category>
  <guid>https://al-garik.github.io/ks-blog/posts/2026-07-09-non-standard-applications-of-ksformat/</guid>
  <pubDate>Wed, 08 Jul 2026 21:00:00 GMT</pubDate>
  <media:content url="https://al-garik.github.io/ks-blog/posts/2026-07-09-non-standard-applications-of-ksformat/images/post-logo.png" medium="image" type="image/png" height="72" width="144"/>
</item>
<item>
  <title>Getting Current R-script name in R automatically</title>
  <dc:creator>Igor Aleschenkov (KeyStat Solutions)</dc:creator>
  <link>https://al-garik.github.io/ks-blog/posts/2026-07-09-getting-current-script-name-in-r/</link>
  <description><![CDATA[ 




<p>When generating clinical reports, it’s often useful to know <strong>which analysis script produced the output</strong>. The script name can be included in report headers, footers, log files, or metadata to improve traceability and simplify debugging.</p>
<p>Many reporting frameworks require manually specifying the program name:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb1" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb1-1">program <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;">"t_14_01_01.R"</span></span></code></pre></div></div>
<p>The obvious downside is that this information must be updated whenever the script is renamed, which is easy to forget.</p>
<p>A better solution is to determine the script name automatically.</p>
<p>The function below detects the currently executing script in the two most common execution modes:</p>
<ul>
<li>when the script is executed via <code>source()</code>;</li>
<li>when the script is executed with <code>Rscript</code> (or <code>R --file</code>).</li>
</ul>
<div class="cell">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb2" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb2-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Returns the name of the currently executing R script.</span></span>
<span id="cb2-2"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">#</span></span>
<span id="cb2-3"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># The function works in two situations:</span></span>
<span id="cb2-4"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">#   1. When the script is executed via source()</span></span>
<span id="cb2-5"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">#   2. When the script is executed from the command line with Rscript</span></span>
<span id="cb2-6"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">#</span></span>
<span id="cb2-7"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># If neither method can determine the script name (e.g. interactive console),</span></span>
<span id="cb2-8"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># an empty string is returned.</span></span>
<span id="cb2-9">current_script_name <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">function</span>()</span>
<span id="cb2-10">{</span>
<span id="cb2-11">  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">#---------------------------------------------------------------------------</span></span>
<span id="cb2-12">  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Returns the current call stack together with corresponding environments.</span></span>
<span id="cb2-13">  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Each stack element contains:</span></span>
<span id="cb2-14">  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">#   - fn_name : name of the called function</span></span>
<span id="cb2-15">  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">#   - env     : execution environment of that call</span></span>
<span id="cb2-16">  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">#---------------------------------------------------------------------------</span></span>
<span id="cb2-17">  .get_stack <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">function</span>() {</span>
<span id="cb2-18">    stack <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;">sys.calls</span>()</span>
<span id="cb2-19">    envs  <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;">sys.frames</span>()</span>
<span id="cb2-20"></span>
<span id="cb2-21">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Remove the current function itself and reverse the order so the most</span></span>
<span id="cb2-22">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># recent calls are inspected first.</span></span>
<span id="cb2-23">    stack <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;">rev</span>(stack[<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">length</span>(stack)])</span>
<span id="cb2-24">    envs  <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;">rev</span>(envs[<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">length</span>(envs)])</span>
<span id="cb2-25"></span>
<span id="cb2-26">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> (<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">length</span>(stack) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>L)</span>
<span id="cb2-27">      <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">return</span>(<span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">NULL</span>)</span>
<span id="cb2-28"></span>
<span id="cb2-29">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">Map</span>(</span>
<span id="cb2-30">      <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">function</span>(call, env)</span>
<span id="cb2-31">        <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">list</span>(</span>
<span id="cb2-32">          <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">fn_name =</span> rlang<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">call_name</span>(call),</span>
<span id="cb2-33">          <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">env =</span> env</span>
<span id="cb2-34">        ),</span>
<span id="cb2-35">      stack,</span>
<span id="cb2-36">      envs</span>
<span id="cb2-37">    )</span>
<span id="cb2-38">  }</span>
<span id="cb2-39"></span>
<span id="cb2-40">  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">#---------------------------------------------------------------------------</span></span>
<span id="cb2-41">  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Searches the call stack for the closest source() call.</span></span>
<span id="cb2-42">  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">#</span></span>
<span id="cb2-43">  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># When source() executes a script, its execution environment contains</span></span>
<span id="cb2-44">  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># the filename used for sourcing.</span></span>
<span id="cb2-45">  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">#---------------------------------------------------------------------------</span></span>
<span id="cb2-46">  .closest_source_frame <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">function</span>() {</span>
<span id="cb2-47">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">Find</span>(</span>
<span id="cb2-48">      <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">function</span>(f)</span>
<span id="cb2-49">        <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">!</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">is.null</span>(f<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>fn_name) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;&amp;</span></span>
<span id="cb2-50">        f<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>fn_name <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"source"</span>,</span>
<span id="cb2-51">      <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">.get_stack</span>()</span>
<span id="cb2-52">    )</span>
<span id="cb2-53">  }</span>
<span id="cb2-54"></span>
<span id="cb2-55">  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">#---------------------------------------------------------------------------</span></span>
<span id="cb2-56">  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Returns the filename of the sourced script.</span></span>
<span id="cb2-57">  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Returns NULL if the script was not started via source().</span></span>
<span id="cb2-58">  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">#---------------------------------------------------------------------------</span></span>
<span id="cb2-59">  .current_source_filename <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">function</span>() {</span>
<span id="cb2-60">    frame <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;">.closest_source_frame</span>()</span>
<span id="cb2-61"></span>
<span id="cb2-62">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> (<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">is.null</span>(frame))</span>
<span id="cb2-63">      <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">NULL</span></span>
<span id="cb2-64">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">else</span></span>
<span id="cb2-65">      frame<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>env<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>filename</span>
<span id="cb2-66">  }</span>
<span id="cb2-67"></span>
<span id="cb2-68">  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">#---------------------------------------------------------------------------</span></span>
<span id="cb2-69">  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Returns the script filename when executed with:</span></span>
<span id="cb2-70">  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">#</span></span>
<span id="cb2-71">  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">#   Rscript myscript.R</span></span>
<span id="cb2-72">  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">#</span></span>
<span id="cb2-73">  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># or</span></span>
<span id="cb2-74">  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">#</span></span>
<span id="cb2-75">  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">#   R --file=myscript.R</span></span>
<span id="cb2-76">  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">#</span></span>
<span id="cb2-77">  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># by inspecting command line arguments.</span></span>
<span id="cb2-78">  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">#---------------------------------------------------------------------------</span></span>
<span id="cb2-79">  .current_cli_filename <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">function</span>() {</span>
<span id="cb2-80"></span>
<span id="cb2-81">    args <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;">rev</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">commandArgs</span>(<span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">FALSE</span>))</span>
<span id="cb2-82"></span>
<span id="cb2-83">    file_index <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;">grep</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"^(--file=|-f$)"</span>, args)[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>L]</span>
<span id="cb2-84"></span>
<span id="cb2-85">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> (<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">is.na</span>(file_index)) {</span>
<span id="cb2-86"></span>
<span id="cb2-87">      <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">NULL</span></span>
<span id="cb2-88"></span>
<span id="cb2-89">    } <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">else</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> (args[file_index] <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"-f"</span>) {</span>
<span id="cb2-90"></span>
<span id="cb2-91">      args[file_index <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>L]</span>
<span id="cb2-92"></span>
<span id="cb2-93">    } <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">else</span> {</span>
<span id="cb2-94"></span>
<span id="cb2-95">      <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">sub</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"^--file="</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">""</span>, args[file_index])</span>
<span id="cb2-96"></span>
<span id="cb2-97">    }</span>
<span id="cb2-98">  }</span>
<span id="cb2-99"></span>
<span id="cb2-100">  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">#---------------------------------------------------------------------------</span></span>
<span id="cb2-101">  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Try to determine the filename from source() first.</span></span>
<span id="cb2-102">  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">#---------------------------------------------------------------------------</span></span>
<span id="cb2-103">  src <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;">.current_source_filename</span>()</span>
<span id="cb2-104"></span>
<span id="cb2-105">  <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> (<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">!</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">is.null</span>(src))</span>
<span id="cb2-106">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">return</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">basename</span>(src))</span>
<span id="cb2-107"></span>
<span id="cb2-108">  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">#---------------------------------------------------------------------------</span></span>
<span id="cb2-109">  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Otherwise try command line execution.</span></span>
<span id="cb2-110">  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">#---------------------------------------------------------------------------</span></span>
<span id="cb2-111">  cli <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;">.current_cli_filename</span>()</span>
<span id="cb2-112"></span>
<span id="cb2-113">  <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> (<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">!</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">is.null</span>(cli))</span>
<span id="cb2-114">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">return</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">basename</span>(cli))</span>
<span id="cb2-115"></span>
<span id="cb2-116">  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Could not determine the script name.</span></span>
<span id="cb2-117">  <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">""</span></span>
<span id="cb2-118">}</span></code></pre></div></div>
</div>
<p>Internally, it first inspects the call stack looking for a <code>source()</code> frame, where R stores the filename. If no such frame exists, it falls back to examining the command-line arguments supplied to the R process.</p>
<p>This makes the function suitable for both interactive development and automated production workflows.</p>
<p>Using it is straightforward:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" 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;">current_script_name</span>()</span>
<span id="cb3-2"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># [1] "t_14_01_01.R"</span></span></code></pre></div></div>
<p>For example:</p>
<div class="cell">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb4" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb4-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">source</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">file.path</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">getwd</span>(), <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'output'</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'the_test_script.R'</span>))</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>The current script is:  the_test_script.R</code></pre>
</div>
</div>
<p>In a clinical reporting environment, the returned filename can be used in several places:</p>
<ul>
<li>document headers and footers;</li>
<li>report metadata;</li>
<li>audit logs;</li>
<li>QC comparison reports;</li>
<li>execution logs generated by batch processes.</li>
</ul>
<p>Because the program name is obtained automatically, there is no risk of documentation becoming inconsistent after a script is renamed. It is one less manual step to remember, making reporting workflows slightly more robust and easier to maintain.</p>
<p>Although the implementation is compact, it provides a convenient building block for reproducible clinical reporting, where every generated output should clearly identify the program that created it.</p>
<hr>
<p><em>This post was originally published on the KeyStat Solutions R Technical Blog. <a href="https://www.r-bloggers.com">Visit R-Bloggers</a> to discover more R content.</em></p>



 ]]></description>
  <category>R</category>
  <category>Tips</category>
  <category>Scripts</category>
  <category>Clinical Programming</category>
  <guid>https://al-garik.github.io/ks-blog/posts/2026-07-09-getting-current-script-name-in-r/</guid>
  <pubDate>Wed, 08 Jul 2026 21:00:00 GMT</pubDate>
  <media:content url="https://al-garik.github.io/ks-blog/posts/2026-07-09-getting-current-script-name-in-r/images/post-logo.png" medium="image" type="image/png" height="58" width="144"/>
</item>
<item>
  <title>Getting Started with ksTFL: Creating Your First Clinical Table</title>
  <dc:creator>Igor Aleschenkov (KeyStat Solutions)</dc:creator>
  <link>https://al-garik.github.io/ks-blog/posts/2026-07-06-getting-started-ks-tfl/</link>
  <description><![CDATA[ 




<section id="introduction" class="level2">
<h2 class="anchored" data-anchor-id="introduction">Introduction</h2>
<p>Creating clinical trial tables, figures, and listings is one of the most time-consuming tasks in clinical statistical programming. The <a href="https://crow16384.r-universe.dev/ksTFL">ksTFL R Package</a> was designed to make this process faster, more reliable, and more enjoyable.</p>
<p>In this post, we’ll walk through the basics of ksTFL and create your first clinical table.</p>
</section>
<section id="why-kstfl" class="level2">
<h2 class="anchored" data-anchor-id="why-kstfl">Why ksTFL?</h2>
<p>Clinical trial deliverables require:</p>
<ul>
<li>✅ Professional formatting and alignment with regulatory standards</li>
<li>✅ Reproducible, auditable code</li>
<li>✅ Traceability of the data throughout the analysis pipeline</li>
<li>✅ Submission-ready output without manual refinement</li>
</ul>
<p>Without a specialized tool, generating submission-ready tables and figures from R can require significant time—sometimes more than the time spent on statistical calculations and modeling itself.</p>
</section>
<section id="installation" class="level2">
<h2 class="anchored" data-anchor-id="installation">Installation</h2>
<p>Install ksTFL from r-universe:</p>
</section>
<section id="your-first-table" class="level2">
<h2 class="anchored" data-anchor-id="your-first-table">Your First Table</h2>
<p>Let’s create a simple demographic summary table using sample data:</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="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Use built-in mtcars dataset for simplicity</span></span>
<span id="cb1-2">spec <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;">create_table</span>(mtcars, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">cols =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(cyl, mpg, hp, wt)) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb1-3">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">add_title</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Motor Trend Car Road Tests"</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">styleRef =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"i"</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb1-4">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">add_title</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Performance Metrics by Cylinder Count"</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">styleRef =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"i"</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb1-5">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">add_footnote</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Source: 1974 Motor Trend US magazine"</span>)</span>
<span id="cb1-6"></span>
<span id="cb1-7"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Define columns with labels and styling</span></span>
<span id="cb1-8">spec <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> spec <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb1-9">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">define_cols</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(mpg, hp, wt), </span>
<span id="cb1-10">              <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">label =</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;">"Miles/(US) gallon"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Horsepower"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Weight&lt;br&gt;(1000 lbs)"</span>),</span>
<span id="cb1-11">              <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">valueStyleRef =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"ac"</span>  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># align center</span></span>
<span id="cb1-12">              ) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb1-13">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">define_cols</span>(cyl, </span>
<span id="cb1-14">                        <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">label =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"N of Cylinders"</span>,</span>
<span id="cb1-15">              <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">dedupe =</span> T) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb1-16">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">set_document</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">contentWidth =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"60%"</span>)</span>
<span id="cb1-17"></span>
<span id="cb1-18"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Create report and render to DOCX</span></span>
<span id="cb1-19">report <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;">create_report</span>(spec)</span>
<span id="cb1-20"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">write_doc</span>(report, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">name =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"demo_table"</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">outDir =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"output"</span>)</span></code></pre></div></div>
</div>
<section id="whats-happening" class="level3">
<h3 class="anchored" data-anchor-id="whats-happening">What’s Happening?</h3>
<ol type="1">
<li><strong><code>create_table(data, cols = ...)</code></strong> - Initialize the table with selected columns</li>
<li><strong><code>add_title()</code>, <code>add_footnote()</code></strong> - Add documentation and annotations</li>
<li><strong><code>define_cols()</code></strong> - Configure column properties (labels, styling, visibility, deduplication, etc.)</li>
<li><strong><code>create_report()</code></strong> - Assemble the table specification</li>
<li><strong><code>write_doc()</code></strong> - Render to a professional DOCX document</li>
</ol>
<p>With just a few lines of code, ksTFL generates a well-formatted MS Word DOCX document:</p>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="images/simple_demog.png" class="lightbox" data-gallery="quarto-lightbox-gallery-1"><img src="https://al-garik.github.io/ks-blog/posts/2026-07-06-getting-started-ks-tfl/images/simple_demog.png" class="img-fluid quarto-figure quarto-figure-center figure-img"></a></p>
</figure>
</div>
</section>
</section>
<section id="key-features" class="level2">
<h2 class="anchored" data-anchor-id="key-features">Key Features</h2>
<section id="declarative-styling" class="level3">
<h3 class="anchored" data-anchor-id="declarative-styling">Declarative Styling</h3>
<p>Apply styles without modifying source data:</p>
<div class="cell">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb2" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb2-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Add conditional styling - highlight high horsepower</span></span>
<span id="cb2-2">spec <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> spec <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb2-3">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">compute_cols</span>(hp <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">180</span>, </span>
<span id="cb2-4">               <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c_style</span>(hp, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">styleRef =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"fc_red"</span>))  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># font color red</span></span></code></pre></div></div>
</div>
<p>The ksTFL package includes many pre-defined atomic styles, but custom styles can also be created using the <code>add_style()</code> function.</p>
</section>
<section id="spanning-headers" class="level3">
<h3 class="anchored" data-anchor-id="spanning-headers">Spanning Headers</h3>
<p>Create multi-column group headers:</p>
<div class="cell">
<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">spec <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> spec <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb3-2">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">add_span_header</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">cols =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(mpg, hp, wt), </span>
<span id="cb3-3">                  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">label =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Performance Metrics"</span>)</span></code></pre></div></div>
</div>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="images/styles1.png" class="lightbox" data-gallery="quarto-lightbox-gallery-2"><img src="https://al-garik.github.io/ks-blog/posts/2026-07-06-getting-started-ks-tfl/images/styles1.png" class="img-fluid quarto-figure quarto-figure-center figure-img"></a></p>
</figure>
</div>
</section>
<section id="flexible-column-selection" class="level3">
<h3 class="anchored" data-anchor-id="flexible-column-selection">Flexible Column Selection</h3>
<p>Use tidyselect helpers for column selection:</p>
<div class="cell">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb4" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb4-1">spec <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb4-2">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">define_cols</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">starts_with</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"m"</span>), </span>
<span id="cb4-3">              <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">valueStyleRef =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"ar"</span>)  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># right align</span></span></code></pre></div></div>
</div>
</section>
<section id="built-in-style-atoms" class="level3">
<h3 class="anchored" data-anchor-id="built-in-style-atoms">Built-in Style Atoms</h3>
<p>Combine predefined styles for quick formatting:</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"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Combine multiple style attributes</span></span>
<span id="cb5-2">spec <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;">add_title</span>(spec, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Summary"</span>, </span>
<span id="cb5-3">                  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">styleRef =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">f_combine</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"i"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"b"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"fc_navy"</span>))</span></code></pre></div></div>
</div>
</section>
</section>
<section id="complete-example-demographics-table" class="level2">
<h2 class="anchored" data-anchor-id="complete-example-demographics-table">Complete Example: Demographics Table</h2>
<p>Let’s build a submission-ready demographics table.</p>
<p>Since this article focuses on ksTFL’s rendering capabilities, the statistical calculations and data preparation are handled upstream. ksTFL does not calculate statistics by itself; rather, it transforms pre-calculated summary tables into publication-ready documents. In production code, statisticians prepare the summary data in a planar format, and ksTFL handles the table layout and formatting.</p>
<p>Below, we use a simple function that generates a data frame with calculated statistics for Age, Sex, and Race:</p>
<div class="cell">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb6" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb6-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Simple function that generates the summary table</span></span>
<span id="cb6-2"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># that a statistical programmer typically creates from ADSL data</span></span>
<span id="cb6-3">generate_demography_summary <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">function</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">seed =</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1007</span>L) {</span>
<span id="cb6-4">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">set.seed</span>(seed)</span>
<span id="cb6-5">    </span>
<span id="cb6-6">    rnd_stat <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">function</span>(N) {</span>
<span id="cb6-7">        <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(</span>
<span id="cb6-8">            <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">sprintf</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"%.1f (%.1f)"</span>, <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">rnorm</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>L, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">48</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>), <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">rnorm</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>L, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">11</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>)),</span>
<span id="cb6-9">            <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">sprintf</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"%.1f"</span>, <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">rnorm</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>L, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">49</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>)),</span>
<span id="cb6-10">            <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">sprintf</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"%d, %d"</span>, <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">sample</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">20</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">30</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>L), <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">sample</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">65</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">75</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>L)),</span>
<span id="cb6-11">            <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">sprintf</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"%d (%.1f%%)"</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">22</span>L, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">100</span> <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">22</span>L <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span> N),</span>
<span id="cb6-12">            <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">sprintf</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"%d (%.1f%%)"</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">20</span>L, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">100</span> <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">20</span>L <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span> N),</span>
<span id="cb6-13">            <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">sprintf</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"%d (%.1f%%)"</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">28</span>L, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">100</span> <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">28</span>L <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span> N),</span>
<span id="cb6-14">            <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">sprintf</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"%d (%.1f%%)"</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">9</span>L, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">100</span> <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">9</span>L <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span> N),</span>
<span id="cb6-15">            <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">sprintf</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"%d (%.1f%%)"</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span>L, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">100</span> <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span>L <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span> N)</span>
<span id="cb6-16">        )</span>
<span id="cb6-17">    }</span>
<span id="cb6-18">    </span>
<span id="cb6-19">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">data.frame</span>(</span>
<span id="cb6-20">        <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">PARAM =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">rep</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Age (years)"</span>,<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>), <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">rep</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Sex"</span>,<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>), <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">rep</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Race"</span>,<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>)),</span>
<span id="cb6-21">        <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">STATISTIC =</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;">"Mean (SD)"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Median"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Min, Max"</span>, </span>
<span id="cb6-22">                                    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Female"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Male"</span>, </span>
<span id="cb6-23">                                    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"White"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Asian"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Other"</span>),</span>
<span id="cb6-24">        <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">PLACEBO =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">rnd_stat</span>(placebo_n),</span>
<span id="cb6-25">        <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">DRUGA =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">rnd_stat</span>(drug_a_n),</span>
<span id="cb6-26">        <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">TOTAL =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">rnd_stat</span>(total_n),</span>
<span id="cb6-27">        <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">stringsAsFactors =</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">FALSE</span></span>
<span id="cb6-28">    )</span>
<span id="cb6-29">}</span></code></pre></div></div>
</div>
<p>With the inputs provided above, the generated data frame looks like this:</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">placebo_n <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">42</span>L</span>
<span id="cb7-2">drug_a_n <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">44</span>L</span>
<span id="cb7-3">total_n <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> placebo_n <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> drug_a_n</span>
<span id="cb7-4"></span>
<span id="cb7-5">table_data <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;">generate_demography_summary</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">seed =</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1007</span>L)</span>
<span id="cb7-6"></span>
<span id="cb7-7">table_data</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>        PARAM STATISTIC     PLACEBO      DRUGA       TOTAL
1 Age (years) Mean (SD) 49.0 (11.3) 48.6 (9.8) 51.6 (12.1)
2 Age (years)    Median        51.6       47.9        50.2
3 Age (years)  Min, Max      26, 68     20, 75      26, 69
4         Sex    Female  22 (52.4%) 22 (50.0%)  22 (25.6%)
5         Sex      Male  20 (47.6%) 20 (45.5%)  20 (23.3%)
6        Race     White  28 (66.7%) 28 (63.6%)  28 (32.6%)
7        Race     Asian   9 (21.4%)  9 (20.5%)   9 (10.5%)
8        Race     Other   5 (11.9%)  5 (11.4%)    5 (5.8%)</code></pre>
</div>
</div>
<p>Now let’s use ksTFL to transform this planar data frame into a submission-ready document:</p>
<div class="cell">
<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="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Initialize ksTFL table specification</span></span>
<span id="cb9-2">table_spec <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;">create_table</span>(table_data) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb9-3">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># PARAM is set to invisible because we use it as a category header.</span></span>
<span id="cb9-4">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># This keeps the table compact and maintains a professional appearance.</span></span>
<span id="cb9-5">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">define_cols</span>(PARAM, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">label =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Parameter"</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">isVisible =</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">FALSE</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb9-6">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># STATISTIC remains visible on every row because it distinguishes</span></span>
<span id="cb9-7">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># different statistics within each parameter block.</span></span>
<span id="cb9-8">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">define_cols</span>(STATISTIC, </span>
<span id="cb9-9">                    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">label =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Parameter&lt;br&gt;Statistic"</span>, </span>
<span id="cb9-10">                    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">valueStyleRef =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"indent_1"</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">labelStyleRef =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'al'</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb9-11">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Treatment columns follow the same display rules, so we define them together.</span></span>
<span id="cb9-12">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Although ksTFL calculates column widths automatically,</span></span>
<span id="cb9-13">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># we manually set them here to ensure consistent treatment column widths</span></span>
<span id="cb9-14">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># across the output for visual clarity and professional presentation.</span></span>
<span id="cb9-15">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">define_cols</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(PLACEBO, DRUGA, TOTAL),</span>
<span id="cb9-16">                            <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">label =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">paste0</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Placebo&lt;br&gt;(N="</span>, placebo_n,<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">')'</span>), </span>
<span id="cb9-17">                                                <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">paste0</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Drug A&lt;br&gt;(N="</span>, drug_a_n,<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">')'</span>), </span>
<span id="cb9-18">                                                <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">paste0</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Total&lt;br&gt;(N="</span>, total_n,<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">')'</span>)),</span>
<span id="cb9-19">                            <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">valueStyleRef =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"ac"</span>,</span>
<span id="cb9-20">                            <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">colWidth =</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;">"18%"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"18%"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"18%"</span>)</span>
<span id="cb9-21">    ) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb9-22">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">compute_cols</span>(</span>
<span id="cb9-23">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># The input data lacks units for categorical statistics;</span></span>
<span id="cb9-24">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># we add them dynamically here.</span></span>
<span id="cb9-25">        PARAM <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%in%</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;">'Sex'</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Race'</span>),</span>
<span id="cb9-26">        <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c_glue</span>(PARAM, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'after'</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">text=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">', n (%)'</span>)</span>
<span id="cb9-27">    ) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb9-28">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Use PARAM values as heading rows for better structure</span></span>
<span id="cb9-29">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">compute_cols</span>(</span>
<span id="cb9-30">        <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">firstOf</span>(PARAM),</span>
<span id="cb9-31">        <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c_addrow</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'above'</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">value_from =</span> PARAM, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">styleRef =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">f_combine</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'al'</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'b'</span>))</span>
<span id="cb9-32">    ) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb9-33">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Define titles, subtitles, and document headers/footers</span></span>
<span id="cb9-34">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">add_title</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Table 14.1 Demographic Summary"</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb9-35">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">add_subtitle</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"(Safety Population)"</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">styleRef =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'ac'</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb9-36">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">add_footnote</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Note: Values are presented as summary statistics prepared before the ksTFL stage."</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb9-37">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">add_header</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Example Study KSTFL-107"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"DEMOGRAPHY"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Page {PAGE} of {NUMPAGES}"</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb9-38">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">add_footer</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Basic summary table example"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">""</span>, <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">format</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">Sys.Date</span>(), <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"%Y-%m-%d"</span>)) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb9-39">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Demographic tables benefit from a moderate content width:</span></span>
<span id="cb9-40">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># narrow enough to keep treatment columns readable, but wide enough</span></span>
<span id="cb9-41">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># to avoid sparse layouts with few rows.</span></span>
<span id="cb9-42">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">set_document</span>(</span>
<span id="cb9-43">        <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">contentWidth =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"50%"</span>,</span>
<span id="cb9-44">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># ksTFL provides flexible control over footnote placement:</span></span>
<span id="cb9-45">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># "doc_footer" (in the Word footer below footer rows),</span></span>
<span id="cb9-46">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># "repeated" (under the table on every page), or</span></span>
<span id="cb9-47">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># "last_page" (under the table on the last page only)</span></span>
<span id="cb9-48">        <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">footnotePlace =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"doc_footer"</span> </span>
<span id="cb9-49">    )</span>
<span id="cb9-50"></span>
<span id="cb9-51"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Create report and render to DOCX</span></span>
<span id="cb9-52">report <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;">create_report</span>(table_spec)</span>
<span id="cb9-53"></span>
<span id="cb9-54"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">write_doc</span>(report, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">name =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"table_14_1"</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">outDir =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"output"</span>)</span></code></pre></div></div>
</div>
<p>With just a few lines of declarative code, the planar data frame transforms into a production-ready document:</p>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="images/table_14_1.png" class="lightbox" data-gallery="quarto-lightbox-gallery-3"><img src="https://al-garik.github.io/ks-blog/posts/2026-07-06-getting-started-ks-tfl/images/table_14_1.png" class="img-fluid quarto-figure quarto-figure-center figure-img"></a></p>
</figure>
</div>
<p>The key advantage of this approach is that the input data remains in a simple, planar format that is easy to validate and audit, without any embedded reporting artifacts or formatting logic.</p>
</section>
<section id="next-steps" class="level2">
<h2 class="anchored" data-anchor-id="next-steps">Next Steps</h2>
<p>Now that you understand the basics of ksTFL, you can:</p>
<p>- Explore the <a href="https://crow16384.github.io/ksTFL/">ksTFL Documentation</a> for advanced features</p>
<p>- Check out the <a href="https://github.com/al-garik/ksTFL-examples">GitHub Repository</a> for more real examples and scripts</p>
<p>- A LinkedIn Post <a href="https://www.linkedin.com/feed/update/urn:li:activity:7479853700828811264/?utm_source=share&amp;utm_medium=member_desktop&amp;rcm=ACoAAAUzuu4BEDY7577xOkwgYzheanx_vKn89pk">here</a> gives some additional context and background on the ksTFL package.</p>
<hr>
<p>Aleschenkov I, Larchenko V (2026). <em>ksTFL: Framework for Clinical Tables, Figures, and Listings</em>. R package version 0.11.9, <a href="https://crow16384.github.io/ksTFL/" class="uri">https://crow16384.github.io/ksTFL/</a> <a href="https://crow16384.r-universe.dev/ksTFL" class="uri">https://crow16384.r-universe.dev/ksTFL</a>.</p>
<p><em>This post was originally published on the KeyStat Solutions Technical Blog. <a href="https://www.r-bloggers.com">Visit R-Bloggers</a> to discover more R content.</em></p>


</section>

 ]]></description>
  <category>R</category>
  <category>ksTFL</category>
  <category>Clinical Programming</category>
  <guid>https://al-garik.github.io/ks-blog/posts/2026-07-06-getting-started-ks-tfl/</guid>
  <pubDate>Sun, 05 Jul 2026 21:00:00 GMT</pubDate>
  <media:content url="https://al-garik.github.io/ks-blog/posts/2026-07-06-getting-started-ks-tfl/images/post_logo.png" medium="image" type="image/png" height="47" width="144"/>
</item>
</channel>
</rss>
