2.1 Vectors: Numeric, Character, and Logical

In the last chapter, you have had a basic understanding of R objects and how to do object assignments. From this section, we will start to introduce the first and perhaps the most fundamental R object type, called vector. Vector is the simplest object type in R, which contains one or more values of the same type. We will introduce numeric vector, character vector, and logical vector in this section. Let’s begin with numeric vector.

2.1.1 Numeric vector

a. Create numeric vectors

A numeric vector is a type of vector that only contains values of numeric type. For example, 6 is a numeric vector with one element of value 6. For vectors, the number of elements corresponds to the length of vector, so 6 is a numeric vector with length 1.

After assigning the value 6 to the name x1, you have created a new vector x1 with the same value as 6, so x1 is also a numeric vector. And you can refer to x1 in the subsequent calculations.

6                         #a numeric vector with length 1
x1 <- 6                   #x1 is also a numeric vector with length 1
x1                        #check the value of x1

But can a numeric vector contain more than one values? The answer is a big YES! In R, you can use the c() function (c is short for combine) to combine elements into a numeric vector.

c(1, 3, 3, 5, 5)          #use c() to combine elements into a numeric vector of length 5
y1 <- c(1, 3, 3, 5, 5)    #y1 is also a numeric vector of length 5
y1                        #check the value of y1
length(y1)                #length of a vector

In this example, you have created a length-5 object using the c() function with arguments containing the five elements separated by comma. Since the value of each element is a number, the object is a numeric vector.

If you assign the values to the name y1, you will get a new numeric vector y1 with 5 values. Notice that the second and third elements have the same value 3 in y1. You can verify the contents of y1 and check the length of it through the length() function.

When you assign several values to a name, the order of the values will not change after assignment. If you create two numeric vectors with same numbers of different orders, these objects will have different values. For example,

y2 <- c(1, 3, 5, 7, 9)    
y2                        
y3 <- c(9, 7, 5, 3, 1)    
y3

Here, y2 and y3 have different values.

If you include several numeric vectors in c(), you will also create a numeric vector as a combination of the input numeric vectors. For example, you can create a numeric vector with values from two numeric vectors. Of course you can create a new numeric vector z1 using object assignment.

c(c(1,2), c(3,4))          #use c() to combine several numeric vectors into one numeric vector
z1 <- c(c(1,2), c(3,4))
z1
length(z1)

After creating vectors, you can use the function class() to check its class.

class(x1)
#> [1] "numeric"
class(y1)
#> [1] "numeric"
class(z1)
#> [1] "numeric"

From the results, you will know that x1, y1 and z1 are numeric, which is the reason why they are called numeric vectors.

b. Extract vector element and update its value To extract an element from a vector, you can use the index of the element with a pair of [ and ] surrounding it following by the vector name.

y1[2]     #extract the second element of `y1`
#> [1] 3
y2[3]     #extract the third element of `y2`
#> [1] 5

You can also update a particular element of a vector by using the assignment operator with the extraction expression on the left and the new value on the right.

y1
#> [1] 1 3 3 5 5
y1[2] <- 100     #update the second element of `y1` to 100
y1
#> [1]   1 100   3   5   5

As you can see here, the second element of y1 is changed to 100, which is reflected via checking the value of y1.

c. Operations between two numeric vectors

Since numeric vectors are made of numbers, you can do arithmetic operations between them, just like the fancy calculator in Section 1.2. If two vectors are of the same length, the calculation is done elementwisely. In other words, R will perform the operation separately for each element. First, let’s create another vector x2 of length 1 and do addition with x1.

x2 <- 3
x1 + x2
#> [1] 9

Then obviously you will get 9!

Similarly, you can create another vector y2 of the same length as vector y1. Then, you can do operations between y1 and y2.

y2 <- c(2, 4, 1, 3, 2)
y1 + y2
#> [1]   3 104   4   8   7

The result is yet another length-5 vector. To check the calculation was indeed done elementwisely, you can verify that the value of the first element is \(1 + 2 = 3\), and value of the second element is \(3 + 4 = 7\), etc.

Since the calculation is done elementwisely, people normally would want the two vectors to have the same length. However, there is a recycling rule in R, which is sometimes quite useful and enables us to write simpler code. Specifically, if one vector is shorter than the other vector, R will recycle (repeat) the shorter vector until it matches in length with the longer one. This recycling is particularly helpful for an operator between a length>1 vector and a length-1 vector. Let’s see an example.

y1 + x1
#> [1]   7 106   9  11  11

From the result, you can see that each element in y1 is added by 6.

The followings are a few additional examples you can try.

y1 * x2
y1 / 5
y2 - x1

2.1.2 Character vector

a. Create character vectors

Now, let’s move to character vectors. In a character vector, the value of each element is of character type, which means each value is a string. A string is a sequence of characters (including letters, numbers, or symbols) surrounded by a pair of double quotes ("") or single quotes (''). To be consistent, we will stick with double quotes in this book.

Let’s first create a character vector sheepstudio which only has one element. You can then check the value of this vector by typing its name and verify the vector type by using class().

sheepstudio <- "sheep@007" 
sheepstudio
class(sheepstudio)

Double quotes need to be paired in strings. If you miss the right double quote, R will show a plus on the next line, waiting for you to finish the command. If this happens, you can either enter the matching double quote, or press ESC to escape this command.

Miss the right quotation mark

Figure 2.1: Miss the right quotation mark

Similar to a numeric vector, you can use the c() function to combine several strings to create a character vector. You can verify the number of strings in the character vector by using length(), and nchar() can help you get the number of characters in each string.

animals <- c("sheep@29", "pig$29", "monkey")
animals
length(animals)
nchar(animals)

