title: R_3 向量date: 2021-07-11
tags: R语言
categories: 学习
mathjax: true

向量

1.向量

向量是一维数据的集合,向量中的所有元素的类型必须相同。

1.1 创建向量

可以使用内置的c()函数创建向量。c()函数接受任意数量的相同类型参数,参数用逗号分隔。最后返回包含这些元素的向量。

  1. people <- c("Sarah","John","Liu")
  2. print(people)

在打印变量前输出的[1]表示开头是向量的第一个元素,打印时元素用TAB分隔。

可以用length()函数确定向量中的元素数目。

print(length(people))

seq()函数可以生成整数向量,第一、二个参数是起始和终止数,第三个参数是间隔。

seq_vector1 <- seq(1,5,1)  #闭区间
print(seq_vector1)

seq_vector2 <- seq(1,5,3)  #左闭右开
print(seq_vector2)

可以用冒号生成一个序列,间隔为1.

colon_seq <- 1:7
print(colon_seq)

2. 向量的操作

在向量上执行操作按照对应位置进行。

v1 <- c(3,1,4,6,7)
v2 <- c(4,7,6,4,2)
#操作按对应位进行
v1 + v2
v1 - v2
v1 * v2
v1 / v2

2.1 向量的循环

两个向量长度不同而放在一起操作时会发生循环,即对较短的向量取模。如果较短向量的长度不能整除较长向量的长度,会发出警告。

v3 <- c(1,2)

v1 + v3    #v1中有第三个元素,v3中没有第三个元素,所以取
           #第3mod2个,即第一个元素与其相加。

2.2 向量与标量

将一个向量与标量相加,会将向量中的每一个元素加上这个标量。因为标量实质上是长度为1的向量。R在所有结果前面输出[1]的原因是每一个数都是向量。因此不能用length()函数获取字符串的长度。因为该字符串是向量中的一个元素,可以看作长度为1的向量,故返回值总是1.

2.3 向量化函数

如果将包含多个值的向量作为函数的参数,则函数将会对向量中的每一个元素执行相同的操作。

v4 <- c("hello","hi")
v5 <- c("world","Julia")

paste(v4,v5,sep="")

2.4 向量索引

获取向量元素子集的方法:
(1) 通过index(索引)引用元素,注意索引从1开始

vowels <- c("a","e","i","o","u")
vowels[1]    #引用一个元素
vowels[1:3]  #引用多个元素,用colon创建匿名向量
vowels[-1]   #使用负索引,将会返回除了该索引以外的其他元素
vowels[6]    #索引超出范围,会返回NA。NA不是字符串,而是一个逻辑值

#vowels[1,2] #不能使用逗号引用多个元素

index <- c(1,2,3)
vowels[index]#将索引放在向量中可以多索引
vowels[c(1,2,3)]

(2) 使用向量过滤。创建一个布尔向量指定需要提取的值,然后将这个向量作为索引。

shoe_sizes <- c(5.5,4,6,7,9)
#手动设置过滤向量
filter_manual <- c(TRUE,FALSE,FALSE,FALSE,TRUE)
shoe_sizes[filter_manual]
#使用条件判断设置过滤向量
filter_conditional <- shoe_sizes < 6#对向量的每一个元素做判断,
                                    #返回 T,T,F,F,F
shoe_sizes[filter_conditional]

#也可放在一条语句中,这样比较简洁。不要忘记索引仍是一个向量
shoe_sizes[shoe_sizes < 6]

2.5 修改向量

可以通过改变向量元素的值来修改向量。

prices <- c(1,2,3,4,5)
prices[1] <- 3
prices[prices>3] <- prices[prices>3]/2

#如果修改的索引值大于向量长度,R会用NA填充向量

可以组合多个向量。

people1 <- c("Jack","Barbara")
people2 <- c("Cheng","Luo")
more_people <- c(people1,people2)
more_people

3. 本章练习

Exercise 1

# Exercise 1: creating and operating on vectors

# Create a vector `names` that contains your name and the names of 2 people 
# next to you. Print the vector.

names <- c("Cheng","Luo","Lycra")
print(names)

# Use the colon operator : to create a vector `n` of numbers from 10:49

n <- 10:49

