The difference between = and <- finally explained

Let’s figure out what the difference between R’s assignment operators is.
Author

Albert Rapp

Published

March 16, 2025

In today’s blogpost, we take a look at one of the most questions about R: What’s the difference between <- and =? And as always, there’s a video version for you:

Similar assignment

Let’s first talk about the similarities of both operators. Obviously, both work as expected when you assign values to variable names.

a = 1
a
## [1] 1
a <- 2
a
## [1] 2

This even works in functions. Take this function, It always returns 5 whatever you stick into the argument a:

fct <- function(some_nmbr) {
  print(glue::glue('I received {some_nmbr}.'))
  5
}
fct(some_nmbr = 10)
## I received 10.
## [1] 5
fct(some_nmbr <- 10)
## I received 10.
## [1] 5

Boring function but have you seen how both = and <- worked the same? That’s why it’s easy to think that both operators are indeed the same. But that’s where different scoping comes in.

Scoping

The <- operator has a broader scope. It can create variables in the global environment when used inside functions, while = typically only assigns within the local function environment.

rm(some_nmbr) # make sure that some_nmbr doesn't currently 
              # exist in global env
fct(some_nmbr = 10)
## I received 10.
## [1] 5

Even though we assigned some_nmbr = inside the fct() the variable some_nmbr isn’t available once fct() completed.

some_nmbr
## Error in eval(expr, envir, enclos): object 'some_nmbr' not found

But watch what happens if we use <- instead of =:

fct(some_nmbr <- 10)
## I received 10.
## [1] 5
some_nmbr
## [1] 10

The function still tells us that it received 10 and returns 5. But this time the assignment some_nmbr <- also worked globally. That’s why we can access some_nmbr after fct() terminated.

Don’t believe me yet? Let’s try it again.

fct(some_nmbr <- 20)
## I received 20.
## [1] 5
some_nmbr
## [1] 20

See? Now, some_nmbr in the global environment is 20. Interestingly, this only takes effect, when the variable some_nmbr is actually used inside of fct(). Let’s create another function.

fct2 <- function(some_nmbr) {
  5
}

This function doesn’t actually use some_nmbr in this function body at all. Now watch what happens when we use the <- assignment again.

fct2(some_nmbr <- 30)
## [1] 5
some_nmbr
## [1] 20

some_nmbr still has the value from before and not the new one. Funny, isn’t it? Anyway, due to these possible side effects you might want to use = inside of function calls.

Powerup of <-

Now that we have seen that <- is in a sense more powerful than =, let me also mention another power-up. You see, you can make the <- into <<- and get an even more powerful operator. You can use the inside a function to define a variable outside the function in the global environment.

Check out this example.

power_fct <- function() {
  defined_inside <- 20
  5
}

This function first used the regular <- operator to define a variable called defined_inside. This variable cannot be accessed once power_fct() terminates.

power_fct()
## [1] 5
defined_inside
## Error in eval(expr, envir, enclos): object 'defined_inside' not found

But watch what happens when we make change <- to <<- inside of power_fct().

power_fct <- function() {
  defined_inside <<- 20
  5
}
power_fct()
## [1] 5
defined_inside
## [1] 20

Magical, isn’t it? This trick can be really handy sometimes but also quite dangerous. Make sure you use this trick only when you know what you want to do.


Enjoyed this blog post?

Here are three other ways I can help you:

3 Minutes Wednesdays

Every week, I share bite-sized R tips & tricks. Reading time less than 3 minutes. Delivered straight to your inbox. You can sign up for free weekly tips online.

Data Cleaning With R Master Class

This in-depth video course teaches you everything you need to know about becoming better & more efficient at cleaning up messy data. This includes Excel & JSON files, text data and working with times & dates. If you want to get better at data cleaning, check out the course page.

Insightful Data Visualizations for "Uncreative" R Users

This video course teaches you how to leverage {ggplot2} to make charts that communicate effectively without being a design expert. Course information can be found on the course page.