<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:media="http://search.yahoo.com/mrss/"><channel><title><![CDATA[Alisa Wazrak's Data Adventures]]></title><description><![CDATA[What is Data for, if Not to Play with?]]></description><link>https://wazrak.com/</link><image><url>https://wazrak.com/favicon.png</url><title>Alisa Wazrak&apos;s Data Adventures</title><link>https://wazrak.com/</link></image><generator>Ghost 5.33</generator><lastBuildDate>Sun, 05 Apr 2026 01:34:48 GMT</lastBuildDate><atom:link href="https://wazrak.com/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[Protect Your Code with Tests! Your First R Package Journey Continues]]></title><description><![CDATA[<p>Following the <a href="https://wazrak.com/making-a-simple-package-in-r-using-modern-tools/">first post I published about how to write your first R package using modern tools</a>, we continue our adventures with R packages and touch upon the topic of <em>writing tests</em>. Tests are essential to ensure your package is robust and that any modification you ever make has no</p>]]></description><link>https://wazrak.com/writing-tests-for-your-first-r-package/</link><guid isPermaLink="false">6495a76eb360d3000104574a</guid><dc:creator><![CDATA[Alisa Wazrak]]></dc:creator><pubDate>Fri, 23 Jun 2023 15:16:40 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1611558709798-e009c8fd7706?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDQ1fHxnbGFzc2VzfGVufDB8fHx8MTY4NzUzMTM0OXww&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" medium="image"/><content:encoded><![CDATA[<img src="https://images.unsplash.com/photo-1611558709798-e009c8fd7706?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDQ1fHxnbGFzc2VzfGVufDB8fHx8MTY4NzUzMTM0OXww&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" alt="Protect Your Code with Tests! Your First R Package Journey Continues"><p>Following the <a href="https://wazrak.com/making-a-simple-package-in-r-using-modern-tools/">first post I published about how to write your first R package using modern tools</a>, we continue our adventures with R packages and touch upon the topic of <em>writing tests</em>. Tests are essential to ensure your package is robust and that any modification you ever make has no impact on its key features.</p><!--kg-card-begin: markdown--><blockquote>
<p>Unit tests are like insurance. You hope you never have to use them, but you&apos;re glad you have them when you do.</p>
</blockquote>
<p><em>Martin Fowler</em></p>
<!--kg-card-end: markdown--><h2 id="why-write-tests">Why Write Tests?</h2><p>Writing tests is not the most exciting task. Most developers would rather spend time developing new features than new tests. But the more complex your code becomes, the more likely you will see bugs pop up everywhere. You can&apos;t plan to cover the whole surface of issues that can arise, and Unit Testing is the first thing that helps to ensure that independent parts of your code (typically, functions), behave as they should, even in corner cases.</p><h2 id="how-to-write-tests-in-the-context-of-a-r-package">How to write tests in the context of a R package?</h2><p>You&apos;ve come here for that!</p><p>Let&apos;s go back to our <a href="https://wazrak.com/making-a-simple-package-in-r-using-modern-tools/">packagedfun</a> package. It has a unique function that does not much right now:</p><pre><code class="language-R">#&apos; Saying Hello is polite
#&apos;
#&apos; @description
#&apos; `hello_fun` says hello and uses the name of the person as an argument.
#&apos;
#&apos; @importFrom glue glue
#&apos;
#&apos; @details
#&apos; This is a generic function that can be used to say hello/
#&apos;
#&apos; @param name the name of the person you want to send a Hello message to
#&apos; @export
hello_fun &lt;- function(name) {

  print(glue::glue(&quot;Hello {name}&quot;))

}</code></pre><p>First, we will make this function a little more elaborate, and do a few more things, such as:</p><ul><li>having a default name value if the function is run as is, without any parameter</li><li>refuse empty names if entered, by throwing an error</li><li>accept multiple names if given in the form of a vector of characters</li></ul><pre><code class="language-R">#&apos; Saying Hello is polite
#&apos;
#&apos; @description
#&apos; `hello_fun` says hello and uses the name of the person(s) as an argument. y
#&apos;
#&apos; @importFrom glue glue
#&apos;
#&apos; @details
#&apos; This is a generic function that can be used to say hello/
#&apos;
#&apos; @param name the name of the person(s) you want to send a Hello message to - you can enter a vector of names. By default is no name is entered, it takes the value of &quot;Person with no name&quot;
#&apos; @export
hello_fun &lt;- function(name=&quot;Person with no name&quot;) {

  if (length(name)==1) {
  if (is.na(name) | name==&quot;&quot;) {
    stop(&quot;I&apos;d like you to enter a name. not an empty string!&quot;)
  } else {
  return(glue::glue(&quot;Hello {name}&quot;))
  }
  }

  if (length(name)&gt;1) {
   names_string &lt;- paste(name,collapse=&quot; and &quot;)
   return(glue::glue(&quot;Hello {names_string}!&quot;))
  }
}</code></pre><p>Now that we can do several things with this function, let&apos;s write some tests for it. </p><p>Go into the main folder of your package, and create a folder called <em>tests</em> and inside that folder <em>testthat</em></p><p>In there, you can create one or several R files that will contain your tests. We will create a first file called <em>test-hello.R.</em></p><div class="kg-card kg-callout-card kg-callout-card-red"><div class="kg-callout-emoji">&#x1F4A1;</div><div class="kg-callout-text">Important! You need to give a name that starts with &quot;test&quot; for all your .R test files in the tests/testthat/ folder, otherwise they will not be recognized as such when trying to test your package.</div></div><p>Here&apos;s the first test we write for our function in test-hello.R:</p><pre><code class="language-R">test_that(&quot;Confirm that the function works with John&quot;, {
  expect_equal(hello_fun(name=&quot;John&quot;), &quot;Hello John&quot;)
})</code></pre><p>It&apos;s a positive test. We confirm that the function will be returning &quot;Hello John&quot; in case we give &quot;John&quot; as a parameter. Makes sense right? We use the expect_equal function from the testthat package, which will in its first argument secure a function call, and compare it with its second argument to confirm that they are identical.</p><p>You can then go in RStudio and hit to &quot;Test Package&quot; menu:</p><figure class="kg-card kg-image-card"><img src="https://wazrak.com/content/images/2023/06/image-10.png" class="kg-image" alt="Protect Your Code with Tests! Your First R Package Journey Continues" loading="lazy" width="281" height="340"></figure><p>You should see something showing up in the environment pane:</p><figure class="kg-card kg-image-card"><img src="https://wazrak.com/content/images/2023/06/image-11.png" class="kg-image" alt="Protect Your Code with Tests! Your First R Package Journey Continues" loading="lazy" width="555" height="176"></figure><p>The key info to pick up here is that <s>I am a</s> <s>coding rockstar</s> your test was successful, and there was only one of them coming from the &quot;hello&quot; test file.</p><p>Let&apos;s write a few more tests! This is now what I have in my tests/testthat/test-hello.R file: </p><pre><code class="language-R">test_that(&quot;Confirm that the function works with John&quot;, {
  expect_equal(hello_fun(name=&quot;John&quot;), &quot;Hello John&quot;)
})

