Menu

R Variables and Assignment: <-, =, and assign()

How to create variables in R with the <- arrow, when = is required instead, the naming rules, and how to list and remove variables with ls() and rm().

This page includes runnable editors - edit, run, and see output instantly.

How to Create a Variable in R

A variable in R is a name attached to a value. You create one with the assignment arrow <-: the name goes before the arrow, the value after it.

Three variables, three different kinds of value, and no type declarations anywhere - R infers the type from the value itself (more on that in data types). Once a variable exists, you use it anywhere you'd use the value:

Reassignment works the same way. A variable happily switches to a new value - even a new type - the moment you assign again:

R didn't complain about a string becoming a number. That flexibility is convenient, but if a variable's meaning shifts halfway through a script, that's usually your cue to pick a new name instead.

Why R Uses <- Instead of =

Here's the question everyone asks: age = 30 also works, so why does every R book, style guide, and package use the arrow?

Because = in R is two different things depending on where it appears. At the top level it assigns. Inside a function call it matches an argument by name - and does not create a variable:

If you tried mean(values, na.rm <- TRUE) you'd accidentally create a global variable called na.rm and pass TRUE positionally - legal, wrong, and hard to spot. The convention that keeps this readable is simple:

  • <- always means assignment.
  • = always means "this argument gets this value" inside a call to a function.

Follow that split and every line of R you read tells you at a glance whether something is being created or passed. It's the single most universal style rule in the R world - RStudio even gives <- its own keyboard shortcut (Alt+-).

The Rarely-Used Cousins: ->, =, and assign()

R has two more ways to assign, both worth recognizing even if you rarely write them.

The reversed arrow -> assigns in the other direction - value first, name last:

You'll occasionally see it at the end of a long pipeline ("compute all this, then store it"), but most style guides say to avoid it: readers scan the start of a line for the name being defined.

assign() creates a variable from a string, which means the name can be built at runtime:

This looks clever and is almost always the wrong tool - a set of numbered variables is really a vector or a list wearing a disguise. Reach for assign() only when a name genuinely must be computed; its partner get("score") reads a variable by string name.

Naming Rules

R accepts names that:

  • Contain letters, digits, dots (.), and underscores (_).
  • Start with a letter, or with a dot not followed by a digit.
  • Are not reserved words (if, for, TRUE, NULL, function, and a handful more).

So these are all valid:

And these are not:

  • 2nd_user - can't start with a digit.
  • _temp - can't start with an underscore either (unlike Python).
  • user-name - a hyphen is subtraction, not a name character.
  • TRUE - reserved word.

Names are case-sensitive: total, Total, and TOTAL are three unrelated variables, and R will not warn you when you typo one into existence.

Listing and Removing: ls() and rm()

Every variable you create lands in the workspace (the global environment). ls() lists what's there, and rm() removes things:

Two details worth knowing. First, rm(list = ls()) wipes the entire workspace - handy at the top of an exploratory session, destructive anywhere else. Second, names that start with a dot (like .cache) are hidden from ls() unless you call ls(all.names = TRUE) - the same convention as hidden files on Unix.

Naming Conventions: Use snake_case

Beyond the hard rules, the modern R community (and the tidyverse style guide) has settled on conventions:

  • lower_snake_case for variables and functions: retry_count, fit_model.
  • Dots in names are legal but dated: base R is full of data.frame-era names like my.data, but dots also carry meaning in R's S3 method system (print.data.frame is "the print method for data frames"), so new code avoids them.
  • No Hungarian prefixes, no camelCase - you'll see camelCase in older packages, but snake_case is where the ecosystem has landed.
  • R has no real constants; the convention is to name would-be constants in caps (MAX_RETRIES <- 5) and simply not reassign them.

Pick descriptive names and stay consistent. avg_score costs four more keystrokes than as and saves every future reader a trip back up the script.

What You Take Away

  • name <- value creates a variable; the community reserves = for function arguments.
  • -> and assign() exist; you'll read them more often than you should write them.
  • Names use letters, digits, dots, and underscores; they can't start with a digit or underscore, and they're case-sensitive.
  • ls() shows the workspace, rm() cleans it up.
  • Write snake_case and your code will look like the R everyone else writes today.

Next up: what kinds of values those variables actually hold - numeric, integer, character, and logical.

Frequently Asked Questions

How do you create a variable in R?

Write the name, the assignment arrow <-, and the value: age <- 30. R figures out the type from the value - there is no declaration step. age = 30 also works at the top level, but the community convention is <-.

What is the difference between <- and = in R?

At the top level of a script they do the same thing. Inside a function call they don't: mean(x, na.rm = TRUE) uses = to match an argument by name, not to create a variable. Because = plays both roles depending on context, R style guides reserve <- for assignment and = for arguments.

How do you delete a variable in R?

rm(x) removes the variable x from the workspace. rm(list = ls()) removes everything - useful for a clean slate, dangerous mid-analysis. ls() lists what currently exists.

Can R variable names contain dots?

Yes - my.data is a perfectly legal name, and older R code uses dots everywhere. Modern style prefers underscores (my_data) because dots also mean something in R's S3 method system, which makes dotted names ambiguous to read.

Coddy programming languages illustration

Learn to code with Coddy

GET STARTED