Three useful (to me) R patterns

[This article was first published on Maëlle's R blog on Maëlle Salmon's personal website, and kindly contributed to R-bloggers]. (You can report issue about the content on this page here)
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.

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.

Combine a list of default values with a list of custom values

Toot

Imagine 💭

🎚️ you have a default_values list and 👇 want to let the user pass a custom_values list to override some of them.

utils::modifyList(default_values, custom_values)does that!

So say you had code à la

default_values <- list(a = 1, b = 2)
options <- list(b = 56)
temporary_list <- default_values
temporary_list[names(options)] <- options
options <- temporary_list

options
#> $a
#> [1] 1
#> 
#> $b
#> [1] 56

You can write it like so

default_values <- list(a = 1, b = 2)
options <- list(b = 56)
options <- modifyList(default_values, options)
options
#> $a
#> [1] 1
#> 
#> $b
#> [1] 56

I learnt about that function in pkgdown source.

Use a default if the user provided NULL

Toot

Do you know the rlang %||% operator?2

Code like

if (is.null(blop)) {
  blop <- 42
}

can become

blop <- blop %||% 42

Related to this, I’d recommend package developers read the chapter of the Tidyverse design guide on defaults, especially the section on the NULL default.

Extract common values or different / unique values from two vectors

Toot

Say I have a vector a and a vector b, and I need the unique a values that are not in b.

a <- c("thing", "object")
b <- c("thing", "gift")

I tended to write something like

unique(a[!(a %in% b)])
#> [1] "object"

(or without the unique() if a has only distinct values)

that can be

setdiff(a, b)
#> [1] "object"

Similarly, when looking for the unique values of the two vectors combined, instead of

unique(c(a, b))
#> [1] "thing"  "object" "gift"

I can write

union(a, b)
#> [1] "thing"  "object" "gift"

Because I’ve noticed I didn’t know these base R functions well enough, I open the Set Operations manual page more often, by typing ?setdiff for instance.

Salix Dubois helpfully noted the functions can be slower, and that one might not always want to drop duplicates.

Conclusion

In this post I presented three basic (set of) functions (not all base functions) that I’ve found serve me well: utils::modifyList(), rlang::%||% and base Set Operations. I’m glad they’re now part of my R vocabulary.

Note that you might still prefer the longer version of some of these patterns, depending on your needs, your code readers, etc. I won’t judge!

I’m curious to see what three new things I’ll have learnt in a few months (and will try not to beat myself up for not learning about them sooner 😇). If you’re interested about code quality in general, you might enjoy this post by Christophe Dervieux and myself on the R-hub blog.


  1. I hope it’s a myth that your puns need to be good! ↩︎

  2. Please don’t ask me to say this aloud, I have no idea how it’s pronounced. ↩︎

To leave a comment for the author, please follow the link and comment on their blog: Maëlle's R blog on Maëlle Salmon's personal website.

R-bloggers.com offers daily e-mail updates about R news and tutorials about learning R and many other topics. Click here if you're looking to post or find an R/data-science job.
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.

Never miss an update!
Subscribe to R-bloggers to receive
e-mails with the latest R posts.
(You will not see this message again.)

Click here to close (This popup will not appear again)