test_that(&quot;Confirm that the function works when no parameter is given&quot;, {
  expect_equal(hello_fun(), &quot;Hello Person with no name&quot;)
})

test_that(&quot;Confirm that the function works when two names are given&quot;, {
  expect_equal(hello_fun(name=c(&quot;Joan&quot;,&quot;Liz&quot;)), &quot;Hello Joan and Liz!&quot;)
})

test_that(&quot;Confirm that the function returns an error when given an empty string&quot;, {
  expect_error(hello_fun(name=&quot;&quot;), &quot;I&apos;d like you to enter a name. not an empty string!&quot;)
})
</code></pre><p>The new thing that I introduced here is the <em>expect_error </em>function. It will not look for equality, but instead confirm that the execution was stopped, and that an error message was returned (and checks that it&apos;s the right one).</p><p>Let&apos;s hit the &quot;Test Package&quot; menu one more time.</p><figure class="kg-card kg-image-card"><img src="https://wazrak.com/content/images/2023/06/image-12.png" class="kg-image" alt="Protect Your Code with Tests! Your First R Package Journey Continues" loading="lazy" width="486" height="167"></figure><p>Good! We have now 4 tests, and all of them were passed. Are we done?</p><p>Let me add one more test!</p><pre><code class="language-R">test_that(&quot;Confirm that the function works when two names are given but one is empty&quot;, {
  expect_equal(hello_fun(name=c(&quot;Joan&quot;,&quot;&quot;)), &quot;Hello Joan&quot;)
})</code></pre><p>I would expect that the function ignores names that are empty... let&apos;s test one more time!</p><figure class="kg-card kg-image-card"><img src="https://wazrak.com/content/images/2023/06/image-13.png" class="kg-image" alt="Protect Your Code with Tests! Your First R Package Journey Continues" loading="lazy" width="671" height="344" srcset="https://wazrak.com/content/images/size/w600/2023/06/image-13.png 600w, https://wazrak.com/content/images/2023/06/image-13.png 671w"></figure><p>Ouch! Look like we met with our first failed test! Looking at my original code, it&apos;s not supposed to handle things this way, and will instead return something like &quot;Hello Joan and !&quot; if the second name is an empty string. </p><p>This is to show you that writing tests is not just about writing obvious statements like checking that 1+1=2, but rather checking expected behavior that should occur in fairly typical scenarios. </p><p>You may not always think about how to deal with empty values, NA values, or other strange things like -Inf or +Inf when dealing with numeric values.</p><p>Writing tests is about thinking what can go wrong. Considering &quot;what if...?&quot; stories. And checking if your code can handle them.</p><p>In the meantime, let&apos;s fix our function!</p><h2 id="whack-a-mole">Whack-a-Mole</h2><p>Fixing this issue? Just 1 minute work, I thought. Here&apos;s my fix:</p><pre><code>#&apos; Saying Hello is polite
#&apos;
#&apos; @description
#&apos; `hello_fun` says hello and uses the name of the person(s) as an argument. y
#&apos;
#&apos; @importFrom glue glue
#&apos;
#&apos; @details
#&apos; This is a generic function that can be used to say hello/
#&apos;
#&apos; @param name the name of the person(s) you want to send a Hello message to - you can enter a vector of names. By default is no name is entered, it takes the value of &quot;Person with no name&quot;
#&apos; @export
hello_fun &lt;- function(name=&quot;Person with no name&quot;) {

  is_empty_string_vector &lt;- name == &quot;&quot;
  name &lt;- name[!is_empty_string_vector]

  is_na_vector &lt;- is.na(name)
  name &lt;- name[!is_na_vector]

  if (length(name)==1) {
  if (is.na(name) | name==&quot;&quot;) {
    stop(&quot;I&apos;d like you to enter a name. not an empty string!&quot;)
  } else {
  return(glue::glue(&quot;Hello {name}&quot;))
  }
  }

  if (length(name)&gt;1) {
   names_string &lt;- paste(name,collapse=&quot; and &quot;)
   return(glue::glue(&quot;Hello {names_string}!&quot;))
  }
}</code></pre><p>The new bits are there to sanitize and remove the empty strings or NA values from the name parameter, if given, and it works no matter how long the vector is! </p><p>Let&apos;s enjoy the final, successful test, while I go and grab a cup of tea:</p><figure class="kg-card kg-image-card"><img src="https://wazrak.com/content/images/2023/06/image-14.png" class="kg-image" alt="Protect Your Code with Tests! Your First R Package Journey Continues" loading="lazy" width="672" height="246" srcset="https://wazrak.com/content/images/size/w600/2023/06/image-14.png 600w, https://wazrak.com/content/images/2023/06/image-14.png 672w"></figure><p>The tea will have to wait. What&apos;s happening here? </p><p>Oh, I fixed one issue, but I created a new one!? Now, when someone enters an empty string as an argument, it will stop throwing an error since my new additions will completely remove them. </p><p>When you end up here, there&apos;s two ways to proceed:</p><ul><li>First would be to fix the function to restore the older behavior. It&apos;s as simple as doing a condition to check if the length of the vector is 1 first before applying our couple of lines that were made mainly for longer vectors.</li><li>The other approach is... well, that test we had does not make sense anymore. I ended up with a generalization that&apos;s <em>more correct, </em>and I could just as well get rid of that test.</li></ul><p>My choice here is to take the second approach. And this is where this quote feels just right at home:</p><!--kg-card-begin: markdown--><blockquote>
<p>&quot;Unit testing is a conversation between the developer and the code.&quot;</p>
</blockquote>
<p><em>Martin Fowler</em> (yes, again)</p>
<!--kg-card-end: markdown--><p>So my final test-hello.R file will be like that:</p><pre><code class="language-R">test_that(&quot;Confirm that the function works with John&quot;, {
  expect_equal(hello_fun(name=&quot;John&quot;), &quot;Hello John&quot;)
})

