## Introduction

Given an R object, we may require separate analysis for one or more parts of the data contained in it. The process of obtaining these parts of the data from a given object is called `subsetting`

.

## Remarks

**Missing values:**

Missing values (`NA`

s) used in subsetting with `[`

return `NA`

since a `NA`

index

picks an unknown element and so returns NA in the corresponding element..

The "default" type of `NA`

is "logical" (`typeof(NA)`

) which means that, as any "logical" vector used in subsetting, will be **recycled** to match the length of the subsetted object. So `x[NA]`

is equivalent to `x[as.logical(NA)]`

which is equivalent to `x[rep_len(as.logical(NA), length(x))]`

and, consequently, it returns a missing value (`NA`

) for each element of `x`

. As an example:

```
x <- 1:3
x[NA]
## [1] NA NA NA
```

While indexing with "numeric"/"integer" `NA`

picks a single `NA`

element (for each `NA`

in index):

```
x[as.integer(NA)]
## [1] NA
x[c(NA, 1, NA, NA)]
## [1] NA 1 NA NA
```

**Subsetting out of bounds:**

The `[`

operator, with one argument passed, allows indices that are `> length(x)`

and returns `NA`

for atomic vectors or `NULL`

for generic vectors. In contrast, with `[[`

and when `[`

is passed more arguments (i.e. subsetting out of bounds objects with `length(dim(x)) > 2`

) an error is returned:

```
(1:3)[10]
## [1] NA
(1:3)[[10]]
## Error in (1:3)[[10]] : subscript out of bounds
as.matrix(1:3)[10]
## [1] NA
as.matrix(1:3)[, 10]
## Error in as.matrix(1:3)[, 10] : subscript out of bounds
list(1, 2, 3)[10]
## [[1]]
## NULL
list(1, 2, 3)[[10]]
## Error in list(1, 2, 3)[[10]] : subscript out of bounds
```

The behaviour is the same when subsetting with "character" vectors, that are not matched in the "names" attribute of the object, too:

```
c(a = 1, b = 2)["c"]
## <NA>
## NA
list(a = 1, b = 2)["c"]
## <NA>
## NULL
```

**Help topics:**

See `?Extract`

for further information.

## Atomic vectors

Atomic vectors (which excludes lists and expressions, which are also vectors) are subset using the `[`

operator:

```
# create an example vector
v1 <- c("a", "b", "c", "d")
# select the third element
v1[3]
## [1] "c"
```

The `[`

operator can also take a vector as the argument. For example, to select the first and third elements:

```
v1 <- c("a", "b", "c", "d")
v1[c(1, 3)]
## [1] "a" "c"
```

Some times we may require to omit a particular value from the vector. This can be achieved using a negative sign(`-`

) before the index of that value. For example, to omit to omit the first value from v1, use `v1[-1]`

. This can be extended to more than one value in a straight forward way. For example, `v1[-c(1,3)]`

.

```
> v1[-1]
[1] "b" "c" "d"
> v1[-c(1,3)]
[1] "b" "d"
```

On some occasions, we would like to know, especially, when the length of the vector is large, index of a particular value, if it exists:

```
> v1=="c"
[1] FALSE FALSE TRUE FALSE
> which(v1=="c")
[1] 3
```

If the atomic vector has names (a `names`

attribute), it can be subset using a character vector of names:

```
v <- 1:3
names(v) <- c("one", "two", "three")
v
## one two three
## 1 2 3
v["two"]
## two
## 2
```

The `[[`

operator can also be used to index atomic vectors, with differences in that it accepts a indexing vector with a length of one and strips any names present:

```
v[[c(1, 2)]]
## Error in v[[c(1, 2)]] :
## attempt to select more than one element in vectorIndex
v[["two"]]
## [1] 2
```

Vectors can also be subset using a logical vector. In contrast to subsetting with numeric and character vectors, the logical vector used to subset has to be equal to the length of the vector whose elements are extracted, so if a logical vector `y`

is used to subset `x`

, i.e. `x[y]`

, if `length(y) < length(x)`

then `y`

will be recycled to match `length(x)`

:

