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_casefor variables and functions:retry_count,fit_model.- Dots in names are legal but dated: base R is full of
data.frame-era names likemy.data, but dots also carry meaning in R's S3 method system (print.data.frameis "the print method for data frames"), so new code avoids them. - No Hungarian prefixes, no camelCase - you'll see
camelCasein 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 <- valuecreates a variable; the community reserves=for function arguments.->andassign()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_caseand 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.