EVOLUTION-MANAGER
Edit File: introducing-the-snakecase-package.html
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta charset="utf-8" /> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta name="generator" content="pandoc" /> <meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="author" content="Malte Grosser" /> <meta name="date" content="2019-05-25" /> <title>Introducing the snakecase package</title> <style type="text/css">code{white-space: pre;}</style> <style type="text/css" data-origin="pandoc"> a.sourceLine { display: inline-block; line-height: 1.25; } a.sourceLine { pointer-events: none; color: inherit; text-decoration: inherit; } a.sourceLine:empty { height: 1.2em; } .sourceCode { overflow: visible; } code.sourceCode { white-space: pre; position: relative; } div.sourceCode { margin: 1em 0; } pre.sourceCode { margin: 0; } @media screen { div.sourceCode { overflow: auto; } } @media print { code.sourceCode { white-space: pre-wrap; } a.sourceLine { text-indent: -1em; padding-left: 1em; } } pre.numberSource a.sourceLine { position: relative; left: -4em; } pre.numberSource a.sourceLine::before { content: attr(title); position: relative; left: -1em; text-align: right; vertical-align: baseline; border: none; pointer-events: all; display: inline-block; -webkit-touch-callout: none; -webkit-user-select: none; -khtml-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; padding: 0 4px; width: 4em; color: #aaaaaa; } pre.numberSource { margin-left: 3em; border-left: 1px solid #aaaaaa; padding-left: 4px; } div.sourceCode { } @media screen { a.sourceLine::before { text-decoration: underline; } } code span.al { color: #ff0000; font-weight: bold; } /* Alert */ code span.an { color: #60a0b0; font-weight: bold; font-style: italic; } /* Annotation */ code span.at { color: #7d9029; } /* Attribute */ code span.bn { color: #40a070; } /* BaseN */ code span.bu { } /* BuiltIn */ code span.cf { color: #007020; font-weight: bold; } /* ControlFlow */ code span.ch { color: #4070a0; } /* Char */ code span.cn { color: #880000; } /* Constant */ code span.co { color: #60a0b0; font-style: italic; } /* Comment */ code span.cv { color: #60a0b0; font-weight: bold; font-style: italic; } /* CommentVar */ code span.do { color: #ba2121; font-style: italic; } /* Documentation */ code span.dt { color: #902000; } /* DataType */ code span.dv { color: #40a070; } /* DecVal */ code span.er { color: #ff0000; font-weight: bold; } /* Error */ code span.ex { } /* Extension */ code span.fl { color: #40a070; } /* Float */ code span.fu { color: #06287e; } /* Function */ code span.im { } /* Import */ code span.in { color: #60a0b0; font-weight: bold; font-style: italic; } /* Information */ code span.kw { color: #007020; font-weight: bold; } /* Keyword */ code span.op { color: #666666; } /* Operator */ code span.ot { color: #007020; } /* Other */ code span.pp { color: #bc7a00; } /* Preprocessor */ code span.sc { color: #4070a0; } /* SpecialChar */ code span.ss { color: #bb6688; } /* SpecialString */ code span.st { color: #4070a0; } /* String */ code span.va { color: #19177c; } /* Variable */ code span.vs { color: #4070a0; } /* VerbatimString */ code span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */ </style> <script> // apply pandoc div.sourceCode style to pre.sourceCode instead (function() { var sheets = document.styleSheets; for (var i = 0; i < sheets.length; i++) { if (sheets[i].ownerNode.dataset["origin"] !== "pandoc") continue; try { var rules = sheets[i].cssRules; } catch (e) { continue; } for (var j = 0; j < rules.length; j++) { var rule = rules[j]; // check if there is a div.sourceCode rule if (rule.type !== rule.STYLE_RULE || rule.selectorText !== "div.sourceCode") continue; var style = rule.style.cssText; // check if color or background-color is set if (rule.style.color === '' || rule.style.backgroundColor === '') continue; // replace div.sourceCode by a pre.sourceCode rule sheets[i].deleteRule(j); sheets[i].insertRule('pre.sourceCode{' + style + '}', j); } } })(); </script> <style type="text/css">body { background-color: #fff; margin: 1em auto; max-width: 700px; overflow: visible; padding-left: 2em; padding-right: 2em; font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 14px; line-height: 1.35; } #header { text-align: center; } #TOC { clear: both; margin: 0 0 10px 10px; padding: 4px; width: 400px; border: 1px solid #CCCCCC; border-radius: 5px; background-color: #f6f6f6; font-size: 13px; line-height: 1.3; } #TOC .toctitle { font-weight: bold; font-size: 15px; margin-left: 5px; } #TOC ul { padding-left: 40px; margin-left: -1.5em; margin-top: 5px; margin-bottom: 5px; } #TOC ul ul { margin-left: -2em; } #TOC li { line-height: 16px; } table { margin: 1em auto; border-width: 1px; border-color: #DDDDDD; border-style: outset; border-collapse: collapse; } table th { border-width: 2px; padding: 5px; border-style: inset; } table td { border-width: 1px; border-style: inset; line-height: 18px; padding: 5px 5px; } table, table th, table td { border-left-style: none; border-right-style: none; } table thead, table tr.even { background-color: #f7f7f7; } p { margin: 0.5em 0; } blockquote { background-color: #f6f6f6; padding: 0.25em 0.75em; } hr { border-style: solid; border: none; border-top: 1px solid #777; margin: 28px 0; } dl { margin-left: 0; } dl dd { margin-bottom: 13px; margin-left: 13px; } dl dt { font-weight: bold; } ul { margin-top: 0; } ul li { list-style: circle outside; } ul ul { margin-bottom: 0; } pre, code { background-color: #f7f7f7; border-radius: 3px; color: #333; white-space: pre-wrap; } pre { border-radius: 3px; margin: 5px 0px 10px 0px; padding: 10px; } pre:not([class]) { background-color: #f7f7f7; } code { font-family: Consolas, Monaco, 'Courier New', monospace; font-size: 85%; } p > code, li > code { padding: 2px 0px; } div.figure { text-align: center; } img { background-color: #FFFFFF; padding: 2px; border: 1px solid #DDDDDD; border-radius: 3px; border: 1px solid #CCCCCC; margin: 0 5px; } h1 { margin-top: 0; font-size: 35px; line-height: 40px; } h2 { border-bottom: 4px solid #f7f7f7; padding-top: 10px; padding-bottom: 2px; font-size: 145%; } h3 { border-bottom: 2px solid #f7f7f7; padding-top: 10px; font-size: 120%; } h4 { border-bottom: 1px solid #f7f7f7; margin-left: 8px; font-size: 105%; } h5, h6 { border-bottom: 1px solid #ccc; font-size: 105%; } a { color: #0033dd; text-decoration: none; } a:hover { color: #6666ff; } a:visited { color: #800080; } a:visited:hover { color: #BB00BB; } a[href^="http:"] { text-decoration: underline; } a[href^="https:"] { text-decoration: underline; } code > span.kw { color: #555; font-weight: bold; } code > span.dt { color: #902000; } code > span.dv { color: #40a070; } code > span.bn { color: #d14; } code > span.fl { color: #d14; } code > span.ch { color: #d14; } code > span.st { color: #d14; } code > span.co { color: #888888; font-style: italic; } code > span.ot { color: #007020; } code > span.al { color: #ff0000; font-weight: bold; } code > span.fu { color: #900; font-weight: bold; } code > span.er { color: #a61717; background-color: #e3d2d2; } </style> </head> <body> <h1 class="title toc-ignore">Introducing the snakecase package</h1> <h4 class="author">Malte Grosser</h4> <h4 class="date">2019-05-25</h4> <p>There are many style guides out there which recommend specific naming conventions for programming languages. At 2017’s useR conference Rasmus Bååth showed quite impressively the variety of cases which even exist within base R in his talk <a href="https://www.youtube.com/watch?v=Pv5dfsHBBKE">“The current state of naming conventions in R”</a>.</p> <p>However, consistent style is not only about naming new objects.</p> <div id="import" class="section level2"> <h2>Import</h2> <p>When you do a data analysis, most of the data already exists and you import it from disk, an API or a database. Here is the first moment in your data analysis when you have to decide if you want to rename your data or leave it as it is.</p> <p>Let’s say you have some data named in any of the following conventions</p> <div class="sourceCode" id="cb1"><pre class="sourceCode r"><code class="sourceCode r"><a class="sourceLine" id="cb1-1" title="1">string <-<span class="st"> </span><span class="kw">c</span>(<span class="st">"lowerCamelCase"</span>, <span class="st">"ALL_CAPS"</span>, <span class="st">"IDontKNOWWhat_thisCASE_is"</span>)</a></code></pre></div> <p>You can now easily convert this string for example to snake case via</p> <div class="sourceCode" id="cb2"><pre class="sourceCode r"><code class="sourceCode r"><a class="sourceLine" id="cb2-1" title="1"><span class="kw">library</span>(snakecase)</a> <a class="sourceLine" id="cb2-2" title="2"><span class="kw">to_snake_case</span>(string)</a> <a class="sourceLine" id="cb2-3" title="3"><span class="co">#> [1] "lower_camel_case" "all_caps" </span></a> <a class="sourceLine" id="cb2-4" title="4"><span class="co">#> [3] "i_dont_know_what_this_case_is"</span></a></code></pre></div> </div> <div id="graphics" class="section level2"> <h2>Graphics</h2> <p>Whenever you want to construct a graphic and you don’t like your conventions to come up in it, you can easily convert strings to a more humanly readable output like</p> <div class="sourceCode" id="cb3"><pre class="sourceCode r"><code class="sourceCode r"><a class="sourceLine" id="cb3-1" title="1"><span class="kw">to_mixed_case</span>(string, <span class="dt">sep_out =</span> <span class="st">" "</span>)</a> <a class="sourceLine" id="cb3-2" title="2"><span class="co">#> [1] "lower Camel Case" "All Caps" </span></a> <a class="sourceLine" id="cb3-3" title="3"><span class="co">#> [3] "I Dont Know What this Case is"</span></a></code></pre></div> <p>You might have noticed the <code>sep_out</code> argument. This allows you to combine any case with any output separator to create other well known cases like</p> <div class="sourceCode" id="cb4"><pre class="sourceCode r"><code class="sourceCode r"><a class="sourceLine" id="cb4-1" title="1"><span class="kw">to_snake_case</span>(string, <span class="dt">sep_out =</span> <span class="st">"."</span>)</a> <a class="sourceLine" id="cb4-2" title="2"><span class="co">#> [1] "lower.camel.case" "all.caps" </span></a> <a class="sourceLine" id="cb4-3" title="3"><span class="co">#> [3] "i.dont.know.what.this.case.is"</span></a> <a class="sourceLine" id="cb4-4" title="4"><span class="kw">to_snake_case</span>(string, <span class="dt">sep_out =</span> <span class="st">"-"</span>)</a> <a class="sourceLine" id="cb4-5" title="5"><span class="co">#> [1] "lower-camel-case" "all-caps" </span></a> <a class="sourceLine" id="cb4-6" title="6"><span class="co">#> [3] "i-dont-know-what-this-case-is"</span></a></code></pre></div> <p>or completely new ones like</p> <div class="sourceCode" id="cb5"><pre class="sourceCode r"><code class="sourceCode r"><a class="sourceLine" id="cb5-1" title="1"><span class="kw">to_screaming_snake_case</span>(string, <span class="dt">sep_out =</span> <span class="st">"="</span>)</a> <a class="sourceLine" id="cb5-2" title="2"><span class="co">#> [1] "LOWER=CAMEL=CASE" "ALL=CAPS" </span></a> <a class="sourceLine" id="cb5-3" title="3"><span class="co">#> [3] "I=DONT=KNOW=WHAT=THIS=CASE=IS"</span></a></code></pre></div> </div> <div id="export" class="section level2"> <h2>Export</h2> <p>Finally, when you are done with your analysis and want to write data back into a .CSV file or your customers database, which has a camel case convention, you can just use</p> <div class="sourceCode" id="cb6"><pre class="sourceCode r"><code class="sourceCode r"><a class="sourceLine" id="cb6-1" title="1"><span class="kw">to_upper_camel_case</span>(string)</a> <a class="sourceLine" id="cb6-2" title="2"><span class="co">#> [1] "LowerCamelCase" "AllCaps" </span></a> <a class="sourceLine" id="cb6-3" title="3"><span class="co">#> [3] "IDontKnowWhatThisCaseIs"</span></a></code></pre></div> </div> <div id="further-information" class="section level2"> <h2>Further information</h2> <p>The snakecase package goes quite deep into the little quirks which arise in automatic case conversion. However, it is well tweaked, to handle almost every edge case in an intuitive and elegant manner.</p> <p>To get a complete overview of its functionality like other cases, handling of abbreviations, special input characters, different parsing options, transliterations and more, I recommend you to have a look into the quite extensive <a href="https://github.com/Tazinho/snakecase">readme on its github repository</a>.</p> <p>As the package is relatively small and basically consists of its workhorse function <code>to_any_case()</code>, I can also react quite fast on new <a href="https://github.com/Tazinho/snakecase/issues">issues</a>.</p> <p>And of course I <a href="https://twitter.com/malte_grosser">tweet</a> occasionally about new functionality.</p> <p>To round this up let me give you one advice about best practices: be aware that automatic case conversion depends on the input string and it is recommended to verify the results. Hence you might want to pipe them into <code>dput()</code> and hard-code name changes instead of blindly trusting the output</p> <div class="sourceCode" id="cb7"><pre class="sourceCode r"><code class="sourceCode r"><a class="sourceLine" id="cb7-1" title="1"><span class="kw">library</span>(magrittr)</a> <a class="sourceLine" id="cb7-2" title="2"><span class="kw">to_any_case</span>(<span class="kw">c</span>(<span class="st">"SomeBAdInput"</span>, <span class="st">"someGoodInput"</span>)) <span class="op">%>%</span><span class="st"> </span><span class="kw">dput</span>()</a> <a class="sourceLine" id="cb7-3" title="3"><span class="co">#> c("some_b_ad_input", "some_good_input")</span></a></code></pre></div> <p>Happy snakecasing everyone ;)</p> </div> <!-- dynamically load mathjax for compatibility with self-contained --> <script> (function () { var script = document.createElement("script"); script.type = "text/javascript"; script.src = "https://mathjax.rstudio.com/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"; document.getElementsByTagName("head")[0].appendChild(script); })(); </script> </body> </html>