Skip to main content
AI in Production 2026 is now open for talk proposals.
Share insights that help teams build, scale, and maintain stronger AI systems.
items
Menu
  • About
    • Overview 
    • Join Us  
    • Community 
    • Contact 
  • Training
    • Overview 
    • Course Catalogue 
    • Public Courses 
  • Posit
    • Overview 
    • License Resale 
    • Managed Services 
    • Health Check 
  • Data Science
    • Overview 
    • Visualisation & Dashboards 
    • Open-source Data Science 
    • Data Science as a Service 
    • Gallery 
  • Engineering
    • Overview 
    • Cloud Solutions 
    • Enterprise Applications 
  • Our Work
    • Blog 
    • Case Studies 
    • R Package Validation 
    • diffify  

Writing a Personal R Package

Published: February 7, 2021

tags: r, package

If you’ve been using R for a while, you’ve likely accumulated a hodgepodge of useful code along the way. Said hodgepodge might include functions you source into multiple projects; bits and bobs that you copy and paste where needed; or code that solved a particularly esoteric problem and will never be applicable elsewhere, but you still enjoy revisiting sometimes. We all do it.

If you’re anything like me, your personal library of code has grown gradually and haphazardly. It’s spread across multiple locations, wherever was easiest at the time: a directory on a laptop; a pen drive; line 243 of the script in which it was originally conceived. It’s entirely untested, poorly documented and takes a while to decipher every time you return to it. You’re proud of some of it, and ashamed at the mess of the rest of it. If you’re nodding along so far, this blogpost is for you.

Do you use Professional Posit Products? If so, check out our managed Posit services

A better way

Writing an R package can seem daunting at first. If you’ve browsed the source code of a popular CRAN package then you can be forgiven for feeling overwhelmed. But a package doesn’t need to be the next data.table or have the audience of dplyr to be worthwhile. And thanks to the wonderful usethis package, creating a personal R package could scarcely be easier.

Plenty of prominent statisticians and data scientists have personal R packages in which they store their miscellaneous functions: Karl Broman; Yihui Xie; and David Robinson, to name a few. But nobodies can do the same: I now have one. The primary audience for a personal R package is yourself, and it doesn’t matter if no else uses or cares about it.

Why bother?

I first created my personal R package because I had the following function saved in a directory called “useful-code”:

## See discussion below for an improved version
days_of_week = function(abbr = FALSE) {
  days = weekdays(as.Date(seq(7), origin = "1950-01-01"))
  if (isFALSE(abbr)) {
    return(days)
  } else {
    return(substr(days, 1, 3))
  }
}

At the time I was working on a project that required aggregating data by day of the week. I was tired of typing out “Monday, Tuesday, Wednesday, …” by hand every time, so I “borrowed” the best code I could find on the topic from Stack Overflow and turned it into a function that did nothing other than return a vector of the days of the week in the formats I required:

days_of_week()
#> [1] "Monday"    "Tuesday"   "Wednesday" "Thursday"  "Friday"    "Saturday"  "Sunday"
days_of_week(abbr = TRUE)
#> [1] "Mon" "Tue" "Wed" "Thu" "Fri" "Sat" "Sun"

Every time I wanted to use days_of_week() in a new project (it was more often than you might think), I copied it from my “useful-code” directory, pasted it into a “functions” sub-directory within my project, and used source() to load it into the relevant script(s). It was laborious and unsustainable; I periodically made (and make) changes to the function but, inevitably, I could never remember all the places I’d used it. I ended up using different versions of the same function across multiple projects, which is risky territory to be in even for a function as basic as this one. After reading Hilary Parker’s blogpost on personal R packages, I decided to give it a try.

How to do it

The aforementioned usethis package takes care of the setup grunt work:

path = file.path(tempdir(), "jafun")
usethis::create_package(path)
#> ✓ Creating '/data/ncsg3/R_tmp/RtmpKbRqBJ/jafun/'
#> ✓ Setting active project to '/data/ncsg3/R_tmp/RtmpKbRqBJ/jafun'
#> ✓ Creating 'R/'
#> ✓ Writing 'DESCRIPTION'
#> Package: jafun
#> Title: What the Package Does (One Line, Title Case)
#> Version: 0.0.0.9000
#> Authors@R (parsed):
#>     * First Last <first.last@example.com> [aut, cre] (YOUR-ORCID-ID)
#> Description: What the package does (one paragraph).
#> License: `use_mit_license()`, `use_gpl3_license()` or friends to pick a
#>     license
#> Encoding: UTF-8
#> Roxygen: list(markdown = TRUE)
#> RoxygenNote: 7.1.2
#> ✓ Writing 'NAMESPACE'
#> ✓ Setting active project to '<no active project>'

