Skip to content

R - Vectors

Vectors are the fundamental data structure in R. They are sequences of elements that share the same data type. There are two main types of vectors:

  • Atomic vectors: The simplest type, where all elements must be of the same type. The six basic atomic vector types are logical, integer, double (often called numeric), character, complex, and raw.
  • Lists: Recursive vectors that can contain elements of different types, including other lists.

This tutorial focuses on atomic vectors, which are the building blocks for most data analysis in R.

The most common way to create a vector is with the c() function, which stands for ‘combine’ or ‘concatenate’.

# A numeric vector (type 'double')
numeric_vector <- c(10.5, 5.2, 8.0, 15.1)
print(numeric_vector)
# An integer vector (note the 'L' suffix)
integer_vector <- c(1L, 6L, 10L)
print(integer_vector)
# A character vector
character_vector <- c("hello", "world", "R", "is", "fun")
print(character_vector)
# A logical vector
logical_vector <- c(TRUE, FALSE, TRUE, TRUE)
print(logical_vector)

When we execute the above code, it produces the following result:

[1] 10.5 5.2 8.0 15.1
[1] 1 6 10
[1] "hello" "world" "R" "is" "fun"
[1] TRUE FALSE TRUE TRUE

Because all elements of an atomic vector must be the same type, R will coerce or force elements to the most flexible type when you try to combine different types. The hierarchy is:

logical → integer → double → character

# Numeric and logical values are coerced to characters
mixed_vector <- c("red", 5, TRUE, 12.5)
print(mixed_vector)
# Check the type of the resulting vector
print(typeof(mixed_vector))

When we execute the above code, it produces the following result:

[1] "red" "5" "TRUE" "12.5"
[1] "character"

For numeric vectors, you can create sequences easily using the : operator or the seq() function.

# Create a sequence from 5 to 13 (inclusive)
seq_colon <- 5:13
print(seq_colon)
# Using seq() for more control
# Increment by 0.5
seq_by_step <- seq(from = 5, to = 9, by = 0.5)
print(seq_by_step)
# Create a sequence with a specific length
seq_by_length <- seq(from = 0, to = 100, length.out = 5)
print(seq_by_length)

When we execute the above code, it produces the following result:

[1] 5 6 7 8 9 10 11 12 13
[1] 5.0 5.5 6.0 6.5 7.0 7.5 8.0 8.5 9.0
[1] 0 25 50 75 100

You can access elements of a vector using square brackets []. R uses 1-based indexing, meaning the first element is at position 1.

days_of_week <- c("Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat")
# 1. Positional Indexing: Access the 2nd and 5th elements
subset_pos <- days_of_week[c(2, 5)]
print(subset_pos)
# 2. Logical Indexing: Access elements where a condition is TRUE
# Get all days except for the weekend
work_days_mask <- c(FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE)
subset_log <- days_of_week[work_days_mask]
print(subset_log)
# A more practical example of logical indexing
scores <- c(88, 92, 75, 99, 65)
passing_scores <- scores[scores > 80]
print(passing_scores)
# 3. Negative Indexing: Exclude elements at specific positions
# Get all days except Sunday (position 1) and Saturday (position 7)
subset_neg <- days_of_week[c(-1, -7)]
print(subset_neg)

When we execute the above code, it produces the following result:

[1] "Mon" "Thu"
[1] "Mon" "Tue" "Wed" "Thu" "Fri"
[1] 88 92 99
[1] "Mon" "Tue" "Wed" "Thu" "Fri"

R is a vectorized language, which means that operations are applied element-by-element. This is highly efficient and lets you avoid writing loops.

# Create two vectors
v1 <- c(3, 8, 4, 5, 0, 11)
v2 <- c(4, 11, 0, 8, 1, 2)
# Vector addition
add_result <- v1 + v2
print(add_result)
# Vector multiplication
multi_result <- v1 * v2
print(multi_result)
# Vector division (Note: division by zero results in 'Inf')
div_result <- v1 / v2
print(div_result)

When we execute the above code, it produces the following result:

[1] 7 19 4 13 1 13
[1] 12 88 0 40 0 22
[1] 0.7500000 0.7272727 Inf 0.6250000 0.0000000 5.5000000

If you perform an operation on two vectors of unequal length, R recycles the elements of the shorter vector. If the length of the longer vector is not a multiple of the shorter one, R will issue a warning.

v1 <- c(3, 8, 4, 5, 0, 11) # Length 6
v2 <- c(4, 11) # Length 2
# v2 is recycled to become c(4, 11, 4, 11, 4, 11)
add_result <- v1 + v2
print(add_result)
# Example with a warning
v3 <- c(1, 2, 3, 4, 5) # Length 5
v4 <- c(10, 20) # Length 2
# This will produce a warning because 5 is not a multiple of 2.
sub_result <- v3 - v4
print(sub_result)

When we execute the above code, it produces the following result:

[1] 7 19 8 16 4 22
[1] -9 -18 -7 -16 -5
Warning message:
In v3 - v4 : longer object length is not a multiple of shorter object length

The sort() function returns a new vector with the elements sorted. To get the indices that would sort the original vector, use the order() function.

v <- c(3, 8, 4, 5, 0, 11, -9, 304)
# Sort in ascending order
sort_result <- sort(v)
print(sort_result)
# Sort in descending order
revsort_result <- sort(v, decreasing = TRUE)
print(revsort_result)
# Sorting character vectors (case-sensitive by default)
v_char <- c("Red", "Blue", "yellow", "violet")
sort_char_result <- sort(v_char)
print(sort_char_result)
# Use order() to get sorting indices
order_indices <- order(v)
print(order_indices)
# Use the indices to sort the original vector
print(v[order_indices])

When we execute the above code, it produces the following result:

[1] -9 0 3 4 5 8 11 304
[1] 304 11 8 5 4 3 0 -9
[1] "Blue" "Red" "violet" "yellow"
[1] 7 5 1 3 4 2 6 8
[1] -9 0 3 4 5 8 11 304