构建向量子集
如果想访问一些特定元素或者向量的一个子集,使用向量子集是一个不错的方法。在
这一节中,我们将展示几种不同的构建向量子集的方法。
首先,生成一个简单的数值向量并且赋值给 v1:
v1 <- c(1, 2, 3, 4)
接下来的每一行都是用来获取 v1 的特定子集。
例如,提取第 2 个元素:
v1[2]
## [1] 2
也可以提取第 2~4 个元素:
v1[2:4]
## [1] 2 3 4
还可以获取除第 3 个以外的其他所有元素:
v1[-3]
## [1] 1 2 4
这个模式很清晰,我们可以在向量后面的方括号中放入任何一个数值向量获取相应的
子集:
a <- c(1, 3)
v1[a]
## [1] 1 3
上述所有例子都是通过位置信息来构造子集,也就是说,通过指定元素的位置来得到
一个向量的子集。方括号中使用负数将排除相应位置的元素。需要注意的一点是,在方括
号中不能同时使用正数和负数:
v1[c(1, 2, -3)]
## Error in v1[c(1, 2, -3)]: 只有负下标里才能有零
如果使用向量范围之外的位置来获取子向量会发生什么呢?接下来的例子尝试获取向
量 v1 的子集,范围是 v1 的第 3~6 个(不存在)元素:
v1[3:6]
## [1] 3 4 NA NA
正如我们所看到的一样,在不存在元素的位置用 NA 替代了缺失值。在现实世界的数
据中,缺失值是普遍存在的。一方面,对所有包含 NA 的数据进行数值运算的结果都是 NA,
而不是其他不确定的结果;另一方面,因为直接假设数据中不存在缺失值并不恰当,所以
我们需要付出额外的工作来处理数据。
另一种构造子集的方法是使用逻辑向量。我们可以输入与要获取向量子集的向量具有
相等长度的逻辑向量,以此决定每一个元素是否要被获取:
v1[c(TRUE, FALSE, TRUE, FALSE)]
## [1] 1 3
除此之外,我们也可以给向量中特定的子集重新赋值(覆盖原值):
v1[2] <- 0
在这种情况下,v1 变成:
v1
## [1] 1 0 3 4
也可以同时覆盖处于不同位置的多个元素:
v1[2:4] <- c(0,1,3)
现在,v1 变成:
v1
## [1] 1 0 1 3
同样,重新赋值时,逻辑选择也是适用的:
v1[c(TRUE, FALSE, TRUE, FALSE)] <- c(3, 2)
正如你所期待的,此时 v1 变成:
v1
## [1] 3 0 2 3
一个常用的技巧是可以通过逻辑标准来选择元素。例如,以下的代码挑选出 v1 中所
有不大于 2 的元素:
v1[v1 <= 2]
## [1] 0 2
这种方法也适用于更复杂的选择标准。下面的例子挑选出 v1 中所有满足 x 2 −x+1≥0
的元素:
v1[v1 ^ 2 - v1 + 1 >= 0]
## [1] 3 0 2 3
以下代码用 0 替代所有满足 x <= 2 的元素:
v1[v1 <= 2] <- 0
像你期待的一样,此时 v1 变成:
v1
## [1] 3 0 0 3
如果我们对一个并不存在的元素重新赋值,向量将自动用 NA 填充未被指定的位置,
当作缺失值处理:
v1[10] <- 8
v1
## [1] 3 0 0 3 NA NA NA NA NA 8