## 2.3 Create Vectors with Patterns

Now you are familiar with numeric vector, character vector and logical vector, and you can create them from scratch using the `c()`

function. However, in many applications, we may want to create vectors with values of **certain patterns**. In this section, we will introduce several commonly used functions for generating vectors with patterns.

### 2.3.1 Create equally-spaced numeric vectors via `:`

One of the commonly used patterns associated with numeric vectors is numeric vectors composed of **equally-spaced** integers, where the differences between adjacent values in the vectors are all \(1\) or \(-1\).

Suppose we want to create a vector with consecutive integers from 1 to 5. The first method is to write all numbers down in `c()`

,

`<- c(1, 2, 3, 4, 5) pattern1 `

You can see that it is not too cumbersome to enumerate all 5 integers when creating `pattern1`

. Let’s imagine if we want to create a vector containing 100 consecutive integers. Do we have a faster way than writing all 100 integers down? The answer is Yes!

You can use the **colon operator** `:`

, which is frequently used in everyday programming. (Note that you don’t need to use `c()`

together with `:`

)

`<- 1:5 #consecutive integers from 1 to 5 pattern2 `

It is worth mentioning the subtle difference between `pattern1`

and `pattern2`

.

```
pattern1#> [1] 1 2 3 4 5
pattern2#> [1] 1 2 3 4 5
typeof(pattern1)
#> [1] "double"
typeof(pattern2)
#> [1] "integer"
```

You can see that although `pattern1`

and `pattern2`

appear to have the same values, they are stored as double and integer values, respectively. The reason is that when you create consecutive integers using `:`

, R will store them as integers to save space.

In addition to creating vectors with consecutive integers that is increasing, `:`

can also be used to create vectors with integers in decreasing sequences.

```
<- 6:2 #decreasing sequence from 6 to 2
pattern3 <- 3:-3 #decreasing sequence from 3 to -3 pattern4
```

Powerful the `:`

operator is, it can only generate equally-spaced numeric vectors with increment 1 or -1. If you want to generate equally-spaced numeric vectors with different increments, you can use the more powerful `seq()`

function.

### 2.3.2 Create equally-spaced numeric vectors via `seq()`

A very efficient way to create **equally-spaced** numeric vectors is to use the `seq()`

function, which is short for sequence.

*a. Create sequences with by argument*

To use the `seq()`

function, you can specify the start value of the sequence in the `from`

argument, the limit end value in the `to`

argument, and the increment in the `by`

argument.

`seq(from = 1, to = 5, by = 1)`

Here, the vector starts with 1, increases by 1 at each step, and ends at 5. Note that the `from`

and `by`

arguments are optional in `seq()`

. If you don’t specify their values, `seq()`

will use the default value 1 for both arguments.

`seq(to = 5)`

Now you have had four methods to create vectors with consecutive integers.

```
c(1,2,3,4,5,6) #write all numbers down
1:6 #use colon operator
seq(from = 1, to = 6, by = 1) #use seq()
seq(to = 6) #use seq()
```

Next, let’s change the increment to 2 and you will get a numeric vector with `1 3 5`

as its values.

```
seq(from = 1, to = 5, by = 2)
#> [1] 1 3 5
```

Note that the end value of the sequence doesn’t always equal the `to`

argument. If you change the limit end value to 6, you still get the same sequence, since the next value in the sequence would be 7 which is larger than the limit end value 6. This is the reason why `to`

is called the limited end value, not the end value.

```
seq(from = 1, to = 6, by = 2)
#> [1] 1 3 5
```

Unlike `:`

, you can set values of three arguments in `seq()`

as decimal numbers.

```
seq(from = 1.1, to = 6.2, by = 0.7)
#> [1] 1.1 1.8 2.5 3.2 3.9 4.6 5.3 6.0
```

Here, you will get a sequence which starts with 1.1, increases by 0.7 each time until it is larger than 6.2.

You can also create a decreasing sequence by using a smaller `to`

value than the `from`

value, coupled with a negative value in the `by`

argument.

`seq(from = 1.5, to = -1, by = -0.5) `

If a positive value is used in the `by`

argument in a decreasing sequence, you will see an error message.

```
seq(from = 1.5, to = -1, by = 0.5)
#> Error in seq.default(from = 1.5, to = -1, by = 0.5): wrong sign in 'by' argument
```

*b. Create sequences with length.out argument*

Instead of setting the increment, you can also specify the `length.out`

argument, which creates a sequence with equal space in the specified length. R will automatically calculate the interval between two neighboring numbers according to values of three arguments in `seq()`

.

`seq(from = 1, to = 5, length.out = 9) `

Here, you will get a equally-spaced sequence of length 9 from 1 to 5.

You can also create a decreasing sequence by using the `length.out`

argument.

`seq(from = 5, to = -5, length.out = 9) `

Unlike creating sequences with `by`

argument, if you specify the `length.out`

argument in `seq()`

, the start value and end value of the sequence you get will be exactly match the input arguments.

*c. Create sequences with both by and length.out arguments*

Lastly, if you provide both the `by`

and `length.out`

arguments, only one of `from`

and `to`

is needed. With one value (the start value or the limit end value) fixed, `seq()`

will create a vector with specified increment and length.

If you only have the `from`

argument, you will get a sequence starting from the value you set with the increment in the `by`

argument, until you get a sequence with specified length.

`seq(from = 1, by = 2, length.out = 5)`