Move your function(s) into the “R” directory, add some documentation, build the package with Ctrl + Shift + B, and voila:

jafun::days_of_week()
jafun::days_of_week(abbr = TRUE)

Next steps

Once you’ve developed the basis of your personal R package, you can spruce it up with as many or as few additional features as you’d like to. Adding your name and some basic details about the package to the Description file is helpful. Unit testing, releases and automated checking are present in most packages. Putting your package on GitHub allows you (and others) to install your package remotely using remotes::install_github() without requiring a local copy of the source code. None of that is compulsory though. Your package only has to be as detailed as you want it to be.

Your package will, inevitably, evolve over time. You’ll add new functions and improve upon existing ones. By way of example, a more efficient implementation of the aforementioned days_of_week() would be:

days_of_week = function(abbreviate = FALSE) {
  dates = as.Date(1:7, origin = "1950-01-01")
  weekdays(dates, abbreviate = abbreviate)
}

This would negate the need for an if statement, and it would fix a bug in the existing version. There are undoubtedly plenty of implementations more efficient than my original one. But I wrote days_of_week() for myself, with the skills I had at the time, and it did what I needed it to do. Any package maintainer would stress the importance of refining your code over time, but it doesn’t need to be at its optimum from the outset to be worth going in a package.

The longer you use R, the more miscellaneous code you’ll amass. And the more you amass, the harder it’ll be to keep track of. Creating a personal R package provides a sustainable and pain-free method of storing, growing and re-using your unique library of code. It might even provide a safe incubator to learn the ropes of package development prior to making open source contributions elsewhere. But at the very least, it’ll stop you from dipping into that “useful-functions” directory every time you want a vector of the days of the week.

Notes and thanks

Most of the links in this blogpost are from the R Packages book by Hadley Wickham and Jenny Bryan.


Jumping Rivers Logo

Recent Posts

  • Start 2026 Ahead of the Curve: Boost Your Career with Jumping Rivers Training 
  • Should I Use Figma Design for Dashboard Prototyping? 
  • Announcing AI in Production 2026: A New Conference for AI and ML Practitioners 
  • Elevate Your Skills and Boost Your Career – Free Jumping Rivers Webinar on 20th November! 
  • Get Involved in the Data Science Community at our Free Meetups 
  • Polars and Pandas - Working with the Data-Frame 
  • Highlights from Shiny in Production (2025) 
  • Elevate Your Data Skills with Jumping Rivers Training 
  • Creating a Python Package with Poetry for Beginners Part2 
  • What's new for Python in 2025? 

Top Tags

  • R (236) 
  • Rbloggers (182) 
  • Pybloggers (89) 
  • Python (89) 
  • Shiny (63) 
  • Events (26) 
  • Training (23) 
  • Machine Learning (22) 
  • Conferences (20) 
  • Tidyverse (17) 
  • Statistics (14) 
  • Packages (13) 

Authors

  • Amieroh Abrahams 
  • Aida Gjoka 
  • Shane Halloran 
  • Russ Hyde 
  • Gigi Kenneth 
  • Osheen MacOscar 
  • Sebastian Mellor 
  • Myles Mitchell 
  • Keith Newman 
  • Tim Brock 
  • Colin Gillespie 
  • Theo Roe 
  • Pedro Silva 

Keep Updated

Like data science? R? Python? Stan? Then you’ll love the Jumping Rivers newsletter. The perks of being part of the Jumping Rivers family are:

  • Be the first to know about our latest courses and conferences.
  • Get discounts on the latest courses.
  • Read news on the latest techniques with the Jumping Rivers blog.

We keep your data secure and will never share your details. By subscribing, you agree to our privacy policy.

Follow Us

  • GitHub
  • Bluesky
  • LinkedIn
  • YouTube
  • Eventbrite

Find Us

The Catalyst Newcastle Helix Newcastle, NE4 5TG
Get directions

Contact Us

  • hello@jumpingrivers.com
  • + 44(0) 191 432 4340

Newsletter

Sign up

Events

  • North East Data Scientists Meetup
  • Leeds Data Science Meetup
  • Shiny in Production
British Assessment Bureau, UKAS Certified logo for ISO 9001 - Quality management British Assessment Bureau, UKAS Certified logo for ISO 27001 - Information security management Cyber Essentials Certified Plus badge
  • Privacy Notice
  • |
  • Booking Terms

©2016 - present. Jumping Rivers Ltd