```
v[c(TRUE, FALSE, TRUE)]
## one three
## 1 3
v[c(FALSE, TRUE)] # recycled to 'c(FALSE, TRUE, FALSE)'
## two
## 2
v[TRUE] # recycled to 'c(TRUE, TRUE, TRUE)'
## one two three
## 1 2 3
v[FALSE] # handy to discard elements but save the vector's type and basic structure
## named integer(0)
```

## Data frames

**Subsetting a data frame into a smaller data frame** can be accomplished the same as subsetting a list.

```
> df3 <- data.frame(x = 1:3, y = c("a", "b", "c"), stringsAsFactors = FALSE)
> df3
## x y
## 1 1 a
## 2 2 b
## 3 3 c
> df3[1] # Subset a variable by number
## x
## 1 1
## 2 2
## 3 3
> df3["x"] # Subset a variable by name
## x
## 1 1
## 2 2
## 3 3
> is.data.frame(df3[1])
## TRUE
> is.list(df3[1])
## TRUE
```

**Subsetting a dataframe into a column vector** can be accomplished using double brackets [[ ]] or the dollar sign operator $.

```
> df3[[2]] # Subset a variable by number using [[ ]]
## [1] "a" "b" "c"
> df3[["y"]] # Subset a variable by name using [[ ]]
## [1] "a" "b" "c"
> df3$x # Subset a variable by name using $
## [1] 1 2 3
> typeof(df3$x)
## "integer"
> is.vector(df3$x)
## TRUE
```

**Subsetting a data as a two dimensional matrix** can be accomplished using `i`

and `j`

terms.

```
> df3[1, 2] # Subset row and column by number
## [1] "a"
> df3[1, "y"] # Subset row by number and column by name
## [1] "a"
> df3[2, ] # Subset entire row by number
## x y
## 2 2 b
> df3[ , 1] # Subset all first variables
## [1] 1 2 3
> df3[ , 1, drop = FALSE]
## x
## 1 1
## 2 2
## 3 3
```

Note: Subsetting by `j`

(column) alone simplifies to the variable's own type, but subsetting by `i`

alone returns a `data.frame`

, as the different variables may have different types and classes. Setting the `drop`

parameter to `FALSE`

keeps the data frame.

```
> is.vector(df3[, 2])
## TRUE
> is.data.frame(df3[2, ])
## TRUE
> is.data.frame(df3[, 2, drop = FALSE])
## TRUE
```

## Elementwise Matrix Operations

Let A and B be two matrices of same dimension. The operators `+`

,`-`

,`/`

,`*`

,`^`

when used with matrices of same dimension perform the required operations on the corresponding elements of the matrices and return a new matrix of the same dimension. These operations are usually referred to as element-wise operations.

Operator | A op B | Meaning |
---|---|---|

+ | A + B | Addition of corresponding elements of A and B |

- | A - B | Subtracts the elements of B from the corresponding elements of A |

/ | A / B | Divides the elements of A by the corresponding elements of B |

* | A * B | Multiplies the elements of A by the corresponding elements of B |

^ | A^(-1) | For example, gives a matrix whose elements are reciprocals of A |

For "true" matrix multiplication, as seen in *Linear Algebra*, use `%*%`

. For example, multiplication of A with B is: `A %*% B`

. The dimensional requirements are that the `ncol()`

of `A`

be the same as `nrow()`

of `B`

**Some Functions used with Matrices**

Function | Example | Purpose |
---|---|---|

nrow() | nrow(A) | determines the number of rows of A |

ncol() | ncol(A) | determines the number of columns of A |

rownames() | rownames(A) | prints out the row names of the matrix A |

colnames() | colnames(A) | prints out the column names of the matrix A |

rowMeans() | rowMeans(A) | computes means of each row of the matrix A |

colMeans() | colMeans(A) | computes means of each column of the matrix A |

upper.tri() | upper.tri(A) | returns a vector whose elements are the upper |

triangular matrix of square matrix A | ||

lower.tri() | lower.tri(A) | returns a vector whose elements are the lower |

triangular matrix of square matrix A | ||