If you only have the `to`

argument, you will get a sequence end with the value you set with the increment in the `by`

argument, until you get a sequence with specified length.

`seq(to = 1, by = 2, length.out = 5)`

One last thing regarding `seq()`

is that you can *at most* provide three arguments. For example, you will see an error when running the following example since all four arguments are specified.

```
seq(from = 1, to = 3, by = 1, length.out = 3)
#> Error in seq.default(from = 1, to = 3, by = 1, length.out = 3): too many arguments
```

### 2.3.3 Create matching numeric vectors via `seq_along()`

Now, we will introduce one function related to `seq()`

. Let’s first create a numeric vector,

`<- seq(from = 2, to = 8, length.out = 9) extend `

From the `seq()`

above, you know that the length of this vector is 9. Next, let’s put this numeric vector in `seq_along()`

.

```
seq_along(extend)
#> [1] 1 2 3 4 5 6 7 8 9
```

`seq_along()`

takes a vector as its argument, and generates consecutive integers from 1 to the length of the input vector. The `seq_along()`

function is commonly used when writing loops, which will be covered at a later time.

You can also use `1:length(extend)`

to get the same result as `seq_along(extend)`

.

`1:length(extend)`

### 2.3.4 Create numeric vectors via `sequence()`

Sometimes, you may want to combine multiple equally-spaced integer sequences into a single vector. To do this, you can use the function `sequence()`

. The most common usage of `sequence()`

is to supply a vector of integers as its input.

```
<- sequence(c(2, 3, 5))
comp_seq1
comp_seq1#> [1] 1 2 1 2 3 1 2 3 4 5
```

From the result, you can see that it firstly create equally-spaced vectors `1:2`

, `1:3`

, and `1:5`

, then combine all vectors into a single one. This avoids the trouble of writing something like `c(1:2, 1:3, 1:5)`

.

### 2.3.5 Create numeric, character and logical vectors with repetition

Another commonly used pattern associated with vectors is **repetition**. Note that while the equally-spaced pattern only makes sense for numeric vectors, the repetition pattern work for all three kinds of vectors.

To do repetition, you can use the `rep()`

function, which works by repeating the first argument for the number of times indicated in the second argument.

Firstly, let’s create a numeric vector with repetition.

```
<- rep(2, 4)
num1
num1#> [1] 2 2 2 2
```

Since the first argument is `2`

and the second argument is `4`

, `2`

is repeated for `4`

times, resulting a length-4 vector with all elements of value 2.

The first argument can also be a numeric vector with several values.

```
<- rep(c(1, 4, 2), 3)
num2
num2#> [1] 1 4 2 1 4 2 1 4 2
```

Here, the `rep()`

will repeat the whole vector `c(1, 4, 2)`

three times. Note that the vector is **repeated as a whole**, not elementwisely.

You may be wondering what happens the second argument also has several numbers? Let’s try together.

```
<- rep(c(1,5,7), c(3,2,1))
num3
num3#> [1] 1 1 1 5 5 7
```

When the second argument is also a vector, R will do an **element repeat** operation by repeating each element in the first argument the number of times indicated in the corresponding location of the second argument, and combine the repeated vectors to a single vector. In this example, 1 is repeated 3 times, 4 is repeated twice, and 7 is repeated once. It is equivalent to

`c(rep(1,3), rep(4,2), rep(7,1))`

The `rep()`

function works the same way if the first argument is a character vector.

```
<- rep(c("sheep", "pig", "monkey"), 2)
animals1
animals1<- rep(c("sheep", "pig", "monkey"), c(3, 2, 1))
animals2 animals2
```

You can also use logical vectors in the first argument.

```
<- rep(c(TRUE, FALSE), c(3,2))
logic logic
```

### 2.3.6 Getting unique elements and their frequencies

So far, you have learned how to create vectors with different patterns. Sometimes, you may want to get the unique elements (elements of different values) of a vector and their corresponding frequencies. Let’s use `num3`

as an example. **(Don’t forget to use ls() or check the environment panel to find all objects you have defined)**,

```
#check the values
num3 #> [1] 1 1 1 5 5 7
```

You can use `unique()`

to show all unique elements in vectors.

```
unique(num3) #get the unique elements
#> [1] 1 5 7
```

From the result, you know the unique elements in `num3`

are `1`

,`5`

, and `7`

. To get the frequency of each element, you can use the `table()`

function.

```
table(num3) #get the frequency table
#> num3
#> 1 5 7
#> 3 2 1
```

Here, the first row is the name of the object, the second row shows all unique elements, and the third row is the corresponding frequency of each element in the same column. In `num3`

, there are three `1`

s, two `5`

s and one `7`

.

`unique()`

and `table()`

work similarly for character vectors and logical vectors. You can try the following codes.

```
animalsunique(animals)
table(animals)
logicunique(logic)
table(logic)
```

### 2.3.7 Exercises

Use five different ways to create an equally-spaced sequence with

`2 4 6 8 10`

as result.Use two different ways to create a numeric vector with

`1 2 3 1 2 3 4 5 1 2 3 4 5 6 7`

as result. Show the unique elements and their corresponding frequency.Write R code using

`rep()`

function to create a character vector with the same result as`c("sheep","pig", "cat","sheep","pig", "cat","sheep","pig", "cat")`

Write R code using

`rep()`

function to create character vector with the same result as`c("sheep","sheep","pig","pig","pig","pig","cat","cat","cat")`