Note that if you have a vector consisted of numbers with surrounding double quotes, it is also a character vector. (“4” and “29” are strings)

num_vec <- c(4, 29)
char_vec <- c("4", "29") 
class(num_vec)
#> [1] "numeric"
class(char_vec)
#> [1] "character"

b. Concatenate several strings into a single string

Next, we will introduce how to concatenate several strings into a single string. To do this, you can use the paste() function. First, let’s create a character vector with four elements,

four_strings <- c("This", "is", "Sheep@29", "$Studio")
length(four_strings) #verify the number of strings

Then use paste() instead of c(),

one_long_string <- paste("This", "is", "Sheep@29", "$Studio")
one_long_string
#> [1] "This is Sheep@29 $Studio"
class(one_long_string)
length(one_long_string) #verify the number of strings

From the results, you can see that one_long_string is a character vector with length 1, and the value of one_long_string is a single string with space between the individual strings.

You may notice that in paste(), the default separator between the individual strings is space. Actually you can change the separator by setting the sep argument in paste(). For example, you can separate the individual strings with comma,

comma <- paste("This", "is", "Sheep@29", "$Studio", sep = ",") 
comma
#> [1] "This,is,Sheep@29,$Studio"

If you don’t want to use a separator, you can use the paste0() function.

nosep <- paste0("This", "is", "Sheep@29", "$Studio") 
nosep
#> [1] "ThisisSheep@29$Studio"

If you would like to concatenate the strings of a vector into a longer string, you need to specify the collapse argument as the separator instead of sep in the paste() function.

paste(four_strings, collapse = "")
#> [1] "ThisisSheep@29$Studio"
paste(four_strings, collapse = ",")
#> [1] "This,is,Sheep@29,$Studio"
paste(four_strings)                 ##doesn't work without the collapse argument
#> [1] "This"     "is"       "Sheep@29" "$Studio"

In addition to paste several strings into one long string, you can also use the paste() function paste two character vectors, where the pair of strings will be pasted elementwisely.

paste(c("July", "August"),  c("2007", "2008"))
#> [1] "July 2007"   "August 2008"

c. Change case

In character vectors, each string can contain both uppercase and lowercase letters. You can unify the cases of all letters inside a vector. Let’s review the character vector four_strings at first,

four_strings <- c("This", "is", "Sheep@29", "$Studio")
four_strings
#> [1] "This"     "is"       "Sheep@29" "$Studio"

Then use the tolower() function to convert all letters to lower case,

tolower(four_strings)
#> [1] "this"     "is"       "sheep@29" "$studio"

The opposite function of tolower() is toupper(), which converts all letters to upper case,

toupper(four_strings)
#> [1] "THIS"     "IS"       "SHEEP@29" "$STUDIO"

2.1.3 Logical vector

So far we have created several numeric vectors and character vectors. Some vectors have names, and some do not. You can see all the named objects by using the ls() function.

ls()
#>  [1] "animals"         "char_vec"        "comma"           "four_strings"   
#>  [5] "nosep"           "num_vec"         "one_long_string" "sheepstudio"    
#>  [9] "x1"              "x2"              "y1"              "y2"             
#> [13] "y3"              "z1"

As introduced in Section 1.3, another way to check the named objects is via the environment panel as shown in Figure 2.2.

Environment

Figure 2.2: Environment

We can see that the environment panel has two columns, with the first column showing the list of object names, and the second column showing the corresponding information for each object. The information includes the vector type (chr is short for character and num is short for numeric), the vector length, and the first few values of the vector. Note that if the vector is of length 1 (for example x1), the environment will not show the type or the length.

By now you have created several objects, and you will find that the objects will not be saved in R if you don’t assign their values to names, for example, the results of x1 + x2 and y1 + y2 are not shown in the environment.

Before introducing the logical vector, let’s first learn a function called is.numeric(), which checks whether a vector is of numeric type,

is.numeric(y1) #Is y1 of numeric type?
#> [1] TRUE

Similar to is.numeric(), you can also use is.character() function to check if the given vector is of character type.

is.character(y1) #Is y1 of character type?
#> [1] FALSE

You may notice that results are TRUE or FALSE from the above codes. Actually, logical vectors are vectors that only use TRUE or FALSE as values. Note that TRUE and FALSE are logical constants in R. Similarly, you can use is.logical() to check if the vector is of logical type, or you can use class() to find out the exact type.

logic1 <- c(TRUE, FALSE, TRUE) #you can also use the c() function to create a logical vector
is.logical(logic1)
class(logic1)

You can also use T to represent TRUE and F to represent FALSE in logical vectors.

logic2 <- c(T, F, F)
is.logical(logic2)
class(logic2)

It is worth to point out that you don’t want to put a pair of double quotes around TRUE or FALSE when you use them as logical values. If you do that, a character vector will be generated instead.

char <- c("TRUE", "FALSE", "TRUE")
is.logical(char)

Note that the keywords TRUE and FALSE are case sensitive, and all letters inside them need to be in upper case. If you change any letter to the lower case, you will get an error, because True is neither a logical constant nor a defined object.

tlogic <- True
#> Error in eval(expr, envir, enclos): object 'True' not found

2.1.4 Exercises

  1. Write R code to create a numeric vector named vec_1 with values 7 24 8 26, get its length, and find out its type.

  2. Write R code to create a character vector named char_1 with values "I", "am", "learning", "R!", get its length, find out its type, and concatenate the vector into a single string with space as the separator.

  3. For the char_1 defined in Q2, find the number of characters in each string, and convert each string to upper case.

  4. Create a length-2 logical vector representing whether vec_1 and char_1 are of character type.