第 4 章 向量

向量是R语言最基础的数据类型。

4.1 向量就像冰糖葫芦

前面,我们把6这个数放入盒子 x

x <- 6

现在,我们想多装一些数据(有顺序、好取出),比如3,4,5,6,7

x <- 3, 4, 5, 6, 7   # work?

为了方便管理,那我们就希望这些数有一定的顺序,并且按照一定的结构组织在一起,我能想到的最好的结构就是—我们小时候吃的冰糖葫芦,中间用一根木棒把水果串起来,有先后顺序,而且当做一个整体方便取出。

对应到R语言里,我们可以用 c() 函数实现类似结构,一个水果对应一个数值

x <- c(3, 4, 5, 6, 7)
x
## [1] 3 4 5 6 7

我们观察到c()函数构造向量的几个要求

  • 这里的c就是 combine 或 concatenate 的意思
  • 它要求元素之间用英文的逗号分隔
  • 且元素的数据类型是统一的,比如这里都是数值

这样,c() 函数把一组数据聚合到了一起,就构成了一个向量

4.1.1 聚合成新向量

c() 函数还可以把两个向量聚合成一个新的向量。

low      <- c(1, 2, 3)
high     <- c(4, 5, 6)
sequence <- c(low, high)
sequence
## [1] 1 2 3 4 5 6

4.1.2 命名向量(named vector)

相比与向量c(5, 6, 7, 8), 每个元素可以有自己的名字

x <- c('a' = 5, 'b' = 6, 'c' = 7, 'd' = 8)
x
## a b c d 
## 5 6 7 8

或者

x <- c(5, 6, 7, 8)
names(x) <- c('a', 'b', 'c', 'd')
x
## a b c d 
## 5 6 7 8

4.1.3 单个元素的向量

我们再回头看看之前的

x <- 6

它实际上就是

x <- c(6)

即长度为 1 的向量,相当于,只有一个草莓的糖葫芦。在我看来,x <- 6x <- c(6) 偷懒的写法。

我们再来看看向量的两个基本属性类型长度

  • 类型
x <- c(3, 4, 5, 6, 7)
typeof(x)
## [1] "double"
  • 长度
## [1] 5

4.2 数值型向量

向量的元素都是数值类型,因此也叫数值型向量。数值型的向量,有 integer 和 double 两种:

x <- c(1L, 5L, 2L, 3L)    # 整数型
x <- c(1.5, -0.5, 2, 3)   # 双精度类型,常用写法
x <- c(3e+06, 1.23e2)     # 双精度类型,科学计数法

如果向量元素很多,用手工一个个去输入,那就成了体力活,不现实。在特定情况下,有几种偷懒方法:

  • seq() 函数可以生成等差数列,from 参数指定数列的起始值,to 参数指定数列的终止值,by 参数指定数值的间距:
s1 <- seq(from = 0, to = 10, by = 0.5)
s1
##  [1]  0.0  0.5  1.0  1.5  2.0  2.5  3.0  3.5  4.0  4.5
## [11]  5.0  5.5  6.0  6.5  7.0  7.5  8.0  8.5  9.0  9.5
## [21] 10.0
  • rep() 是 repeat(重复)的意思,可以用于产生重复出现的数字序列:x 用于重复的向量,times 参数可以指定要生成的个数,each 参数可以指定每个元素重复的次数
s2 <- rep(x = c(0, 1), times = 3)
s2
## [1] 0 1 0 1 0 1
s3 <- rep(x = c(0, 1), each = 3)
s3
## [1] 0 0 0 1 1 1
  • m:n,如果单纯是要生成数值间距为1的数列,用 m:n 更快捷,它产生从 m 到 n 的间距为1的数列
s4 <- 0:10  # Colon operator (with by = 1):
s4
##  [1]  0  1  2  3  4  5  6  7  8  9 10
s5 <- 10:1
s5
##  [1] 10  9  8  7  6  5  4  3  2  1

