R Programming / Language and data foundations / Lesson 2
Vectors, types, coercion, and recycling
Make R’s vector rules explicit so convenient arithmetic does not silently change data meaning.
On this page
Lesson goals
- Inspect atomic types and intentional conversion.
- Predict recycling in elementwise arithmetic.
- Protect scalar and pairwise contracts with validation.
Atomic vectors use one underlying type
A base atomic vector stores elements under one common type, such as logical, integer, double, or character. The L suffix denotes an integer literal; ordinary numeric literals such as 2 are commonly doubles. Combining different types can coerce values to a common representation. This behavior is useful when deliberate and dangerous when an accidental text token converts a whole numeric column to character. Type is distinct from class and other attributes, which later lessons examine. Check typeof, length, and representative values before assuming that a printed digit is stored as a numeric measurement.
Conversion needs an interpretation policy
The first fixture combines integer values with a character token, producing a character vector. Converting those particular strings back to numeric succeeds because the tokens are known and simple. Real import code must decide how to handle blanks, decimal conventions, units, and invalid text. A coercion warning should trigger inspection rather than automatic suppression. Converting a factor with as.numeric has another meaning: it returns internal category codes, not parsed labels. Keep the original token alongside the converted value when diagnosing failures, and count newly introduced missing values so a cleanup step cannot silently erase observations.
x <- c(2L, 4L, 6L)
combined <- c(x, "8")
cat("x type=", typeof(x), "; combined type=", typeof(combined), "\n", sep = "")
cat("sum=", sum(x), "; count=", length(x), "\n", sep = "")
cat("converted=", paste(as.numeric(combined), collapse = ","), "\n", sep = "")
x type=integer; combined type=character
sum=12; count=3
converted=2,4,6,8
Atomic vectors have a common type; explicit conversion is appropriate here only because every string is a known numeric token.
Elementwise operations can recycle values
Base vector arithmetic repeats a shorter vector to align with a longer one. The second fixture adds a two-element offset pattern to four values. Because the shorter length divides the longer exactly, this recycling can occur without a warning. That makes absence of a warning a weak test of intended pairing. A scalar offset applied to every observation is often meaningful; a two-sensor offset pattern applied to arbitrary rows may not be. Write whether the operation expects one scalar, one value per observation, or an explicit repeating pattern before choosing the expression.
x <- c(10, 20, 30, 40)
offset <- c(1, 2)
cat("recycled=", paste(x + offset, collapse = ","), "\n", sep = "")
add_same_length <- function(a, b) {
stopifnot(is.numeric(a), is.numeric(b), length(a) == length(b))
a + b
}
cat("paired=", paste(add_same_length(c(10, 20), c(1, 2)), collapse = ","), "\n", sep = "")
recycled=11,22,31,42
paired=11,22
Base arithmetic recycles the shorter vector; an explicit equal-length contract forbids that behavior for paired measurements.
Distinguish elementwise arithmetic and aggregation
The operators + and * work element by element under their documented rules, while sum and mean aggregate. For matrices, * still means elementwise multiplication; %*% is matrix multiplication. Comparisons also return logical vectors that can become selection masks. A function intended to receive one threshold should reject a vector of thresholds rather than accidentally recycling it. Empty vectors introduce a separate boundary: an empty sum can have an identity value while an empty mean has no observed average. Validate the intended input size and do not treat every mathematically defined empty result as a meaningful domain answer.
Numeric equality has several meanings
Floating-point arithmetic can represent values approximately, so exact equality is not always the right correctness check for computed measurements. identical tests strict object identity properties, including relevant type differences; all.equal provides a comparison that can describe approximate differences and is commonly wrapped in isTRUE for a Boolean decision. Choose tolerances from units and the calculation rather than copying an arbitrary constant. Keep integer counts, category identifiers, and approximate physical measurements conceptually separate. The supplied fixtures avoid ambiguous formatting and demonstrate exact small arithmetic; no R runtime execution or broad numerical-accuracy benchmark was performed.
Common errors and fixes
A numeric column becomes character
- Why it happens
- A text token caused coercion to a common atomic type.
- How to fix it
- Inspect original tokens and convert under an explicit parsing policy.
- Prevent it next time
- Validate types after import and count conversion failures.
Paired arithmetic gives plausible but wrong values
- Why it happens
- A shorter vector recycled without violating length divisibility.
- How to fix it
- Require matching lengths or an explicitly permitted scalar.
- Prevent it next time
- Test unequal lengths even when one divides the other.
Category labels turn into unexpected integers
- Why it happens
- as.numeric was applied directly to a factor.
- How to fix it
- Use the labels and a justified parsing or mapping policy.
- Prevent it next time
- Distinguish factors from numeric measurements before conversion.
Check your understanding
1. Predict c(1,2,3,4,5,6) + c(10,20,30). Should a pairwise function accept it?
Show worked solution
Base arithmetic repeats the offsets and yields 11,22,33,14,25,36. A function promising one matching offset per observation should reject the unequal lengths even though recycling is exact and need not warn. A deliberate repeating-pattern function could accept it with that contract.
2. Why is suppressing a conversion warning an incomplete repair?
Show worked solution
It hides evidence that some tokens did not fit the numeric interpretation without restoring their meaning. Inspect the failed tokens, decide whether they are invalid or represent another convention, and report missingness introduced by conversion. Only then choose a validated normalization or rejection policy.
Key takeaways
- Atomic vectors have a common underlying type.
- Exact recycling can be silent and still wrong for the task.
- Choose equality checks according to type, units, and precision.