test_that(&quot;Confirm that the function works when no parameter is given&quot;, {
  expect_equal(hello_fun(), &quot;Hello Person with no name&quot;)
})

test_that(&quot;Confirm that the function works when two names are given&quot;, {
  expect_equal(hello_fun(name=c(&quot;Joan&quot;,&quot;Liz&quot;)), &quot;Hello Joan and Liz!&quot;)
})

test_that(&quot;Confirm that the function works when two names are given but one is empty&quot;, {
  expect_equal(hello_fun(name=c(&quot;Joan&quot;,&quot;&quot;)), &quot;Hello Joan&quot;)
})
</code></pre><p>And this time, all tests are passed:</p><figure class="kg-card kg-image-card"><img src="https://wazrak.com/content/images/2023/06/image-15.png" class="kg-image" alt="Protect Your Code with Tests! Your First R Package Journey Continues" loading="lazy" width="630" height="186" srcset="https://wazrak.com/content/images/size/w600/2023/06/image-15.png 600w, https://wazrak.com/content/images/2023/06/image-15.png 630w"></figure><p>And apparently, I&apos;m not a rockstar anymore :-( </p><p>But I get to enjoy my tea, before it got cold. All&apos;s good.</p><h2 id="is-that-it">Is that it?</h2><p>For simple tests, yes. But there are many other tests you can plan, and different ways to write them, too. Next time, I will bring a more complex example on this topic - there&apos;s a lot to cover.</p><p>Stay tuned!</p>]]></content:encoded></item><item><title><![CDATA[Python, R, Reticulate, and Fixing Unknown Crashes (Numpy)]]></title><description><![CDATA[<p>A short post this time. If you use <a href="https://rstudio.github.io/reticulate/">{reticulate}</a> (the excellent library to bridge together Python and R code) you will sometimes end up with a complete system crash (R session aborted) when loading specific Python functions using a reticulate environment.</p><p>Since the error gives you no insight as to</p>]]></description><link>https://wazrak.com/python-r-reticulate-and-fixing-unknown-crashes/</link><guid isPermaLink="false">647f33dcb360d300010456f3</guid><dc:creator><![CDATA[Alisa Wazrak]]></dc:creator><pubDate>Tue, 06 Jun 2023 13:41:50 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1611260507265-97f990094080?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDl8fGNyYXNofGVufDB8fHx8MTY4NjA1ODYxNnww&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" medium="image"/><content:encoded><![CDATA[<img src="https://images.unsplash.com/photo-1611260507265-97f990094080?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDl8fGNyYXNofGVufDB8fHx8MTY4NjA1ODYxNnww&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" alt="Python, R, Reticulate, and Fixing Unknown Crashes (Numpy)"><p>A short post this time. If you use <a href="https://rstudio.github.io/reticulate/">{reticulate}</a> (the excellent library to bridge together Python and R code) you will sometimes end up with a complete system crash (R session aborted) when loading specific Python functions using a reticulate environment.</p><p>Since the error gives you no insight as to what is actually happening, this is a hard one to debug. Nobody likes to meet face-to-face with a <em>&quot;Segmentation Fault&quot;</em>. </p><p>In my case, I have ultimately found that this error occurs when I use a Python environment with <a href="https://numpy.org/">Numpy</a> installed. As soon as the environment is loaded with Numpy, this leads to this kind of crash.</p><p>This happens (on Linux) when I install Numpy this way in a virtualenv:</p><pre><code class="language-R">reticulate::virtualenv_install(envname = &quot;python-env-for-analysis&quot;,packages = &quot;numpy&quot;)</code></pre><p> To make this error go away, this is what actually works - you need to let pip know that you don&apos;t want to fetch a binary for numpy, but actually recompile it from sources on your local machine.</p><pre><code class="language-R">reticulate::virtualenv_install(envname = &quot;python-env-for-analysis&quot;,packages = &quot;numpy&quot;, pip_options = &quot;--no-binary=&apos;numpy&apos;&quot;,ignore_installed = TRUE)</code></pre><p>It will take a little longer to install, but it&apos;s worth it.</p><p>If you ever get some weird, unexpected crashes with reticulate, keep this is in mind (or in a bookmark). It might save you many, many precious hours.</p><h1></h1>]]></content:encoded></item><item><title><![CDATA[Making a Simple Package in R, using Modern Tools]]></title><description><![CDATA[<p>I will not be using {fusen} here while it&apos;s often being advertised these days. I find it a bit confusing and much prefer the typical way of building packages.</p><p>You need to install the following:</p><ul><li>devtools (necessary to build your package)</li><li>usethis (helper functions to take shortcuts)</li><li>roxygen2</li></ul>]]></description><link>https://wazrak.com/making-a-simple-package-in-r-using-modern-tools/</link><guid isPermaLink="false">647c1164b360d300010455c7</guid><category><![CDATA[R]]></category><category><![CDATA[packaging]]></category><category><![CDATA[package]]></category><category><![CDATA[library]]></category><category><![CDATA[guide]]></category><category><![CDATA[tutorial]]></category><dc:creator><![CDATA[Alisa Wazrak]]></dc:creator><pubDate>Sun, 04 Jun 2023 10:05:09 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1585583323619-327e6177d23b?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDE2fHxjYXJkYm9hcmQlMjBib3h8ZW58MHx8fHwxNjg1ODcwMDYyfDA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" medium="image"/><content:encoded><![CDATA[<img src="https://images.unsplash.com/photo-1585583323619-327e6177d23b?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDE2fHxjYXJkYm9hcmQlMjBib3h8ZW58MHx8fHwxNjg1ODcwMDYyfDA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" alt="Making a Simple Package in R, using Modern Tools"><p>I will not be using {fusen} here while it&apos;s often being advertised these days. I find it a bit confusing and much prefer the typical way of building packages.</p><p>You need to install the following:</p><ul><li>devtools (necessary to build your package)</li><li>usethis (helper functions to take shortcuts)</li><li>roxygen2 (simplifies package creation)</li><li>testthat (to incorporate standard testing as part of your package build)</li></ul><p>You can install them all with a one liner:</p><pre><code>install.packages(c(&quot;devtools&quot;, &quot;roxygen2&quot;,&quot;usethis&quot;, &quot;testthat&quot;))</code></pre><h2 id="setting-you-on-the-right-path">Setting You on the Right Path</h2><p>First you need to setup the path that you are working with, and where a new folder will be created for you. (don&apos;t create a folder for your package!)</p><pre><code>setwd(&quot;/path/to/your/main/folder/&quot;)</code></pre><p>Now you can use a helper function to create the main structure of your package:</p><pre><code>usethis::create_package(&quot;packagedfun&quot;)</code></pre><p>note that are limits to what kind of characters you can use when you name a package. If you get an error this probably means that you tried to use some of them that are not allowed.</p><p>When you execute the above command in RStudio, it will directly reload the environment to put you inside the newly created project.</p><p>Your environment will have the following files:</p><ul><li>.gitignore</li><li>.Rbuildignore</li><li>DESCRIPTION</li><li>NAMESPACE</li><li>packagedfun.Rproj</li><li>R (folder)</li></ul><p>The DESCRIPTION file generates meta data about your project. You will have to edit it by yourself to reflect the actual information about your package. </p><p>The NAMESPACE file is automatically generated (and is read-only) in our workflow so you should not edit it manually.</p><p>The R folder is where you will put your R scripts which will contain your functions and scripts.</p><h2 id="licensing-just-a-few-seconds-of-work">Licensing: Just a Few Seconds of Work</h2><p>First I&apos;d recommend you set the license of your package. You can use the helper functions from usethis for this purpose. Let&apos;s say we want to use the MIT license, you can simply write in the console:</p><pre><code class="language-R">usethis::use_mit_license()</code></pre><p>This will automatically modify the DESCRIPTION file to include the MIT license and add a separate license file (actually two, LICENSE and LICENSE.md) in the working folder with the MIT license text. Practical!</p><p>Of course this is not limited to MIT, you can add AGPL, GPL, or even proprietary licenses directly from usethis. </p><h2 id="versioning-easy">Versioning: Easy!</h2><p>You probably want to start enumerating the version of your package as well. Once again, usethis comes to the rescue when you run it in the console:</p><pre><code class="language-R">usethis::use_version()</code></pre><p>This will ask you to choose how to increment your package&apos;s version number:</p><figure class="kg-card kg-image-card"><img src="https://wazrak.com/content/images/2023/06/image.png" class="kg-image" alt="Making a Simple Package in R, using Modern Tools" loading="lazy" width="440" height="141"></figure><p>If you are still in early days of developing your package, you may want to start with a minor version (option 2). Type 2, and the DESCRIPTION will be automatically updated.</p><h2 id="your-packages-first-function">Your Package&apos;s First Function</h2><p>Let&apos;s proceed by creating a simple function:</p><pre><code class="language-R">usethis::use_r(&quot;hello&quot;)</code></pre><p>This creates a hello.R file inside the R folder, as you can imagine.</p><p>The new file is completely empty and you can start creating your function. Let&apos;s do a simple hello world, but with a twist.</p><pre><code class="language-R">hello_fun &lt;- function(name) {
  
  print(glue::glue(&quot;Hello {name}&quot;))
  
}</code></pre><p>As you can see, I am including an external dependency on purpose here. Most of the tutorials on the net consider that you make functions that depend on nothing at all, which is far from being the typical use case.</p><p>Now let&apos;s see what happens if we check the package in its current state.</p><h2 id="learning-from-failures">Learning from Failure(s)</h2><p>Assuming you use RStudio, you can use the &quot;Check Package&quot; menu from the Rstudio interface in the Build menu:</p><figure class="kg-card kg-image-card"><img src="https://wazrak.com/content/images/2023/06/image-2.png" class="kg-image" alt="Making a Simple Package in R, using Modern Tools" loading="lazy" width="318" height="366"></figure><p>You will get a long list of checks happening in the environment tab on the upper right corner, and at the end it will issue a warning about the fact that you did not declare a dependency.</p><figure class="kg-card kg-image-card"><img src="https://wazrak.com/content/images/2023/06/image-1.png" class="kg-image" alt="Making a Simple Package in R, using Modern Tools" loading="lazy" width="650" height="133" srcset="https://wazrak.com/content/images/size/w600/2023/06/image-1.png 600w, https://wazrak.com/content/images/2023/06/image-1.png 650w"></figure><p>You can actually still build your package - and it will work and load, but when you call the hello_fun() function it will complain that the function glue is not available, which is less than ideal.</p><p>In order to fix it, you can follow the <a href="https://roxygen2.r-lib.org/articles/rd.html">style used by roxygen2</a> to add meta data to your functions:</p><pre><code class="language-R">#&apos; Saying Hello is polite
#&apos; 
#&apos; @description
#&apos; `hello_fun` says hello and uses the name of the person as an argument.
#&apos;
#&apos; @import glue
#&apos;
#&apos; @details
#&apos; This is a generic function that can be used to say hello/
hello_fun &lt;- function(name) {

  print(glue::glue(&quot;Hello {name}&quot;))

}</code></pre><p>The key statement here is the @import. Here by specify &quot;glue&quot;, which means it will import the whole glue library along with all of its functions. While that would work, that&apos;s completely overkill, and incurs the risk of functions with the same name causing conflicts. The better approach if a more specific import statement:</p><pre><code class="language-R">#&apos; Saying Hello is polite
#&apos; 
#&apos; @description
#&apos; `hello_fun` says hello and uses the name of the person as an argument.
#&apos;
#&apos; @importFrom glue glue
#&apos;
#&apos; @details
#&apos; This is a generic function that can be used to say hello/
hello_fun &lt;- function(name) {

  print(glue::glue(&quot;Hello {name}&quot;))

}
</code></pre><p>Since it&apos;s not obvious from the example above, the @importFrom follows the syntax:</p><pre><code>@importFrom &lt;package&gt; &lt;function&gt;</code></pre><p>So if you import the function write_feather from the library arrow, it would look like:</p><pre><code>@importFrom arrow write_feather</code></pre><p>Are we done now? </p><p>Let&apos;s &quot;check&quot; the package again. </p><figure class="kg-card kg-image-card"><img src="https://wazrak.com/content/images/2023/06/image-5.png" class="kg-image" alt="Making a Simple Package in R, using Modern Tools" loading="lazy" width="318" height="366"></figure><p>When you run the checks, it will also modify the NAMESPACE file - and if you open it, you will see it now contains the dependency declaration:</p><pre><code># Generated by roxygen2: do not edit by hand