det() | det(A) | results in the determinant of the matrix A |

solve() | solve(A) | results in the inverse of the non-singular matrix A |

diag() | diag(A) | returns a diagonal matrix whose off-diagnal elemts are zeros and |

diagonals are the same as that of the square matrix A | ||

t() | t(A) | returns the the transpose of the matrix A |

eigen() | eigen(A) | retuens the eigenvalues and eigenvectors of the matrix A |

is.matrix() | is.matrix(A) | returns TRUE or FALSE depending on whether A is a matrix or not. |

as.matrix() | as.matrix(x) | creates a matrix out of the vector x |

## Lists

A list can be subset with `[`

:

```
l1 <- list(c(1, 2, 3), 'two' = c("a", "b", "c"), list(10, 20))
l1
## [[1]]
## [1] 1 2 3
##
## $two
## [1] "a" "b" "c"
##
## [[3]]
## [[3]][[1]]
## [1] 10
##
## [[3]][[2]]
## [1] 20
l1[1]
## [[1]]
## [1] 1 2 3
l1['two']
## $two
## [1] "a" "b" "c"
l1[[2]]
## [1] "a" "b" "c"
l1[['two']]
## [1] "a" "b" "c"
```

Note the result of `l1[2]`

is still a list, as the `[`

operator selects elements of a list, returning a smaller list. The `[[`

operator extracts list elements, returning an object of the type of the list element.

Elements can be indexed by number or a character string of the name (if it exists). Multiple elements can be selected with `[`

by passing a vector of numbers or strings of names. Indexing with a vector of `length > 1`

in `[`

and `[[`

returns a "list" with the specified elements and a recursive subset (if available), *respectively*:

```
l1[c(3, 1)]
## [[1]]
## [[1]][[1]]
## [1] 10
##
## [[1]][[2]]
## [1] 20
##
##
## [[2]]
## [1] 1 2 3
```

Compared to:

```
l1[[c(3, 1)]]
## [1] 10
```

which is equivalent to:

```
l1[[3]][[1]]
## [1] 10
```

The `$`

operator allows you to select list elements solely by name, but unlike `[`

and `[[`

, does not require quotes. As an infix operator, `$`

can only take a single name:

```
l1$two
## [1] "a" "b" "c"
```

Also, the `$`

operator allows for partial matching by default:

```
l1$t
## [1] "a" "b" "c"
```

in contrast with `[[`

where it needs to be specified whether partial matching is allowed:

```
l1[["t"]]
## NULL
l1[["t", exact = FALSE]]
## [1] "a" "b" "c"
```

Setting `options(warnPartialMatchDollar = TRUE)`

, a "warning" is given when partial matching happens with `$`

:

```
l1$t
## [1] "a" "b" "c"
## Warning message:
## In l1$t : partial match of 't' to 'two'
```

## Matrices

For each dimension of an object, the `[`

operator takes one argument. Vectors have one dimension and take one argument. Matrices and data frames have two dimensions and take two arguments, given as `[i, j]`

where `i`

is the row and `j`

is the column. Indexing starts at 1.

```
## a sample matrix
mat <- matrix(1:6, nrow = 2, dimnames = list(c("row1", "row2"), c("col1", "col2", "col3")))
mat
# col1 col2 col3
# row1 1 3 5
# row2 2 4 6
```

`mat[i,j]`

is the element in the `i`

-th row, `j`

-th column of the matrix `mat`

. For example, an `i`

value of `2`

and a `j`

value of `1`

gives the number in the second row and the first column of the matrix. Omitting `i`

or `j`

returns all values in that dimension.

```
mat[ , 3]
## row1 row2
## 5 6
mat[1, ]
# col1 col2 col3
# 1 3 5
```

When the matrix has row or column names (not required), these can be used for subsetting:

```
mat[ , 'col1']
# row1 row2
# 1 2
```

By default, the result of a subset will be simplified if possible. If the subset only has one dimension, as in the examples above, the result will be a one-dimensional vector rather than a two-dimensional matrix. This default can be overriden with the `drop = FALSE`

argument to `[`

:

```
## This selects the first row as a vector
class(mat[1, ])
# [1] "integer"
## Whereas this selects the first row as a 1x3 matrix:
class(mat[1, , drop = F])
# [1] "matrix"
```

Of course, dimensions cannot be dropped if the selection itself has two dimensions:

```
mat[1:2, 2:3] ## A 2x2 matrix
# col2 col3
# row1 3 5
# row2 4 6
```

#### Selecting individual matrix entries by their positions

It is also possible to use a Nx2 matrix to select N individual elements from a matrix (like how a coordinate system works). If you wanted to extract, in a vector, the entries of a matrix in the `(1st row, 1st column), (1st row, 3rd column), (2nd row, 3rd column), (2nd row, 1st column)`

this can be done easily by creating a index matrix with those coordinates and using that to subset the matrix:

```
mat
# col1 col2 col3
# row1 1 3 5
# row2 2 4 6
ind = rbind(c(1, 1), c(1, 3), c(2, 3), c(2, 1))
ind
# [,1] [,2]
# [1,] 1 1
# [2,] 1 3
# [3,] 2 3
# [4,] 2 1
mat[ind]
# [1] 1 5 6 2
```

In the above example, the 1st column of the `ind`

matrix refers to rows in `mat`

, the 2nd column of `ind`

refers to columns in `mat`

.

## Other objects

The `[`

and `[[`

operators are primitive functions that are generic. This means that any *object* in R (specifically `isTRUE(is.object(x))`

--i.e. has an explicit "class" attribute) can have its own specified behaviour when subsetted; i.e. has its own *methods* for `[`

and/or `[[`

.

For example, this is the case with "data.frame" (`is.object(iris)`

) objects where `[.data.frame`

and `[[.data.frame`

methods are defined and they are made to exhibit both "matrix"-like and "list"-like subsetting. With forcing an error when subsetting a "data.frame", we see that, actually, a function `[.data.frame`

was called when we -just- used `[`

.

```
iris[invalidArgument, ]
## Error in `[.data.frame`(iris, invalidArgument, ) :
## object 'invalidArgument' not found
```

Without further details on the current topic, an example`[`

method:

```
x = structure(1:5, class = "myClass")
x[c(3, 2, 4)]
## [1] 3 2 4
'[.myClass' = function(x, i) cat(sprintf("We'd expect '%s[%s]' to be returned but this a custom `[` method and should have a `?[.myClass` help page for its behaviour\n", deparse(substitute(x)), deparse(substitute(i))))
x[c(3, 2, 4)]
## We'd expect 'x[c(3, 2, 4)]' to be returned but this a custom `[` method and should have a `?[.myClass` help page for its behaviour
## NULL
```

We can overcome the method dispatching of `[`

by using the equivalent non-generic `.subset`

(and `.subset2`

for `[[`

). This is especially useful and efficient when programming our own "class"es and want to avoid work-arounds (like `unclass(x)`

) when computing on our "class"es efficiently (avoiding method dispatch and copying objects):

```
.subset(x, c(3, 2, 4))
## [1] 3 2 4
```

## Vector indexing

For this example, we will use the vector:

```
> x <- 11:20
> x
[1] 11 12 13 14 15 16 17 18 19 20
```

R vectors are 1-indexed, so for example `x[1]`

will return `11`

. We can also extract a sub-vector of `x`

by passing a vector of indices to the bracket operator:

```
> x[c(2,4,6)]
[1] 12 14 16
```

If we pass a vector of negative indices, R will return a sub-vector with the specified indices excluded:

```
> x[c(-1,-3)]
[1] 12 14 15 16 17 18 19 20
```

We can also pass a boolean vector to the bracket operator, in which case it returns a sub-vector corresponding to the coordinates where the indexing vector is `TRUE`

:

```
> x[c(rep(TRUE,5),rep(FALSE,5))]
[1] 11 12 13 14 15 16
```

If the indexing vector is shorter than the length of the array, then it will be repeated, as in:

```
> x[c(TRUE,FALSE)]
[1] 11 13 15 17 19
> x[c(TRUE,FALSE,FALSE)]
[1] 11 14 17 20
```