What is the difference between =, “<-" and "<<-" in R

Symbol of coding on a computer screen

An introduction to using the assignment operators =, “<-” and “<<-” in R


Assignment Operators in R

The assignment operators = , <-, and <<- in R assign a value to a named object. For example:

x = 5

myVariable <- 'Hello World'

y <<- 1:5
Programming Environments in R

When variables and functions are defined and assigned values using assignment operators in R, they are created in an ‘environment’. Environments are like place-holders to contain the programming objects.

  • Environments are nested so that there are environments within other environments.
  • An environment which contains another environment is referred to as the parent environment.
  • The top level environment where objects are stored is the global environment.
  • The global environment is also enclosed in another environment called the empty environment, which, as its name suggests, cannot contain any objects.

A function has its own environment. Depending on which assignment operator(s) is used inside the function, its object(s) may or may not be referred to (found) outside of the function itself.

Each of the assignment operators <-, <<- and = has a different scope (effect) depending on the environment in which it is used.

Compare <- and = in the global environment in R

  • In these two examples, we’re defining variables a and b to equal the values 1 through 5 (1,2,3,4,5).
  • We haven’t specified which environment R should create them in, so they have been put into the global environment by default. The inbuilt function environment() returns the name of the current environment.
  • We can see below that there is no difference between using <- or =. When we call the variables a and b, their values are returned. They have both been ‘found’ and can be referred to.
# define variable 'a' using '='
> a = 1:5
> a
[1] 1 2 3 4 5

# define b using '<-'
> b <- 1:5
> b
[1] 1 2 3 4 5

> environment()
<environment: R_GlobalEnv>

Compare <-,<<-, and = in a function environment in R

EXAMPLE 1: ‘<-‘ vs ‘=’

For the first example, we’ll use the inbuilt median() function in base R which takes x as its argument. For example, use the function to find the median value of 1,2,3,4,5:

# assign the value to x using '='
> median(x = 1:5)
[1] 3

If we use ‘=’ inside the median() function this restricts assignment of the value to x to exist only within the function — if we now try to ‘call’ the output of x, it is not found outside of our median() function statement.

> x
Error: object 'x' not found

However, if we use the assignment operator ‘<-‘ within the median() function, the value of x is defined in the parent environment as well as in the function environment, and can be ‘called’ outside of the median() function statement. In this instance the parent environment is the global environment (the default environment).

# assign the value to x using '<-'
> median(x <- 1:9)
[1] 5
> x
[1] 1 2 3 4 5 6 7 8 9

To ‘clear’ or ‘remove’ a single variable in R, use rm(variableName). So to ‘clear’ the value assigned to ‘x’ and remove the object ‘x’ from the environment:

> rm(x)
> x
Error: object 'x' not found
EXAMPLE 2: ‘<-‘, ‘=’ and ‘<<-‘

In these examples below, when we refer to the ‘parent’ environment we are actually within the global environment (because that is the default environment). The examples below would have different results if we had defined different levels of nested environments, or if we were creating a nested function.

For the second example, we’re going to create our own simple functionnewFun‘ to illustrate the effect of using the three different assignment operators ‘<-‘, ‘=’ and ‘<<-‘ .

Our function newFun takes two arguments ‘d‘ and ‘e‘, assigns the value 30 to d, and then multiplies d and e together.

# assign value to d using '='
> newFun <- function(d,e) {
 	result <- (d=30) * e
 	print(result)
 }

# if the function is applied to the values for d=1 and e=2, d is forced to equal 30,
so the result is 60 (30 * 2)

> newFun(1,2)
[1] 60

# if we call d from within the parent environment (outside of the function environment),
it cannot be found, because we used the assignment operator '=' 

> d
Error: object 'd' not found

We’ll repeat the above, now using <- instead of =. As we’ll see, there is no difference, they both have the same ‘scope’ of defining d only within the function itself.

# assign value to d using '<-'
> newFun <- function(d,e) {
 	result <- (d <- 30) * e
 	print(result)
 }

# if the function is applied to the values for d=1 and e=2, d is forced to equal 30,
so the result is 60
> newFun(1,2)
[1] 60

# if we call d from within the parent environment,
it cannot be found, because we used '<-' 
> d
Error: object 'd' not found

For the third run, we’re going to use <<-. This time, by using ‘<<-‘ the variable d is created in the parent environment and we can call it outside of the function environment.

# assign value to d using '<<-'
> newFun <- function(d,e) {
 	result <- (d <<- 30) * e
 	print(result)
 }

> newFun(2,3)
[1] 90
 
> d
[1] 30

So, we can see from the above that the different assignment operators have different scopes depending on the environment (context) in which they are used. The operator <<- is normally only used within a function environment.

Direction of assignment – leftwards and rightwards forms

The assignment forms <- and <<- are described as ‘leftwards’ because they assign values to the object on the left hand side of the statement.

They can also be used in their ‘rightwards’ forms -> and ->>, where the object on the right of the statement is being assigned to.

> 'Hello World!' -> x

However, this is not generally regarded as best practice – see Google’s R Style guide.

Use of ‘=’ to assign values

The operator ‘=’ will be used to assign values to variables and arguments in functions and other contexts, e.g. when defining the inbuilt variables of ‘height’ and ‘width’ for a map output, or assigning variables to the x and y values of a ggplot chart:

# define the map dimensions of a leaflet map
  leafletOutput("londonMap",
	height=600,
	width="100%")

# assign the data table variables of make and mileage to the x and y axes
  ggplot(cars_mpg, aes(x=make, y=mileage))