importFrom(glue,glue)
</code></pre><p>... which is great, but alas! this is not enough to pass the checks yet!</p><figure class="kg-card kg-image-card"><img src="https://wazrak.com/content/images/2023/06/image-3.png" class="kg-image" alt="Making a Simple Package in R, using Modern Tools" loading="lazy" width="651" height="174" srcset="https://wazrak.com/content/images/size/w600/2023/06/image-3.png 600w, https://wazrak.com/content/images/2023/06/image-3.png 651w"></figure><p>Now we get an actual error, because our dependency is not declared in the DESCRIPTION file!</p><p>It&apos;s an easy fix - this is the DESCRIPTION before the import statement:</p><pre><code class="language-R">Package: packagedfun
Title: Enjoy a proper Hello World with a customized message!
Version: 0.1.0
Authors@R: 
    person(&quot;Alisa&quot;, &quot;Wazrak&quot;, , &quot;alisa.wazrak@example.com&quot;, role = c(&quot;aut&quot;, &quot;cre&quot;))
Description: This package provides the valuable hello_fun function that nobody has ever created before.
License: MIT + file LICENSE
Encoding: UTF-8
Roxygen: list(markdown = TRUE)
RoxygenNote: 7.2.3
</code></pre><p>and after:</p><pre><code class="language-R">Package: packagedfun
Title: Enjoy a proper Hello World with a customized message!
Version: 0.1.0
Authors@R: 
    person(&quot;Alisa&quot;, &quot;Wazrak&quot;, , &quot;alisa.wazrak@example.com&quot;, role = c(&quot;aut&quot;, &quot;cre&quot;))
