2.4 常用的向量运算
接下来将介绍一些常用的向量运算,包括算术和逻辑运算、向量索引以及一些创建向量的有用方法。然后将给出两个使用这些运算的扩展案例。
2.4.1 向量运算和逻辑运算
记住R是一种函数式语言,它的每一个运算符,包括下例中的+,实际上也是函数。
再回顾一次,标量实际上是一元向量,因此向量也可以相加,+算子按元素逐一进行运算。
如果你熟悉线性代数,当将两个向量相乘时,你也许会对所发生的感到惊讶。
但请记住,由于*函数的使用方式,实际上是元素和元素相乘。上例结果中的第一个元素5,是x的第一个元素1,与c(5,0,-1)中第一个元素5相乘的结果,以此类推。
同样的道理适用于其他数值运算符。下面有一个例子:
2.4.2 向量索引
R中最重要和最常用的一个运算符是索引,我们使用它来选择给定向量中特定索引的元素来构成子向量。索引向量的格式是向量1[向量2],它返回的结果是,向量1中索引为向量2的那些元素。
像这样的情况,使用length()函数通常很有用。例如,假设我们想选择向量z中除最后一个元素外的其他全部元素。以下代码可以实现:
对于上例,更常用的方法是z[1:2]。我们的程序可能需要处理长于二元的向量,此时第二种方法就更为通用。
2.4.3 用:运算符创建向量
R中有一些运算符在创建向量时十分有用。我们从第1章介绍过的冒号运算符:开始。它生成指定范围内数值构成的向量。
在表达式1:i-1中,冒号运算符的优先级高于减号,因此先计算1:i,得到1:2,然后再减1。这意味着二元向量减去一元向量。这就要用到循环补齐,一元向量(1)将扩展为(1,1),与二元向量1:2的长度匹配。按元素逐一相减,得到结果(0,1)。
另一方面,在表达式1:(i-1)中,括号的优先级高于减号。也就是说,先计算出i-1,表达式最终结果为1:1,也就是上例所看到的结果。
注意 在命令窗口中输入?Syntax,可以 从R自带的帮助文件里获得运算符优先级的详细说明。
2.4.4 使用seq()创建向量
比:运算符更为一般的函数是seq()(由sequence得来),用来生成等差序列。例如,鉴于3:8生成向量(3,4,5,6,7,8),其元素间隔为1(4-3=1,5-4=1,以此类推),用seq()函数可以生成间隔为3的向量,如下所示:
可以看到,如果x非空,seq(x)与1:length(x)的结果相同,但如果x为空,seq(x)正确地计算出空值NULL,导致上面的循环迭代0次。
2.4.5 使用rep()重复向量常数
rep()(由repeat得出)函数让我们可以方便地把同一常数放在长向量中。调用的格式是rep(x, times),即创建times*length(x)个元素的向量,这个向量由是x重复times次构成。例如:
rep()函数还有一个参数each,与times参数不同的是,它指定x交替重复的次数。