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)

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

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.


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.


If you don't want to break existing code, something like this (printing a warning not an error) might work - you give the warning then assign to the parent.frame using <- (to avoid any recursion)

`=` <- function(...){
        .what <- as.list(match.call())
        .call <-  sprintf('%s <- %s', deparse(.what[[2]]),  deparse(.what[[3]]))
        mess <- 'Use <- instead of = for assigment '
        if(getOption('warn_assign', default = T)) {
        stop (mess) } else {
        warning(mess)
        eval(parse(text =.call), envir = parent.frame())  
          }
        }

If you set options(warn_assign = F), then = will warn and assign. Anything else will throw an error and not assign.

examples in use
# with no option set
z = 1
## Error in z = 1 : Use <- instead of = for assigment 
options(warn_assign = T)
z = 1
## Error in z = 1 : Use <- instead of = for assigment 
 options(warn_assign = F)
 z = 1
## Warning message:
##  In z = 1 : Use <- instead of = for assigment 
Better options

I think formatR or lint and code formatting are better approaches.


Need Your Help

Slide down animation from display:none to display:block?

javascript jquery html css css-transitions

Is there a way to animate display:none to display:block using CSS so that the hidden div slides down instead of abruptly appearing, or should I go about this a different way?

exec: "gcc": executable file not found in %PATH% when trying go build

windows go build hyperledger-fabric cgo

I am using Windows 10. When I tried to build Chaincode it reported this error