Description: This package provides the valuable hello_fun function that nobody has ever created before.
Imports: glue
License: MIT + file LICENSE
Encoding: UTF-8
Roxygen: list(markdown = TRUE)
RoxygenNote: 7.2.3
</code></pre><p>Are we there yet?</p><figure class="kg-card kg-image-card"><img src="https://wazrak.com/content/images/2023/06/image-6.png" class="kg-image" alt="Making a Simple Package in R, using Modern Tools" loading="lazy" width="318" height="366"></figure><p>Let&apos;s see...</p><figure class="kg-card kg-image-card"><img src="https://wazrak.com/content/images/2023/06/image-7.png" class="kg-image" alt="Making a Simple Package in R, using Modern Tools" loading="lazy" width="638" height="210" srcset="https://wazrak.com/content/images/size/w600/2023/06/image-7.png 600w, https://wazrak.com/content/images/2023/06/image-7.png 638w"></figure><p>Almost! </p><p>Now we are notified that we have forgotten to document the argument in our function.</p><p>We can just modify it in the hello.R file to include a @param statement as well as an @export statement to ensure that the function is available once you load the package later on: (functions without @export flags are ignored)</p><pre><code>#&apos; Saying Hello is polite
#&apos;
#&apos; @description
#&apos; `hello_fun` says hello and uses the name of the person as an argument.
#&apos;
#&apos; @importFrom glue glue
#&apos;
#&apos; @details
#&apos; This is a generic function that can be used to say hello/
#&apos;
#&apos; @param name the name of the person you want to send a Hello message to
#&apos; @export
hello_fun &lt;- function(name) {

  print(glue::glue(&quot;Hello {name}&quot;))

}
</code></pre><p>And we are done! The last check works:</p><figure class="kg-card kg-image-card"><img src="https://wazrak.com/content/images/2023/06/image-8.png" class="kg-image" alt="Making a Simple Package in R, using Modern Tools" loading="lazy" width="645" height="119" srcset="https://wazrak.com/content/images/size/w600/2023/06/image-8.png 600w, https://wazrak.com/content/images/2023/06/image-8.png 645w"></figure><h2 id="building-installing-and-testing-the-package">Building, Installing and Testing the Package</h2><p>Now you can go ahead and build a binary package, for example, once the checks are successful:</p><figure class="kg-card kg-image-card"><img src="https://wazrak.com/content/images/2023/06/image-9.png" class="kg-image" alt="Making a Simple Package in R, using Modern Tools" loading="lazy" width="299" height="346"></figure><p>This will build a <strong>packagedfun_0.1.0_R_x86_64-pc-linux-gnu.tar.gz</strong> (if you run this on Linux) in the parent folder of your package.</p><p>To check if it works, you can exit the current Rstudio session, and reload a clean one. Then you try installing the package (of course, adapt the path to your system&apos;s):</p><pre><code>install.packages(&quot;/path/to/your/package/binary/packagedfun_0.1.0_R_x86_64-pc-linux-gnu.tar.gz&quot;)</code></pre><p>It should succeed. </p><p>Now you can load it:</p><pre><code>library(packagedfun)
</code></pre><p>and try it out:</p><pre><code>hello_fun(&quot;You!&quot;)</code></pre><p>and you should see a glorious answer in your console:</p><pre><code>Hello You!</code></pre><p>We are done!</p><p>I hope you enjoyed this post. We will come back with a few more details on how to make packages in R. This time we focused on how to do it correctly with the minimal effort - next, we will see how we can add some more polish.</p>]]></content:encoded></item><item><title><![CDATA[Hi There!]]></title><description><![CDATA[<p>This is my first post, just to say Hi! I&apos;m Alisa, and I love to play around with data in my spare time. I will be sharing with you some of the things I do once in a while! Stay tuned!</p>]]></description><link>https://wazrak.com/hi-there/</link><guid isPermaLink="false">63e1c97259ac170001d8157a</guid><dc:creator><![CDATA[Alisa Wazrak]]></dc:creator><pubDate>Tue, 07 Feb 2023 03:46:47 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1627008767693-20498ff18ab7?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDE3fHxoZWxsb3xlbnwwfHx8fDE2ODU5OTczMzJ8MA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" medium="image"/><content:encoded><![CDATA[<img src="https://images.unsplash.com/photo-1627008767693-20498ff18ab7?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDE3fHxoZWxsb3xlbnwwfHx8fDE2ODU5OTczMzJ8MA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" alt="Hi There!"><p>This is my first post, just to say Hi! I&apos;m Alisa, and I love to play around with data in my spare time. I will be sharing with you some of the things I do once in a while! Stay tuned!</p>]]></content:encoded></item></channel></rss>