# 2.1.4 Indexing {#chap:Inde}

## Learning Objectives

By the end of this chapter you should be familiar with:

- Indexing using `[]`, and

We already encountered a type of indexing when we used the `subset()` function and _logical expressions_. Here, we will go one step further and perform indexing without using any unnecessary functions. We can filter our data-set according to:

- Equations (i.e. using _logical expressions_, see section \@ref(chap:LogOp)
- Position (i.e. using row \& column _number_, discussed here.), or
- Text matching (i.e. using _regular expressions_).

## Indexing vectors (1D)

The beauty of indexing is that we can use `[]` notation for all of these types of questions. We can limit our investigation to specific data points by using the `[x]` notation to select the $x{}^{th}$ data point in a vector. Let's return to the simple `foo1` example.

```{r}
foo1	     # Our data-set
foo1[6]    # The value at position 6
p	         # An object to use for indexing
foo1[p]    # The value at position p
foo1[3:p]  # The values between position 3 and p
foo1[3:length(foo1)] # Position 3 to the end of foo1

```

This is convenient, but becomes very powerful when we start mining our data by combining position with logical expressions. Recall that the result of a logical expression is a TRUE/FALSE answer, which can be used as an index.

```{r}

# For every value in foo1, is it less than 50?
foo1 < 50

# Save the logical expression as an object and use it
# as an index to report only the TRUE results
m <- foo1 < 50
foo1[m]

# Use the logical expression as an index to report
# only the TRUE results
foo1[foo1<50]
# Combine logical expressions to find values:
# Either less than or equal to 22 or greater than 71
foo1 <= 22 | foo1 > 71

# How many are there:
sum(foo1 <= 22 | foo1 > 71)

# What are they?
foo1[foo1 <= 22 | foo1 > 71]
```

<!-- \marginnote[-14.0cm]{Notice how we saved the TRUE/FALSE vector as an object and then used this as an index. This is a very common technique. It makes your code easier to read and to reproduce.} -->
<!-- \marginnote[-10.0cm]{Note the distinction between \texttt{>}, \texttt{>=}, \texttt{<} and \texttt{<=}.} -->
<!-- \marginnote[-8.5cm]{i.e. From 22 (inclusive) to 71} -->
<!-- \marginnote[-6.0cm]{i.e. Every value} -->
<!-- \marginnote[-3.5cm]{i.e. None of the values} -->
<!-- \marginnote[-1.0cm]{i.e. The tails of the distribution}Logical expressions can also be used to test the properties of specific -->
<!-- values. -->

## Indexing Dataframes (2D)

Recall that each column in a data frame is the same as a vector. Returning to the `foo_df` data frame we defined earlier, let's try to extract the same information using logical expressions instead of the `subset()` function.

```{r}
# Our data frame
foo_df
# The tissue variable (i.e. column, vector)
foo_df$tissue
# Which rows specify Liver?
# First make an index
foo_df$tissue == "Liver"

# Which values in the index are TRUE
which(foo_df$tissue == "Liver")
# How many Liver samples are there?
# TRUE values = 1, so take the sum.
sum(foo_df$tissue == "Liver")

```

Notice that we can combine an index of one column (i.e. `foo_df\$healthy == TRUE`) to extract values from another (`foo_df\$quantity`).

```{r}
# The quantity values of only healthy observations
foo_df$quantity[foo_df$healthy == TRUE]

```

To really make use of indexing with data frames, we can use `[x,y]` notation to select the `$x{}^{th}$` row (i.e. observation) of the `$y{}^{th}$` column (i.e. variable).

```{r}
# The fourth row (i.e. observation)
foo_df[4,]
# The fourth row, second column (i.e. variable)
foo_df[4,2]
```


<!-- \marginnote[-3.5cm]{This is the 4th row of the \texttt{foo1.df} data frame. Notice that the row number and variable names are provided because although it is only one row, it is also a data frame.} -->
<!-- \marginnote[-1.0cm]{The levels presented here will be discussed in detail in the section on Factor variables (page \pageref{chap:factors}).} -->

## Exercises for Indexing

Complete the exercises on indexing in the `diamonds` data set chapter.

