R: R Operators
Last updated: 2026-08-26
In the previous lesson, we learned about vectors and data types. In this lesson, we’ll dive into the “fundamentals” of R programming—operators. All R programs—from simple calculations to complex statistical models—are powered by operators at their core.
R’s set of operators is much the same as that of other languages, but there are two small details unique to R: integer division %% %/% and vectorized “broadcasting” behavior. In this lesson, we’ll thoroughly cover all the operators.
1. What You'll Learn
- 4 Major Categories of Arithmetic Operators (Basic Operations + Integer Division + Vector Operations)
- 3 Types of Comparison Operators (Numeric Comparison + String Comparison + Special Values)
- 3 Types of Logical Operators (AND, OR, NOT + Short-Circuit Evaluation)
- 5 unique R operators (
%in%%*%%/%%%:) - Operator Precedence (Avoiding Ambiguous Expressions)
- Common Computational Pitfalls in Real-World Applications
2. A Story About a Financial Calculation
(1) Pain Point: Calculating Profits by Hand
Bob is an accountant, and at the end of the month, he has to prepare the "branch sales report" for his manager:
The company has 5 branches, and this month's sales for each are
120, 150, 80, 200, 175ten thousand yuan. Calculate:
- Total Sales, Average Sales
- Profit per store (sales × 30% profit margin)
- Which stores have sales above average (require special attention)
- The integer portion of total profit (in 10,000 yuan, rounded down)
If you do the calculation by hand with a calculator, it takes 5 minutes; with Excel, you have to create a spreadsheet and enter formulas; with R—
(2) Solution using R
# 5 Sales at each branch(10,000 yuan)
sales <- c(120, 150, 80, 200, 175)
# All calculations are completed with a single line of code
total_sales <- sum(sales) # Total Sales 725
avg_sales <- mean(sales) # Average 145
profit <- sales * 0.3 # Profit Vector
high_sales <- sales[sales > avg_sales] # Branches with Above-Average Performance
profit_int <- profit %/% 1 # Integer Profit(Integer Division)
cat("Total Sales:", total_sales, "10,000 yuan\n")
cat("Average Sales:", avg_sales, "10,000 yuan\n")
cat("Total Profit(Integer):", sum(profit_int), "10,000 yuan\n")
cat("Above-average sales at branch locations:", high_sales, "\n")
10 lines of code to solve 5 computational tasks. That’s the power of the R operator—a single line of code equals a vector of operations.
3. Arithmetic Operators: Mathematical Calculations
(1) Basic Arithmetic Operators
| Operator | Meaning | Example | Result |
|---|---|---|---|
+ |
Add | 2 + 3 |
5 |
- |
Decrease | 5 - 2 |
3 |
* |
Multiply | 4 * 3 |
12 |
/ |
Remove | 7 / 2 |
3.5 |
^ or ** |
Power | 2 ^ 3 |
8 |
%% |
Subtraction (Remainder) | 7 %% 2 |
1 |
%/% |
Integer division | 7 %/% 2 |
3 |
(2) Integer Division: R-specific
# 7 / 2 = 3.5(Ordinary Division)
7 / 2
# [1] 3.5
# 7 %/% 2 = 3(Integer Division,Round down)
7 %/% 2
# [1] 3
# 7 %% 2 = 1 (Modulo, Remainder)
7 %% 2
# [1] 1
# Practical Application: Convert seconds to "hr:min:s"
total_seconds <- 3725
hours <- total_seconds %/% 3600
minutes <- (total_seconds %% 3600) %/% 60
seconds <- total_seconds %% 60
cat(hours, "hr", minutes, "min", seconds, "s\n")
# 1 hr 2 min 5 s
%% and %/% are extremely common in data processing: pagination (page %/% page_size), grouping (id %% 10—dividing into 10 groups based on the last digit), and time conversion.
(3) Vector Operations (Key Point)
Arithmetic operations in R are vectorized by default—this is one of R’s core strengths:
graph LR
A["x = 1, 2, 3"] --> C["+ 10"]
C --> D["11, 12, 13"]
E["x = 1, 2, 3"] --> F["+ y = 10, 20, 30"]
F --> G["11, 22, 33"]
style A fill:#cce5ff
style C fill:#d4edda
style D fill:#d4edda
# Vector + Scalar(Scalar"Broadcast"Go to each element)
c(1, 2, 3) + 10
# [1] 11 12 13
# Vector + Vector(Element-wise Operations)
c(1, 2, 3) + c(10, 20, 30)
# [1] 11 22 33
# When the lengths are different,"Loop"
c(1, 2, 3, 4) + c(10, 20)
# Warning: longer object length is not a multiple of shorter object length
# [1] 11 22 13 24
(4) Common Mathematical Functions
| Function | Purpose | Example |
|---|---|---|
abs() |
absolute value | abs(-5) → 5 |
sqrt() |
square root | sqrt(16) → 4 |
| Natural logarithm | → | |
log10() |
Common logarithm | log10(1000) → 3 |
log2() |
Base 2 | log2(8) → 3 |
exp() |
x to the power of e | exp(1) → 2.718 |
| Rounding up | round() |
|
floor() |
Round down | floor(3.7) → 3 |
| Round up | ceiling() |
ceiling(3.2) → 4 |
4. Comparison Operators: True/False Evaluation
(1) 6 Comparison Operators
| Operator | Meaning | Example | Result |
|---|---|---|---|
== |
equals | 5 == 5 |
TRUE |
!= |
Not equal to | 5 != 3 |
TRUE |
< |
Smaller than | 3 < 5 |
TRUE |
> |
Greater than | 5 > 3 |
TRUE |
<= |
Less than or equal to | 5 <= 5 |
TRUE |
>= |
Greater than or equal to | 5 >= 6 |
FALSE |
(2) ⚠️ Important Pitfall: Single Equal Sign vs. Double Equal Signs
# Single = It is an assignment
x = 5
# Double equal sign == It is a comparison
x == 5
# [1] TRUE
==; do not use =. R will not report a "=` error (since it is a valid assignment), but the result will be completely incorrect.
(3) String Comparison (Lexicographical Order)
# Character by ASCII Code Comparison
"apple" < "banana"
# [1] TRUE ← 'a' Coding < 'b'
# Numeric characters cannot be compared directly for size.(Character-by-character comparison,Not by value)
"9" > "10"
# [1] TRUE <- '9' (0x39) > '1' (0x31), Not a numerical comparison!
# The Correct Way to Do It:Convert to a number
as.numeric("9") > as.numeric("10")
# [1] FALSE
(4) Comparing Special Values
# NA The results of the comparison are NA(No TRUE/FALSE)
NA == 5
# [1] NA
# Decision NA Must use is.na()
is.na(NA)
# [1] TRUE
# NaN Comparison of
NaN == NaN
# [1] NA <- NaN == NaN is also NA!
is.na() specifically to check for this.
5. Logical Operators: Combining Conditions
(1) The 3 Basic Logical Operators
| Operator | Meaning | Example | Result |
|---|---|---|---|
& |
Element-wise AND | TRUE & FALSE |
FALSE |
| |
Element-wise OR | TRUE | FALSE |
TRUE |
! |
Cancel | !TRUE |
FALSE |
(2) Vectorization (Key Point)
x <- c(TRUE, TRUE, FALSE, FALSE)
y <- c(TRUE, FALSE, TRUE, FALSE)
# Elemental Level AND(Vectorization)
x & y
# [1] TRUE FALSE FALSE FALSE
# Elemental Level OR
x | y
# [1] TRUE TRUE TRUE FALSE
(3) Short-circuit evaluation: && and ||
| Operator | Behavior | Purpose |
|---|---|---|
& |
Element-wise AND, all calculations | Vector logical operations |
&& |
Short-circuit AND, only the first one counts | if condition |
| |
Element-wise OR, all calculations | Vector logical operations |
|| |
Short-circuit OR, only the first one counts | if condition |
# if Used in the conditions &&(Check only the first element)
if (x > 0 && x < 10) {
cat("x is between 0-10\n")
}
# Used in vector logic &(Check all elements)
c(1, 2, 11) > 0 & c(1, 2, 11) < 10
# [1] TRUE TRUE FALSE
if condition, you must use && and ||; do not use & or |. Otherwise, you may get unexpected results.
(4) Hands-On: Filtering with Combined Conditions
# Find 18-30 Adults aged
ages <- c(15, 22, 28, 35, 40, 19)
adults <- ages[ages >= 18 & ages <= 30]
adults
# [1] 22 28 19
# Identify the failing or perfect scores
scores <- c(58, 60, 75, 100, 45, 90)
special <- scores[scores < 60 | scores == 100]
special
# [1] 58 100 45
6. R-Specific Operators
(1) 5 Special Operators
| Operator | Meaning | Example | Result |
|---|---|---|---|
%in% |
Belongs to (Member Check) | 3 %in% c(1,2,3) |
TRUE |
%*% |
Matrix Multiplication | matrix(1:4,2) %*% matrix(1:4,2) |
Matrices |
%/% |
Integer division | 7 %/% 2 |
3 |
%% |
demold | 7 %% 2 |
1 |
: |
Sequence | 1:5 |
1 2 3 4 5 |
(2) A Detailed Explanation of %in%
%in% is the "core" operator for data filtering:
# Is the element in the vector?
c(1, 2, 3) %in% c(2, 4, 6)
# [1] FALSE TRUE FALSE <- 1, 3 Not here; 2 is
# Practical Application: Filter "Beijing, Shanghai, and Guangzhou" City
cities <- c("Beijing", "Shanghai", "Shenzhen", "Guangzhou", "Hangzhou")
target <- c("Beijing", "Shanghai", "Guangzhou")
cities[cities %in% target]
# [1] "Beijing" "Shanghai" "Guangzhou"
(3) Introduction to Matrix Multiplication %*%
# Basic Multiplication(Elemental Level)
matrix(1:4, 2, 2) * matrix(1:4, 2, 2)
# [,1] [,2]
# [1,] 1 9
# [2,] 4 16
# Matrix Multiplication(Linear Algebra)
matrix(1:4, 2, 2) %*% matrix(1:4, 2, 2)
# [,1] [,2]
# [1,] 7 15
# [2,] 10 22
7. Operator Precedence (Avoiding Ambiguity)
Operators in R have a specific order of precedence; using parentheses when in doubt is the safest approach:
| Priority | Operator | Description |
|---|---|---|
| High | ^ |
Power Operations |
| ↑ | * / |
Multiplication and Division |
| ↑ | + - |
Addition and Subtraction |
| ↑ | < <= > >= == != |
Compare |
| ↑ | ! |
Undo |
| ↑ | & && |
With |
| or | ||
| Low | <- |
Assignment |
# Without parentheses(By priority)
1 + 2 * 3
# [1] 7 <- 2*3=6, then +1
# Add parentheses(Clarify Intent)
(1 + 2) * 3
# [1] 9
# Be sure to use parentheses in complex expressions.
# Find 18-65 yrs
ages <- c(15, 25, 70, 30)
adults <- ages[ages >= 18 & ages <= 65] # ✅ Adding parentheses makes it clearer
8. Complete Example: Comprehensive Analysis of Branch Sales
Below is an example of a complete workflow that combines all the operators from this lesson.
▶ Example: Comprehensive Analysis of Branch Sales
# ============================================
# Comprehensive Analysis of Branch Sales
# Features:Analysis Using Various Operators 5 Sales Data by Branch
# ============================================
# 1. Prepare data
sales <- c(Beijing = 120, Shanghai = 150, Shenzhen = 80, Guangzhou = 200, Hangzhou = 175)
cat("Raw Sales Data(10,000 yuan):\n")
print(sales)
# 2. Arithmetic Operations:Total Sales,Average,Highest,Lowest
total <- sum(sales) # Sum
avg <- mean(sales) # Average
cat("\nTotal Sales:", total, "10,000 yuan\n")
cat("Average Sales:", avg, "10,000 yuan\n")
cat("Top Sales:", max(sales), "10,000 yuan\n")
cat("Minimum Sales:", min(sales), "10,000 yuan\n")
# 3. Arithmetic Operations:Profit(30% Profit Margin)
profit_rate <- 0.3
profit <- sales * profit_rate # Vector × Scalar
cat("\nTotal Profit:", sum(profit), "10,000 yuan\n")
# 4. Comparison + Logic:Identify branches that perform above average
is_above_avg <- sales > avg # Comparison:Which ones are above average?
cat("\nBranches with Above-Average Performance:")
print(sales[is_above_avg])
# 5. Comparison + Logic:Identify low-performing stores(< 1,000,000)
is_low <- sales < 100
cat("\nLow-Sales Stores(< 1,000,000):")
print(sales[is_low])
# 6. Integer Operations:Round Profit to the Nearest Whole Number + Grouping
profit_int <- profit %/% 1 # Integer Division(Round down)
cat("\nRound Profit to the Nearest Whole Number:")
print(profit_int)
# 7. %in% Filter
target_cities <- c("Beijing", "Shanghai", "Guangzhou")
selected <- sales[names(sales) %in% target_cities]
cat("\nSales in Target Cities:")
print(selected)
Expected Output (Excerpt):
Raw Sales Data(10,000 yuan):
Beijing Shanghai Shenzhen Guangzhou Hangzhou
120 150 80 200 175
Total Sales: 725 10,000 yuan
Average Sales: 145 10,000 yuan
Top Sales: 200 10,000 yuan
Minimum Sales: 80 10,000 yuan
Branches with Above-Average Performance:
Guangzhou Hangzhou
200 175
Total Profit: 217.5 10,000 yuan
Low-Sales Stores(< 1,000,000):
Shenzhen
80
❓ FAQ
%% and %/%?%% performs modulo division (returns the remainder), while %/% performs integer division (returns the quotient). For example, 7 %/% 2 = 3 (quotient) and 7 %% 2 = 1 (remainder). These are extremely common in pagination, time conversion, and grouping scenarios.x = 5 and x == 5?x = 5 is an assignment (assigning 5 to x), while x == 5 is a comparison (checking whether x equals 5). When writing a comparison, you must use ==; you cannot use =. Otherwise, it will become an assignment, and the result will be completely different.NA == 5 equal to?NA, not TRUE or FALSE. Any comparison result containing NA is NA. To check for NA, you must use the is.na() function.& or &&?& for vector logical operations (vectorized, evaluates all elements); use && for if conditions (short-circuit evaluation, evaluates only the first element). R does not distinguish between them as strictly as other languages, but using the wrong one can lead to incorrect if statements.%in%?%in% is the "belongs to" operator, which returns a logical vector. For example, 3 %in% c(1,2,3) returns TRUE. It is extremely common in data filtering: df$city %in% c("Beijing", "Shanghai") selects cities in the north and east.📖 Summary
- 4 major categories of operators: arithmetic (
+ - * / ^ %% %/%), comparison (== != < > <= >=), logical (& \| !), and assignment (<- = -> <<-) - R Features: Integer division
%%%/%, vectorized "broadcasting" behavior,%in%member checking - Vector + scalar = the scalar is broadcast to each element; vector + vector = element-wise operation
- Strings are compared based on their ASCII encoding (not their numerical values); numeric characters must be converted using
as.numeric(). iffor conditional operations&&\|\|(short-circuit evaluation), and&\|for vector logic (vectorization)- Operators have precedence; if you're unsure, use parentheses (readability > conciseness)
NA == 5The result isNA(not TRUE/FALSE); useis.na()to evaluate it
📝 Exercises
-
Basic Problem: Use R to calculate 1+2+3+...+100 using three different methods: ①
sum(1:100)② a loop ③ a formulan(n+1)/2. Verify that the results from all three methods match. -
Basic Exercise: Convert the number of seconds
total_seconds <- 3725to the "hours:minutes:seconds" format (refer to the integer division example in this lesson), and save a screenshot of the code and the output. -
Basic Problem: Use
%in%to find the even numbers in vectorc(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)(using the method described forc(2, 4, 6, 8, 10) %in%), and take a screenshot of the output. -
Advanced Problem: Generate the scores of 5 students
scores <- c(85, 92, 78, 95, 88)using comparison and logical operators to: ① Find the scores of 90 or higher; ② Find the scores between 60 and 89; ③ Count the number of students with scores of 80 or higher. -
Challenge: Write a script that uses
sample(1:100, 20)to randomly generate 20 numbers, and count: ① how many are even (%% 2 == 0); ② how many are divisible by 3 (%% 3 == 0); ③ how many are both even and divisible by 3 (&—combined condition); ④ the sum and average of these numbers.