本文含有:
- 向量的创建与运算
- 两个方便创建向量的函数:rep()与seq()
- 如何访问向量中的元素
首先先明白几个要点:
- R区分大小写,向量A和向量a是两个不同的向量;
- R可以识别负数,如5+-2可以输出结果3
- R是计数时是1-base,也就是说R中的1就代表第一个数,而其他语言有可能第一个数用0来表示。
- R的赋值符号可以是“<-”,也可以是“=”。
1. 向量的创建与运算
- 创建一个向量
> l <- c(2, 2, 1, 3, 8)
> l
[1] 2 2 1 3 8
- 创建一个1至5的向量,“:”表示“至”,“1:5”则表示从1到5的5个整数。
> n <- 1:5
> n
[1] 1 2 3 4 5
也可以用函数vector(length=)创建向量。创建的向量初始默认为逻辑值FALSE
> v <- vector(length = 4)
> v
[1] FALSE FALSE FALSE FALSE
- 切片运算(这也是访问向量的一种方式)
注意R中的序号1就表示第1个,而不是2个,要与python相区别
n[1:4]
[1] 1 2 3 4
- 基本运算
首先肯定是用+, -, *, /这几个运算符号进行的。幂运算使用^,带括号先算括号内的内容。用刚刚创建的n和a列表进行示范:
> a1 <- l + n
> a1
[1] 3 4 4 7 13
> a2 <- l / n
> a2
[1] 2.0000000 1.0000000 0.3333333 0.7500000 1.6000000
a和n是等长的,即向量内元素的个数是一样的,得到的运算结果也是一一对应相运算的结果。若不等长会怎么样呢?
较少元素的向量在运算完一遍以后将会重新对应较多元素的向量中的剩余元素逐个再从头运算一次。这句话比较难理解,看例子:
> n <- 1:5
> l <- c(1,1,1,1,1,2,2,2,2,2)
> a <- n * l
> a
[1] 1 2 3 4 5 2 4 6 8 10
2.seq函数 - 建立等差数列
建立从2到10,间隔为2的等差数列:
> n <- seq(from=2, to=10, by=2) # 或 n <- seq(2, 10, 2)
> n
[1] 2 4 6 8 10
如果换成1到11,间隔为2的等差数列会怎么样呢?答案是11会被剔除。
> n <- seq(2, 11, 2)
> n
[1] 2 4 6 8 10
3. rep函数 - 元素的重复
两种格式:
- rep(起始值:终止值, times = 重复次数)
- rep(起始值:终止值, each = 重复次数)
第一种是将整一个向量重复n次;
第二种是将向量的每个元素依次重复n次;
若直接写数字,则是第一种times.
见下面例子:
> x=1:4
> rep(x,2)
[1] 1 2 3 4 1 2 3 4
第一行代码表示把1到4赋值给x,第二行表示把向量x重复2次。当然我们也可以直接写入数字:
> rep(1:4,2)
[1] 1 2 3 4 1 2 3 4
当然,向量可以重复,字符也是可以重复的,但是不要忘记加个引号,例如,如果我们想把字符“male”和“female”各重复10次,那么我们输入下面的代码:
> rep(c("male","female"),each=10)
[1] "male" "male" "male" "male" "male" "male" "male" "male"
[9] "male" "male" "female" "female" "female" "female" "female" "female"
[17] "female" "female" "female" "female"
先用c()函数将“male”和“female”结合成一个向量,each=10是将向量中每一个元素重复10次。如果不写each=10,直接写10,将会是这样的:
> rep(c("male","female"),10)
[1] "male" "female" "male" "female" "male" "female" "male" "female"
[9] "male" "female" "male" "female" "male" "female" "male" "female"
[17] "male" "female" "male" "female"
注意它和前一个代码重复的区别。再强调一次,第一个是将向量中的每一个元素重复十次,第二个是将整个向量重复了10次。
> rep(c(1,2),c(10,10))
[1] 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2
这样写也表示把1,2各重复10次。因此,我们显然可以想到,如果把1,2,3,4分别重复5,6,7,8次,代码一定是这样的:
> rep(c(1,2,3,4),c(5,6,7,8))
[1] 1 1 1 1 1 2 2 2 2 2 2 3 3 3 3 3 3 3 4 4 4 4 4 4 4 4
与seq函数一样,rep函数也可以设置长度。
> rep(1:7,3)
[1] 1 2 3 4 5 6 7 1 2 3 4 5 6 7 1 2 3 4 5 6 7
> rep(1:7,3,length.out=18)
[1] 1 2 3 4 5 6 7 1 2 3 4 5 6 7 1 2 3 4
比较这两组代码与结果。第一个表示将1到7重复3次,得出了21个值,第二个表示将1到7重复3次,限制长度为18,所以结果只有18个值。同样,length.out也可以简写为length或len。
当我们在rep中使用each时,还可以使用times:
> rep(c(3,5,7),each=3,times=2)
[1] 3 3 3 5 5 5 7 7 7 3 3 3 5 5 5 7 7 7
代码表示将向量中的每个元素重复三次,再将所得的结果重复2次(结合结果,仔细理解我这句话),“times”即“加倍”的意思。
最后想删除向量x:
rm(x)
4.访问向量中的元素
(1)访问指定位置上的元素
有三种书写格式:
- 向量名[位置常量]
- 向量名[位置常量1:位置常量2]
- 向量名[c(位置常量列表)]
> v <- vector(length = 10) #创建10元素向量v
> v
[1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
> v[1] <- 1 # 访问第1个元素,赋值为1
> v[2:4] <- c(2,3,4) # 访问第2~4个元素,赋值为2,3,4
> v
[1] 1 2 3 4 0 0 0 0 0 0
> w <- seq(5,9,1) # 生成一个取值为5~9的序列给向量w
> v[c(5:9,10)] <- c(w,10) # 访问第5~9和第10个元素,赋值为5~10
> v
[1] 1 2 3 4 5 6 7 8 9 10
这个c(w, 10)的访问方式,可以有效实现多个向量的合并。
(2)利用位置向量访问指定位置上的元素
> v
[1] 1 2 3 4 5 6 7 8 9 10
> w <- (2:4)
> v[w]
[1] 2 3 4
要注意这个w的赋值没有用c函数。
除了直接指定位置,也可以利用逻辑型位置向量来访问。
> w <- c(T,F,F,T,F,F,F,F,F,F)
> v[w] # 访问v中位置向量w取值为TRUE位置(即1,4)上的元素
[1] 1 4
(3)访问指定位置之外的元素
加个负号就可以实现
> v[-1] # 访问除了第1个元素以外的元素
[1] 2 3 4 5 6 7 8 9 10
> v[-(2:4)] # 访问除了2~4元素以外的元素
[1] 1 5 6 7 8 9 10
> v[-c(5:9,10)]
[1] 1 2 3 4
如果尝试逻辑型位置向量呢?会出现问题:
> w
[1] TRUE FALSE FALSE TRUE FALSE FALSE FALSE FALSE FALSE FALSE
> v[-w]
[1] 2 3 4 5 6 7 8 9 10
本文参考:《R语言数据挖掘》第2版 薛薇 编著