# Indexing

Author

Marie-Hélène Burle

This section covers indexing from the various data structures.

## Indexing atomic vectors

Here is an example with an atomic vector of size one:

Indexing in R starts at `1` and is done with square brackets next to the element to index:

``````x <- 2
x``````
``[1] 2``
``x[1]``
``[1] 2``

What happens if we index out of range?

``x[2]``
``[1] NA``

Example for an atomic vector with multiple elements:

``````x <- c(2, 4, 1)
x``````
``[1] 2 4 1``
``x[2]``
``[1] 4``
``x[2:4]``
``[1]  4  1 NA``

### Modifying mutable objects

Indexing also allows to modify some of the values of mutable objects:

``x``
``[1] 2 4 1``
``````x[2] <- 0
x``````
``[1] 2 0 1``

### Copy-on-modify

Not all languages behave the same when you assign the same mutable object to several variables, then modify one of them.

#### In Python: no copy-on-modify

Don’t try to run this code in R. This is for information only.

`Python`
``````a = [1, 2, 3]
b = a
b``````
``[1, 2, 3]``
`Python`
``````a[0] = 4           # In Python, indexing starts at 0
a``````
``[4, 2, 3]``
`Python`
``b``
``[4, 2, 3]``

Modifying `a` also modifies `b`: this is because no copy is made when you modify `a`. If you want to keep `b` unchanged, you need to assign an explicit copy of `a` to it with `b = copy.copy(a)`.

#### In R: copy-on-modify

``````a <- c(1, 2, 3)
b <- a
b``````
``[1] 1 2 3``
``````a[1] <- 4          # In R, indexing starts at 1
a``````
``[1] 4 2 3``
``b``
``[1] 1 2 3``

Here, the default is to create a new copy in memory when `a` is transformed so that `b` remains unchanged.

## Indexing matrices and arrays

``````x <- matrix(1:12, nrow = 3, ncol = 4)
x``````
``````     [,1] [,2] [,3] [,4]
[1,]    1    4    7   10
[2,]    2    5    8   11
[3,]    3    6    9   12``````
``x[2, 3]``
``[1] 8``
``````x <- array(as.double(1:24), c(3, 2, 4))
x``````
``````, , 1

[,1] [,2]
[1,]    1    4
[2,]    2    5
[3,]    3    6

, , 2

[,1] [,2]
[1,]    7   10
[2,]    8   11
[3,]    9   12

, , 3

[,1] [,2]
[1,]   13   16
[2,]   14   17
[3,]   15   18

, , 4

[,1] [,2]
[1,]   19   22
[2,]   20   23
[3,]   21   24``````
``x[2, 1, 3]``
``[1] 14``

## Indexing lists

``````x <- list(2L, 3:8, c(2, 1), FALSE, "string")
x``````
``````[[1]]
[1] 2

[[2]]
[1] 3 4 5 6 7 8

[[3]]
[1] 2 1

[[4]]
[1] FALSE

[[5]]
[1] "string"``````

Indexing a list returns a list:

``x[3]``
``````[[1]]
[1] 2 1``````
``typeof(x[3])``
``[1] "list"``

To extract elements of a list, double square brackets are required:

``x[[3]]``
``[1] 2 1``
``typeof(x[[3]])``
``[1] "double"``

Try to extract the number `7` from this list.

## Indexing data frames

``````x <- data.frame(
var = c(2.9, 3.1, 4.5)
)
x``````
``````  country var
2     USA 3.1
3  Mexico 4.5``````

A data frame is a list of atomic vectors representing the various columns:

``x[1]``
``````  country
2     USA
3  Mexico``````
``typeof(x[1])``
``[1] "list"``
``x[[1]]``
``[1] "Canada" "USA"    "Mexico"``
``typeof(x[[1]])``
``[1] "character"``

Indexing dataframes can also be done using the column names:

``x\$country``
``[1] "Canada" "USA"    "Mexico"``
``identical(x[[1]], x\$country)``
``[1] TRUE``