<p><div><div><div><div data-width="100" data-show-faces="false" data-send="true" data-layout="button_count" data-height="21" data-href="https://www.r-bloggers.com/strung-out-on-string-ops-a-brief-comparison-of-stringi-and-stringr/"></div></div><div></div></div><div></div></div>
<div>
(This article was first published on <strong><a href="https://rud.is/b/2017/02/06/strung-out-on-string-ops-a-brief-comparison-of-stringi-and-stringr/"> R – rud.is</a></strong>, and kindly contributed to <a rel="nofollow" href="https://www.r-bloggers.com/">R-bloggers)</a> </div>
<p>I made a promise to someone that my next blog would be about <code>stringi</code> vs <code>stringr</code> and I intend to keep said promise.</p>
<p><code>stringr</code> and <code>stringi</code> do “string operations”: find, replace, match, extract, convert, transform, etc.</p>
<p>The <code>stringr</code> package is now part of the <code>tidyverse</code> and is 100% focused on string processing and is pretty much a wrapper package for <code>stringi</code>. The <code>stringi</code> package wraps chunks of the <a target="_blank" rel="nofollow" href="http://icu-project.org/apiref/icu4c/"><code>icu4c</code></a> library but the <code>stringi</code> API frmaing was actually based on the patterns in the <code>stringr</code> package API. <code>stringr</code> did not wrap <code>stringi</code> at the time but dows now and <code>stringi</code> strays a bit (on occasion) from string processing since the entire <code>icu4c</code> library is at it’s disposal. Confused? Good! There’s more!</p>
<p>The impetus for asking me to blog about this is that I’m known to say “<em>just use <code>stringi</code></em>” in situations where someone has taken a <code>stringr</code> “shortcut”. Let me explain why.</p>
<h3>Readers Digest</h3>
<p>First, you need to read pages 4-5 of <a target="_blank" rel="nofollow" href="https://cran.r-project.org/web/packages/stringi/stringi.pdf">the <code>stringi</code> manual</a> [PDF] and then the <a target="_blank" rel="nofollow" href="https://cran.r-project.org/web/packages/stringr/vignettes/stringr.html"><code>stringr</code> vignette</a>. I’m not duplicating the information on those pages. The TL;DR on them is:</p>
<ul>
<li>that <code>stringr</code> makes some (valid) assumptions about defaults for the <code>stringi</code> calls it wraps</li>
<li><code>stringr</code> is much easier to initially grok as it’s very focused and has far fewer functions</li>
<li>they both use <a target="_blank" rel="nofollow" href="http://userguide.icu-project.org/strings/regexp">ICU regular expressions</a></li>
<li><code>stringi</code> includes more than string processing and has far more total functions:</li>
</ul>
<p><a target="_blank" rel="nofollow" href="https://i2.wp.com/rud.is/b/wp-content/uploads/2017/02/ct-1.png?ssl=1"><img alt="" class="wp-image-4982" src="https://i2.wp.com/rud.is/b/wp-content/uploads/2017/02/ct-1.png?resize=456%2C143&ssl=1" data-recalc-dims="1"></a></p>
<p>As noted, <code>stringr</code> wraps <code>stringi</code> calls (for the most part) and some of the <code>stringr</code> functions reference more than one <code>stringi</code> function:</p>
<p><a target="_blank" rel="nofollow" href="https://i1.wp.com/rud.is/b/wp-content/uploads/2017/02/fun-1.png?ssl=1"><img alt="" class="wp-image-4983" src="https://i1.wp.com/rud.is/b/wp-content/uploads/2017/02/fun-1.png?resize=456%2C200&ssl=1" data-recalc-dims="1"></a></p>
<p>That’s my primary defense for “<em>just use <code>stringi</code></em>” — <code>stringr</code> “just uses” it and you are forced to install <code>stringi</code> on every system <code>stringr</code> is on, so why introduce another dependency into your code?</p>
<h3>All Wrapped Up</h3>
<p>These are the <code>stringr</code> functions with a 1:~1 correspondence to <code>stringi</code> functions:</p>
<pre><code>stri_c stri_conv stri_count stri_detect stri_dup stri_extract stri_extract_all stri_join stri_length stri_locate stri_locate_all stri_match stri_match_all stri_order stri_pad stri_replace stri_replace_all stri_replace_na stri_sort stri_split stri_split_fixed stri_sub stri_sub&lt;- stri_subset stri_trim stri_wrap
</code></pre>
<p>I used 1:~1 since at the heart of the string processing capabilities of both packages lies the concept of granular control of matching behaviour. Specifically, there are four modes (so it’s really 1:4?):</p>
<ul>
<li><strong>fixed</strong>: Compare literal bytes in the string. This is very fast, but not usually what you want for non-ASCII character sets</li>
<li><strong>coll</strong>: Compare strings respecting standard collation rules</li>
<li><strong>regex</strong>: The default. Uses ICU regular expressions</li>
<li><strong>boundary</strong>: Match boundaries between things</li>
</ul>
<p><code>stringr</code> has function modifiers around <code>pattern</code> to handle those whereas <code>stringi</code> requires explicit function calls. So, you’d do the following to replace a fixed char/byte sequence in each package:</p>
<ul>
<li><code>stri_replace_all_fixed(&quot;Lorem i.sum dolor sit amet, conse.tetur adipisicing elit.&quot;, &quot;.&quot;, &quot;#&quot;)</code></li>
<li><code>str_replace_all(&quot;Lorem i.sum dolor sit amet, conse.tetur adipisicing elit.&quot;, fixed(&quot;.&quot;), &quot;#&quot;)</code></li>
</ul>
<p>In that case there’s not much in the way of keystroke savings, but the default mode of <code>stringr</code> is to use regex replacement and you do save both an <code>i</code> and <code>_regex</code> for that but add one more function call in-between you and your goal. When you work with multi-gigabyte character structures (as I do), those milliseconds often add up. If keystrokes > milliseconds in your workflow, you may want to stick with <code>stringr</code>.</p>
<h3>Treasure Hunting in stringi</h3>
<p>If you take some time to look at what’s in <code>stringi</code> you’ll find quite a bit (I excluded the fixed/coll/reged/boundary versions for brevity):</p>
<p><img alt="" src="https://rud.is/dl/stringi.svg"></p>
<p>That’s an SVG, so zoom in as much as you need to to read it.</p>
<p>These are <code>stringi</code> <em>gems</em>:</p>
<ul>
<li><code>stri_stats_general</code> (stats abt a character vector)</li>
<li><code>stri_trans_totitle</code> (For When You Want Title Case)</li>
<li><code>stri_flatten</code> (<code>paste0</code> but better defaults)</li>
<li><code>stri_rand_strings</code> (random strings)</li>
<li><code>stri_rand_lipsum</code> (random Lorem Ipsum lines!)</li>
<li><code>stri_count_words</code>, <code>stri_extract_all_words</code>, <code>stri_extract_first_words</code>, <code>stri_extract_last_words</code></li>
</ul>
<p>Plus it has some helpful operators:</p>
<ul>
<li><code>%s!=%</code>, <code>%s!==%</code>, <code>%s+%</code>, <code>%s&lt;%</code>, <code>%s&lt;=%</code>, <code>%s==%</code>, <code>%s===% %s>%</code>, <code>%s>=%</code>, <code>%stri!=%</code>, <code>%stri!==%</code>, <code>%stri+%</code>, <code>%stri&lt;%</code>, <code>%stri&lt;=%</code>, <code>%stri==%</code>, <code>%stri===%</code>, <code>%stri>%</code>, <code>%stri>=%</code></li>
</ul>
<p>Of those, <code>%s+%</code> is ++handy for string concatenation.</p>
<p>Prior to <code>readr</code>, these were my go-to line/raw readers/writer: <code>stri_read_raw</code>, <code>stri_read_lines</code>, and <code>stri_write_lines</code>.</p>
<p>It also handles gnarly character encoding operations in a cross-platform, predictable manner.</p>
<h3>FIN</h3>
<p>To do a full comparison justice would have required writing a mini-book which is something I can’t spare cycles on, so my primary goals were to make sure folks knew <code>stringr</code> wrapped <code>stringi</code> and to show that <code>stringi</code> has much more to offer than you probably knew. If you start to get hooked on some of the more “fun” or utilitarian functions in <code>stringi</code> it’s probably worth switching to it. If string ops are ancillary operations to you and you normally work in regex-land, then you’re not missing out on anything and can save a few keystrokes here and there by using <code>stringr</code>.</p>
<p>Comments are extremely encouraged for this post as I’m curious if you know about <code>stringi</code> before and when/where/how you use it vs <code>stringr</code> (or, why you don’t).</p>
<p>
<div>
<div>To <strong>leave a comment</strong> for the author, please follow the link and comment on their blog: <strong><a href="https://rud.is/b/2017/02/06/strung-out-on-string-ops-a-brief-comparison-of-stringi-and-stringr/"> R – rud.is</a></strong>.</div>
<hr>
<a rel="nofollow" href="https://www.r-bloggers.com/">R-bloggers.com</a> offers <strong><a rel="nofollow" href="https://feedburner.google.com/fb/a/mailverify?uri=RBloggers">daily e-mail updates</a></strong> about <a title="The R Project for Statistical Computing" rel="nofollow" href="https://www.r-project.org/">R</a> news and <a title="R tutorials" rel="nofollow" href="https://www.r-bloggers.com/search/tutorial">tutorials</a> on topics such as: <a title="Data science" rel="nofollow" href="https://www.r-bloggers.com/search/data%20science">Data science</a>, <a title="Big Data" rel="nofollow" href="https://www.r-bloggers.com/search/Big%20Data">Big Data, <a title="R jobs" rel="nofollow" href="https://www.r-users.com/">R jobs</a>, visualization (<a title="ggplot and ggplot2 tutorials" rel="nofollow" href="https://www.r-bloggers.com/search/ggplot2">ggplot2</a>, <a title="Boxplots using lattice and ggplot2 tutorials" rel="nofollow" href="https://www.r-bloggers.com/search/boxplot">Boxplots</a>, <a title="Maps and gis" rel="nofollow" href="https://www.r-bloggers.com/search/map">maps</a>, <a title="Animation in R" rel="nofollow" href="https://www.r-bloggers.com/search/animation">animation</a>), programming (<a title="RStudio IDE for R" rel="nofollow" href="https://www.r-bloggers.com/search/RStudio">RStudio</a>, <a title="Sweave and literate programming" rel="nofollow" href="https://www.r-bloggers.com/search/sweave">Sweave</a>, <a title="LaTeX in R" rel="nofollow" href="https://www.r-bloggers.com/search/LaTeX">LaTeX</a>, <a title="SQL and databases" rel="nofollow" href="https://www.r-bloggers.com/search/SQL">SQL</a>, <a title="Eclipse IDE for R" rel="nofollow" href="https://www.r-bloggers.com/search/eclipse">Eclipse</a>, <a title="git and github, Version Control System" rel="nofollow" href="https://www.r-bloggers.com/search/git">git</a>, <a title="Large data in R using Hadoop" rel="nofollow" href="https://www.r-bloggers.com/search/hadoop">hadoop</a>, <a title="Web Scraping of google, facebook, yahoo, twitter and more using R" rel="nofollow" href="https://www.r-bloggers.com/search/Web+Scraping">Web Scraping</a>) statistics (<a title="Regressions and ANOVA analysis tutorials" rel="nofollow" href="https://www.r-bloggers.com/search/regression">regression</a>, <a title="principal component analysis tutorial" rel="nofollow" href="https://www.r-bloggers.com/search/PCA">PCA</a>, <a title="Time series" rel="nofollow" href="https://www.r-bloggers.com/search/time+series">time series</a>, <a title="finance trading" rel="nofollow" href="https://www.r-bloggers.com/search/trading">trading</a>) and more...
<img height="1" alt="" width="1" src="http://feeds.feedburner.com/~r/RBloggers/~4/Aa6C9P97_6Y"></a></div>