Get your codebase lint-free forever with lintr
This post was featured on the R Weekly highlights podcast hosted by Eric Nantz and Mike Thomas. Writing good code is hard. Some aspects get easier with experience – although I observe that I consistently forget some things. 🙈 Other aspects can be tackled through code review – although your reviewer’s time will be better spent on design questions than on nitpicks. 💅 Static code analysis can help with code quality.
Hack your way to a good Git history
I’ve now explained on this blog why it’s important to have small, informative Git commits1 and how I’ve realized that polishing history can happen in a second phase of work in a branch. However, I’ve more or less glossed over how to craft the history in a branch once you’re done with the work. I’ve entitled this post “Hack your way to a good Git history” because writing the history after the fact can feel like cheating, but it’s not!
Why you need small, informative Git commits
This post was featured on the R Weekly highlights podcast hosted by Eric Nantz and Mike Thomas. “Make small Git commits with informative messages” is a piece of advice we hear a lot when learning Git. That’s why we might want to sometimes rewrite history in a branch. In this post, I’d like to underline three main (😉) reasons why you’ll be happy you, or someone else, made small and informative Git commits in a codebase.
Load different R package versions at once with git worktree
This post was featured on the R Weekly highlights podcast hosted by Eric Nantz and Mike Thomas. Do you ever see GitHub issue comments where someone posts the results of a reprex with a current package version, and then with an older one, to prove a regression? How would you go about preparing such a report? Today I learnt there is a clean way to have different versions of a codebase at once on your computer, thanks to the ever powerful Git.
Reading notes on Pro Git by Scott Chacon
As mentioned about a million times on this blog, last year I read Git in practice by Mike McQuaid and it changed my life – not only giving me bragging rights about the reading itself. 😅 I decided to give Pro Git by Scott Chacon a go too. It is listed in the resources section of the excellent “Happy Git with R” by Jenny Bryan, Jim Hester and others. For unclear reasons I bought the first edition instead of the second one.
Reading notes on The Pragmatic Programmer by David Thomas and Andrew Hunt
In my quest to having reading notes on the tech books I read, and while waiting for code to run, I recently re-read The Pragmatic Programmer by David Thomas and Andrew Hunt. That book, whose second edition was published in 2019, offers an overview of many topics useful to programmers, from the idea of taking responsability, to testing, tooling, etc. Not my favorite tone I’m not the biggest fan of the tone used in the book, that feels a bit patronizing to me.
The two phases of commits in a Git branch
I seem to have at last entered my Git era. 🎉 Reading and applying Git in practice was probably the best thing I did for my upskilling this year. One Git workflow aspect I’ve finally realized is that it’s fine to have two phases of work in a Git branch. I’ll explain it in this post. Set up: create a branch for your work! Ideally, in most cases, when adding a feature or fixing a bug or whatever, I’ll work in a branch.
Reading notes on Kill It with Fire by Marianne Bellotti
Another month, another long train trip enjoyed in the company of great books, among which a work-related one, Kill it with fire by Marianne Bellotti. As indicated by its subtitle “Manage Aging Computer Systems (and Future Proof Modern Ones)”, the book deals with handling legacy computer systems. The focus is on bigger projects (including serious internal politics) than what I usually deal with, but there’s some valuable lessons for any project size in there.
Useful functions for dealing with object names
My sticky note filled up quickly after I only added setNames() on it, with related functions for dealing with object names, in base R and beyond! (Un)Setting object names: stats::setNames(), unname() and rlang::set_names() I noticed a function ending with something like this: blop <- function() { # code creating the df data.frame # ... names(df) <- c("col1", "col2") df } It struck me as simplifiable by:
Reading notes on Git in Practice by Mike McQuaid
While preparing materials for teaching Git a few months ago, I re-read Suzan Baert’s excellent post about Git and GitHub, where she mentioned having read “Git in Practice” by Mike McQuaid. I added the book to my Momox alerts, where it got available a few weeks later. The book source is on GitHub. The book isn’t too heavy, so I took it with me on a long train journey! 🚋
3 (actually 4) neat R functions
Time for me to throw away my sticky note after sharing what I wrote on it! grep(...) not which(grepl(...)) Recently I caught myself using which(grepl(...)), animals <- c("cat", "bird", "dog", "fish") which(grepl("i", animals)) #> [1] 2 4 when the simpler alternative is animals <- c("cat", "bird", "dog", "fish") grep("i", animals) #> [1] 2 4 And should I need the values instead of the indices, I know I shouldn’t write
Reading notes on A Philosophy of Software Design by John Ousterhout
When I see a book recommendation somewhere, be it for work or leisure, I often either order the book or set an alert in my favorite online second-hand bookstore. By the time I am notified the book is available, I sometimes don’t remember why I listed it! That’s what happened for the book A Philosophy of Software Design by John Ousterhout. I decided to trust my past self and buy it.
The real reset button for local mess fom tests: withr::deferred_run()
This post was featured on the R Weekly highlights podcast hosted by Eric Nantz and Mike Thomas. Following last week’s post on my testing workflow enhancements, Jenny Bryan kindly reminded me of the existence of an actual reset button when you’ve been interactively running tests that include some “local mess”: withr::local_envvar(), withr::local_dir(), usethis::local_project()… The reset button is withr::deferred_run(). It is documented in Jenny’s article about test fixtures: Since the global environment isn’t perishable, like a test environment is, you have to call deferred_run() explicitly to execute the deferred events.
Two recent enhancements to my testing workflow
I spend a lot of quality time with testthat, that sometimes deigns to praise my code with emojis, sometimes has to encourage me. No one gets it right on their first try apparently? Anyway, in honor of testthat 3.2.0 release 🎉 👏, I’d like to mention two small things that improved my testing workflow a whole lot! Running one single test at a time Under testthat 3.2.0 minor features lies a small gem:
3 R functions that I enjoy
Straight from my sticky note, three functions that I like a lot, despite their not being new at all… But maybe new to some of you? sprintf(), the dependency-free but less neat “glue” Imagine I want to tell you who I am. I could write name <- whoami::fullname() github_username <- whoami::gh_username() glue::glue("My name is {name} and you'll find me on GitHub as {github_username}!") #> My name is Maëlle Salmon and you'll find me on GitHub as maelle!
R functions that shorten/filter stuff: less is more
My sticky note is full! And luckily all functions on it can be squeezed into a similar topic: making things smaller! Make lists smaller with purrr::compact(), purrr::keep(), purrr::discard() Once upon a time there was a list (isn’t this the beginning of all R scripts?!) my_list <- list( name = "Maëlle", city = "Nancy", r_problems_encountered = Inf, python_skills = NULL ) Imagine you want to get rid of NULL elements.
Three (four?) R functions I enjoyed this week
There are already three functions of note on a piece of paper on my desk, so it’s time to blog about them! This post was featured on the R Weekly podcast by Eric Nantz and Mike Thomas. How does this package depend on this other package? pak::pkg_deps_explain() The pak package by Gábor Csárdi makes installing packages easier. If I need to start working on a package, I clone it, then run pak::pak() to install and update its dependencies.
Reducing my for loop usage with purrr::reduce()
I (only! but luckily!) recently got introduced to the magic of purrr::reduce(). Thank you, Tobias! I was told about it right as I was unhappily using many for loops in a package1, for lack of a better idea. In this post I’ll explain how purrr::reduce() helped me reduce my for loop usage. I also hope that if I’m doing something wrong, someone will come forward and tell me! This post was featured on the R Weekly podcast by Eric Nantz and Mike Thomas.
Three useful (to me) R notions
Following my recent post on three useful (to me) R patterns, I’ve written down three other things on a tiny sticky note. This post will allow me to throw away this beaten down sticky note, and maybe to show you one element you didn’t know? nzchar(): “a fast way to find out if elements of a character vector are non-empty strings” One of my favorite testing technique is the escape hatch strategy, about which I wrote a post on the R-hub blog: you make part of your code responsive to an environment variable, and you locally set that environment variable in your tests.
Three useful (to me) R patterns
This post was featured on the R Weekly highlights podcast hosted by Eric Nantz and Mike Thomas. I’m happy to report that I thought “oh but I know a better way to write that code!” a few times lately when reading old scripts of mine, or scripts by others. It’s a good feeling because it shows progress! I’ve tooted about all three things I’ll present in this post: After reading Julia Evans’ post about blogging, I decided to train the blogging muscle a bit using these low-hanging fruits/toots1.