0Pricing
R Academy · Lesson

Assignment and Special Operators

Explore >, %in%, and the pipe operator in R.

Assignment and Special Operators is a free R Academy lesson on CoddyKit — lesson 3 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the R Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.

Assignment in R

R has several ways to assign values to variables. The most idiomatic is <-, which is the preferred style. You will also encounter = for assignment, though it behaves slightly differently in some contexts.

# Both assign a value, <- is preferred
name <- 'Alice'
age = 30
cat('Name:', name, '
')
cat('Age:', age, '
')

Left Arrow <- vs Equals =

<- always creates a variable in the current environment. = can also assign, but inside function calls it sets named arguments rather than creating a variable. This distinction matters.

# <- creates a variable outside function calls
x <- 42

# = inside function call sets argument, does NOT create x
mean(x = c(1, 2, 3))  # x is an arg here, not a variable

# But <- inside a function call DOES create a variable
mean(y <- c(1, 2, 3))  # y is now also in workspace
cat('y was created:', y, '
')

Right Assignment Operator ->

R also supports right-to-left assignment with ->. This assigns the left side to the name on the right. While valid, it is rarely used in practice since it reduces readability.

# Right assignment operator
100 -> max_score
'R Programming' -> course_name
cat('Max score:', max_score, '
')
cat('Course:', course_name, '
')

# Same as:
# max_score <- 100
# course_name <- 'R Programming'

Global Assignment with <<-

<<- assigns a value to a variable in the parent (enclosing) environment, not the local function environment. It is used inside functions to modify a variable that exists outside the function.

counter <- 0

increment <- function() {
  counter <<- counter + 1  # modifies the global counter
}

increment()
increment()
increment()
cat('Counter after 3 increments:', counter, '
')

The %in% Membership Operator

%in% tests whether each element on the left appears in the vector on the right. It returns a logical vector of the same length as the left operand. It is the cleanest way to test set membership in R.

fruits <- c('apple', 'banana', 'cherry', 'date', 'elderberry')

# Check membership
cat('Is mango in fruits?', 'mango' %in% fruits, '
')
cat('Is cherry in fruits?', 'cherry' %in% fruits, '
')

# Check multiple values at once
search <- c('banana', 'mango', 'date')
cat('Which are in fruits:', search %in% fruits, '
')

Filtering with %in%

%in% is particularly powerful when used to filter vectors or data frame rows. It lets you select elements that belong to a predefined set of allowed values.

countries <- c('USA', 'UK', 'Canada', 'Germany', 'France', 'Japan')
populations <- c(331, 67, 38, 83, 67, 126)  # millions

# Keep only G7 European members
g7_europe <- c('UK', 'Germany', 'France', 'Italy')
mask <- countries %in% g7_europe
cat('G7 Europe countries:', countries[mask], '
')
cat('Populations:', populations[mask], '
')

Matrix Multiplication with %*%

%*% performs true matrix multiplication (dot product), as opposed to * which multiplies element-by-element. For two matrices A (m x n) and B (n x p), the result is an (m x p) matrix.

A <- matrix(c(1, 2, 3, 4), nrow = 2, ncol = 2)
B <- matrix(c(5, 6, 7, 8), nrow = 2, ncol = 2)

cat('Matrix A:
')
print(A)
cat('Matrix B:
')
print(B)
cat('A %*% B (matrix mult):
')
print(A %*% B)
cat('A * B (element-wise):
')
print(A * B)

The Native Pipe |>

Introduced in R 4.1, the native pipe |> passes the result of the left-hand expression as the first argument of the right-hand function. It makes chains of operations much more readable.

# Without pipe
result1 <- round(sqrt(abs(-16)), 2)
cat('Without pipe:', result1, '
')

# With native pipe |>
result2 <- -16 |> abs() |> sqrt() |> round(2)
cat('With pipe:', result2, '
')

# Reading left to right: take -16, get abs, sqrt, then round

Pipe with Vectors

The native pipe |> is especially useful with vectors and numeric operations. You can chain transformations without creating intermediate variables, making your code cleaner and easier to follow.

scores <- c(88, 45, 92, 61, 73, 55, 84, 79)

# Chain: keep passing scores, then compute mean
passing_mean <- scores |> \(x) x[x >= 60] |> mean()
cat('Mean of passing scores:', round(passing_mean, 2), '
')

# Another chain: sort, reverse, take top 3
top3 <- scores |> sort(decreasing = TRUE) |> head(3)
cat('Top 3 scores:', top3, '
')

Custom Infix Operators

R allows you to define custom infix operators using the %name% syntax. This is how packages like dplyr define the %>% pipe. You can create your own for domain-specific operations.

# Define a custom infix operator for 'not in'
'%notin%' <- function(x, table) !(x %in% table)

cities <- c('Paris', 'London', 'Berlin', 'Tokyo', 'Sydney')
exclude <- c('Tokyo', 'Sydney')

cat('Cities not in exclude list:', cities[cities %notin% exclude], '
')

Operator Quick Reference

Here is a summary of the special operators covered in this lesson:

  • <- — standard assignment (preferred)
  • = — assignment (also used for function args)
  • <<- — global/parent environment assignment
  • %in% — membership test
  • %*% — matrix multiplication
  • |> — native pipe (R 4.1+)
  • %name% — custom infix operator syntax
# Demonstrate %in% as a filter
all_nums <- 1:20
special <- c(3, 6, 9, 12, 15, 18)
cat('Multiples of 3 up to 20:', all_nums[all_nums %in% special], '
')

# Demonstrate pipe
1:10 |> mean() |> cat('
')

Quick Check

What does the %in% operator return when used as c(2, 4, 6) %in% c(1, 2, 3)?

Recap: Special Operators

Well done! Here are the key takeaways from this lesson:

  • Use <- for assignment — it is the R convention
  • = works for assignment but is ambiguous inside function calls
  • <<- modifies a variable in the parent (global) environment from inside a function
  • %in% is the cleanest way to test set membership in R
  • %*% performs matrix multiplication (not element-wise)
  • The native pipe |> (R 4.1+) chains function calls left-to-right for readable code
  • Custom operators follow the %name% pattern
# Pipe + %in% combined
data <- c(5, 12, 3, 8, 15, 7, 20, 1)
valid_range <- 5:15

result <- data |> \(x) x[x %in% valid_range] |> sort()
cat('Values in range 5-15:', result, '
')

Frequently asked questions

Is the “Assignment and Special Operators” lesson free?

Yes — the full text of “Assignment and Special Operators” is free to read here on the web, and the R Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the R Academy course, upgrade to CoddyKit PRO.

What will I learn in “Assignment and Special Operators”?

Explore >, %in%, and the pipe operator in R. You practise R Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.

Do I need any experience to start R Academy?

No prior experience is required. R Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 3 of 4, so you can start here or from the beginning and move at your own pace.

How long does the “Assignment and Special Operators” lesson take?

Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.

Can I write and run code in this R Academy lesson?

Yes. Every R Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.

All lessons in this course

  1. Arithmetic and Comparison Operators
  2. Logical Operators and Boolean Logic
  3. Assignment and Special Operators
  4. Operator Precedence and Complex Expressions
← Back to R Academy