Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Disable assignment via = in R

R allows for assignment via <- and =.

Whereas there a subtle differences between both assignment operators, there seems to be a broad consensus that <- is the better choice than =, as = is also used as operator mapping values to arguments and thus its use may lead to ambiguous statements. The following exemplifies this:

> system.time(x <- rnorm(10))
   user  system elapsed 
      0       0       0 
> system.time(x = rnorm(10))
Error in system.time(x = rnorm(10)) : unused argument(s) (x = rnorm(10))

In fact, the Google style code disallows using = for assignment (see comments to this answer for a converse view).

I also almost exclusively use <- as assignment operator. However, the almost in the previous sentence is the reason for this question. When = acts as assignment operator in my code it is always accidental and if it leads to problems these are usually hard to spot.

I would like to know if there is a way to turn off assignment via = and let R throw an error any time = is used for assignment.

Optimally this behavior would only occur for code in the Global Environment, as there may well be code in attached namespaces that uses = for assignment and should not break.

(This question was inspired by a discussion with Jonathan Nelson)

like image 667
Henrik Avatar asked Sep 13 '12 23:09

Henrik


3 Answers

Here's a candidate:

`=` <- function(...) stop("Assignment by = disabled, use <- instead")
# seems to work
a = 1
Error in a = 1 : Assignment by = disabled, use <- instead
# appears not to break named arguments
sum(1:2,na.rm=TRUE)
[1] 3
like image 143
James Avatar answered Nov 10 '22 22:11

James


I'm not sure, but maybe simply overwriting the assignment of = is enough for you. After all, `=` is a name like any other—almost.

> `=` <- function() { }
> a = 3
Error in a = 3 : unused argument(s) (a, 3)
> a <- 3
> data.frame(a = 3)
  a
1 3

So any use of = for assignment will result in an error, whereas using it to name arguments remains valid. Its use in functions might go unnoticed unless the line in question actually gets executed.

like image 9
MvG Avatar answered Nov 10 '22 22:11

MvG


The lint package (CRAN) has a style check for that, so assuming you have your code in a file, you can run lint against it and it will warn you about those line numbers with = assignments.

Here is a basic example:

temp <- tempfile()
write("foo = function(...) {
          good <- 0
          bad = 1
          sum(..., na.rm = TRUE)
       }", file = temp)

library(lint) 
lint(file = temp, style = list(styles.assignment.noeq))
# Lint checking: C:\Users\flodel\AppData\Local\Temp\RtmpwF3pZ6\file19ac3b66b81
# Lint: Equal sign assignemnts: found on lines 1, 3

The lint package comes with a few more tests you may find interesting, including:

  • warns against right assignments
  • recommends spaces around =
  • recommends spaces after commas
  • recommends spaces between infixes (a.k.a. binary operators)
  • warns against tabs
  • possibility to warn against a max line width
  • warns against assignments inside function calls

You can turn on or off any of the pre-defined style checks and you can write your own. However the package is still in its infancy: it comes with a few bugs (https://github.com/halpo/lint) and the documentation is a bit hard to digest. The author is responsive though and slowly making improvements.

like image 7
flodel Avatar answered Nov 10 '22 23:11

flodel