# Use the `length()` function to get the number of elements in `n`

print(length(n))

# Add 1 to each element in `n` and print the result

n <- n + 1

# Create a vector `m` that contains the numbers 10 to 1 (in that order). 
# Hint: use the `seq()` function

m <- seq(10,1,-1)

# Subtract `m` FROM `n`. Note the recycling!

m <- m - n

# Use the `seq()` function to produce a range of numbers from -5 to 10 in `0.1`
# increments. Store it in a variable `x_range`

x_range <- seq(-5,10,0.1)

# Create a vector `sin_wave` by calling the `sin()` function on each element 
# in `x_range`.

sin_wave <- sin(x_range)

# Create a vector `cos_wave` by calling the `cos()` function on each element 
# in `x_range`.

cos_wave <- cos(x_range)

# Create a vector `wave` by multiplying `sin_wave` and `cos_wave` together, then
# adding `sin_wave` to the product

wave <- sin_wave * cos_wave + sin_wave 

# Use the `plot()` function to plot your `wave`!

plot(wave)

Exercise 2

# Exercise 2: indexing and filtering vectors

# Create a vector `first_ten` that has the values 10 through 20 in it (using 
# the : operator)

first_ten <- 10 : 20

# Create a vector `next_ten` that has the values 21 through 30 in it (using the 
# seq() function)

next_ten <- 21 : 30

# Create a vector `all_numbers` by combining the previous two vectors

all_numbers <- c(first_ten,next_ten)

# Create a variable `eleventh` that contains the 11th element in `all_numbers`

eleventh <- all_numbers[11]

# Create a vector `some_numbers` that contains the 2nd through the 5th elements 
# of `all_numbers`

some_numbers <- all_numbers[2:5]

# Create a vector `even` that holds the even numbers from 1 to 100

even <- seq(1,100,2)

# Using the `all()` function and `%%` (modulo) operator, confirm that all of the
# numbers in your `even` vector are even

all(even %% 2)

# Create a vector `phone_numbers` that contains the numbers 8, 6, 7, 5, 3, 0, 9

phone_numbers <- c(8,6,7,5,3,0,9)

# Create a vector `prefix` that has the first three elements of `phone_numbers`

prefix <- phone_numbers[1:3]

# Create a vector `small` that has the values of `phone_numbers` that are 
# less than or equal to 5

small <- phone_numbers[phone_numbers <= 5]

# Create a vector `large` that has the values of `phone_numbers` that are 
# strictly greater than 5

large <- phone_numbers[phone_numbers > 5]

# Replace the values in `phone_numbers` that are larger than 5 with the number 5

phone_numbers[phone_numbers > 5] <- 5 

# Replace every odd-numbered value in `phone_numbers` with the number 0

phone_numbers[seq(1,length(phone_numbers),2)] <- 0

Exercise 3

# Exercise 3: vector practice

# Create a vector `words` of 6 (or more) words.
# You can Google for a "random word generator" if you wish!

words <- c("apple","banana","orange","pear","peach","kiwi")

# Create a vector `words_of_the_day` that is your `words` vector with the string
# "is the word of the day!" pasted on to the end.
# BONUS: Surround the word in quotes (e.g., `'data' is the word of the day!`)
# Note that the results are more obviously correct with single quotes.

words_of_the_day <- paste(words,"is the word of the day!")

# Create a vector `a_f_words` which are the elements in `words` that start with 
# "a" through "f"
# Hint: use a comparison operator to see if the word comes before "f" alphabetically!
# Tip: make sure all the words are lower-case, and only consider the first letter
# of the word!

a_f_words <- words[substr(words,1,1) <= "f"]

# Create a vector `g_m_words` which are the elements in `words` that start with 
# "g" through "m"

g_m_words <- words[substr(words,1,1) <= "m" & substr(words,1,1) >= "g"]

# Define a function `word_bin` that takes in three arguments: a vector of words, 
# and two letters. The function should return a vector of words that go between 
# those letters alphabetically.

word_bin <- function(words,first_letter,last_letter)
{
  return(words[substr(words,1,1) <= last_letter & substr(words,1,1) >= first_letter])
}

# Use your `word_bin` function to determine which of your words start with "e" 
# through "q"

word_bin(words,"e","q")