4.3 字符串型向量

字符串(String)数据类型,实际上就是文本类型,必须用单引号或者是双引号包含,例如:

x <- c("a", "b", "c")    
x <- c('Alice', 'Bob', 'Charlie', 'Dave')    
x <- c("hello", "baby", "I love you!") 

需要注意的是,x1是字符串型向量,x2是数值型向量

x1 <- c("1", "2", "3")
x2 <- c(1, 2, 3)

4.4 逻辑型向量

逻辑型常称为布尔型(Boolean), 它的常量值只有 TRUE 和 FALSE。注意 TRUE 和 FALSE 是在R语言中的保留词汇,所谓保留词汇,就是专用词,类似圆周率\(\pi\),特指某个含义。

x <- c(TRUE, TRUE, FALSE, FALSE)
x <- c(T, T, F, F)            # Equivalent, but not recommended

TRUE和FALSE必须都大写,不能写成下面这些形式

x <- c(True, False)          
x <- c(true, false)          

注意以下两者不要混淆,x1是逻辑型向量,x2是字符串型向量

x1 <- c(TRUE, FALSE)             # logical
x2 <- c("TRUE", "FALSE")         # character

因为TRUE和FALSE专用词,不加引号,如果加了引号,就是字符串型向量。

4.5 因子型向量

因子型可以看作是字符串向量的增强版,它是带有层级(Levels)的字符串向量。比如这里四个季节的名称,他们构成一个向量

four_seasons <- c("spring", "summer", "autumn", "winter")
four_seasons
## [1] "spring" "summer" "autumn" "winter"

我们使用 factor() 函数可以将这里的字符串向量转换成因子型向量

four_seasons_factor <- factor(four_seasons)
four_seasons_factor
## [1] spring summer autumn winter
## Levels: autumn spring summer winter

查看因子型向量的时候,也会输出了层级信息,默认的情况,它是按照字符串首字母的顺序排序,当然也可以指定顺序,这个时候,我们就需要指定层级信息,比如指定我对四个季节喜欢的顺序为c(“summer”, “winter”, “spring”, “autumn”)

four_seasons <- c("spring", "summer", "autumn", "winter")
four_seasons_factor <- factor(four_seasons, 
                              levels = c("summer", "winter", "spring", "autumn")
                              )
four_seasons_factor
## [1] spring summer autumn winter
## Levels: summer winter spring autumn

再比如,General上将;Colonel上校;Captain上尉, 如果没有指定层级levels,c("Colonel", "General", "Captain")就是一个常规的字符串向量,若指定了层级levels,这个字符串就多了军衔信息.

soldier <- factor(c("Colonel", "General", "Captain"), 
                 levels = c("General", "Colonel", "Captain")
       )
soldier
## [1] Colonel General Captain
## Levels: General Colonel Captain

4.6 小结

4.7 强制转换

矢量中的元素必须是相同的类型,但如果不一样呢,会发生什么? 这个时候R会强制转换成相同的类型。这就涉及数据类型的转换层级

  • character > numeric > logical
  • double > integer

比如这里会强制转换成字符串类型

c(1, "foo", TRUE)
## [1] "1"    "foo"  "TRUE"

这里会强制转换成数值型

c(7, TRUE, FALSE)
## [1] 7 1 0

这里会强制转换成双精度的数值型

c(1L, 2, pi)
## [1] 1.000 2.000 3.142

4.8 习题

  • 请说出fun3的结果
fun <- c("programming", "in", "R") 
fun2 <- c("Have", "fun")
fun3 <- c(fun2, fun)
fun3
  • 数据类型必须一致是构建向量的基本要求,如果数值型、字符串型和逻辑型写在一起,用c()函数构成向量,猜猜会发生什么?
x <- c(1, "USA", TRUE)
x
  • 形容温度的文字
temperatures <- c("warm", "hot", "cold")

要求转换成因子类型向量,并按照温度从高到低排序