On right assignment

Programmers unfamiliar with R are often put off by its rather peculiar assignment operator. While = does work as well, using <- is the recommended practice.

The reasons for <- are to be found in ancient history, when a single physical key to type the left arrow existed. Arguably, the arrow assignment operator adds clarity by disambiguating assignment from declaration of named vectors elements and function arguments. And those who find it looks a tad primitive could easily use a font with a corresponding ligature, such as Fira Code.

Arguments against <- usually boil down to either confusing programmers coming from other languages, the extra typing effort, and the possible introduction of some nasty bugs for the space-unaware (foo< -5, anyone? 5<-5?).

But then there is also that evergreen tip to blow the minds of #rstats newbies around the world: you can assign to the right, with ->! This makes sense especially given the explosive popularity in recent years of the magrittr pipe %>%, where each operation logically builds on the result of the previous one. Adding the assignment as the final step, rather than the first, is consistent with this pipeline idiom of data processing. For instance:

library(dplyr)

iris %>%
  group_by(Species) %>%
  count() -> species_counts

Yet I don’t do this - because it obfuscates variable creation in a script or program. If variables have meaningful names, you don’t always need to know how exactly they were created. That would be a ‘deep dive’ into them. But you do want to immediately parse visually where in the program flow a variable name was defined.

A second argument pro-right-assignment has more merit. When working interactively, often you execute a piece of code and print its output. If it looks all right, you assign it to a variable. Right assignment allows you to take the same code (using the up arrow in the console) and add the assignment at the end, whereas adding it to the beginning inside the console would be most annoying. But there is an alternative to this:

nrow(iris)
## [1] 150
n_rows <- .Last.value

… with the added benefit of not actually having to do the computation again, either. I will admit though to usually doing this instead:

.Last.value -> n_rows

.L <TAB> brings the psychological comfort of ‘finding’ the object, even with the possibility of printing it again just to be sure, before assigning it. This to me is the main practical use of right assignment. In most other cases my opinion is: don’t. Variable naming is too important for the visual structuring of code to bury it under a pile of pipes. And if those names are not important to your code, perhaps just go fully functional then and skip unnecessary intermediate assignment altogether!