1.向量
向量是R语言的核心,向量的元素必须属于某种数据类型,在一个向量中元素必须是同一数据类型。
向量是最基本的数据类型。如果一个函数作用到向量上,那么它作用到该向量的每个元素之上。
1.1向量的创建
x<-seq(1,5,by=0.5);###以步长0.5从1至5创建向量(等差数列)
###创建times*length(x)个元素的向量
rep(x,times)
y<-rep(2:5,2);y ##重复2:5这个序列2次
z<-rep(2:5,rep(2,4));z ###从2至5,每个元素重复两次,4是元素个数
f<-rep(2:5,times=1,each=2);f##重复2:5这个序列一次,每个元素两次
rep(c(1,2,3),c(5,4,3))##重复元素1,5次;重复元素2,四次。
下面是结果展示:
1.2 添加或删除向量元素
向量是连续存储的,不能进行插入和删除处理。向量一经建立,其大小已经确定。如果想要进行添加或删除元素,则需要重新赋值。
################添加元素##############
x<-seq(from=1,to=100,by=2)
x[51]<-101 ;x
v<-1:3
v[c(4,5,6)]<-c(4,5,6) ;v #####批量赋值
x<-c(x[1:23],168, x[24:50])###在第23、24个元素之间插入168
append(x=v,values = 9,after = 2)##在向量v中插入元素9,其位置在2个元素后
append(x=v,values = 9,after = 0)###在向量头部插入数据
##################删除元素#############
y<-y[-(1:3)];y
###############修改元素##################
y["five"]<-100;y
v[2]<-15;v
v[3]<-"five";v
1.3 获取向量长度
x<-seq(from=1,to=100,by=2)
length(x)
编写一个函数来判断向量x元素中第一个1所在的索引。
x<-c(2,4,5,1,6,7,1,2,3,1)
judge<-function(x){
for(i in 1:length(x)){
if(x[i] == 1){
break
}
}
return(i)
}
judge(x)
如果length(x)为0时,上述方法不再有用。
如:空向量x,R会报错。我们可以用seq()函数来实现。如果x非空,seq()函数与1:length(x)的结果相同
> x<-c()
> judge<-function(x){
+ for(i in seq(x)){
+ if(x[i] == 1){
+ break
+ }
+ }
+ return(i)
+ }
> judge(x)
NULL
1.4 循环补齐
较短向量会被R自动补充,直到与长向量长度相同。
在R中,矩阵实际上是一个长向量。是一列一列地存储的。在存储上,矩阵y与向量c(1,2,3,4,5,6)相同。图一的运算相当于图二的运算。
图一:
图二:
1.5向量运算
R是一种函数式语言,每一个符号都相当于一个函数。
x<-c(1,2,3,4,5)
y<-c(6,7,8,9,10)
> x+1 ####向量中每个元素都加1
[1] 2 3 4 5 6
> y %% x ####求余
[1] 0 1 2 1 0
> y %/% x ###整除
[1] 6 3 2 2 2
> x %*% y ###求内积
[,1]
[1,] 130
> x * y ###对应元素相乘
[1] 6 14 24 36 50
#求内积 x %*% y t(x)%*%y crossprod(x,y)
##求外积 x %o% y outer(x,y) x%*%t(y)
x<-c(1,2,3,4,5)
y<-c(2,4,6,8,10)
x%*%y
t(x)%*%y
crossprod(x,y)
x%o%y
outer(x,y)
x%*%t(y)
1.6 向量索引
###############################向量的索引#######################
x<-seq(from=1,to=100,by=2)
x[i] ##表示向量x的第i个元素
x[c(4:18)] ####向量x的第四个到第18个元素
x[c(1,23,24,50)] ###向量x的第一个、第23个、第24个、第50个元素
names(y)<-c("one","two","three","four","five");y
y["one"] ####访问向量y中名字为one 的元素
1.7 使用any()和all()
分别返回其参数是否至少一个为TRUE,全部为TRUE
> x<-1:10
> any(x>8)
[1] TRUE
> any(x>88)
[1] FALSE
> all(x>88)
[1] FALSE
> all(x>0)
[1] TRUE
例子1:寻找连续(:)出现1的游程(run)。注:在一个0和1组成的序列中,一个由连续的0或者1构成的串称为一个游程。
x<-c(1,0,0,1,1,1,0,1,1)
findruns<-function(x,k){
n<-length(x)
runs<-NULL
for(i in 1:(n-k+1)){
if(all(x[i:(i+k-1)]==1))runs<-c(runs,i)
}
return(runs)
}
findruns(x,3)
由于调用c(runs,i),每次执行时都会减慢代码的运行速度。我们可以预先分配内存空间。
x<-c(1,0,0,1,1,0,0,1,1)
findruns<-function(x,k){
n<-length(x)
runs<-rep(0,n)###给runs分配了内存空间
j<-0
for(i in 1:(n-k+1)){
if(all(x[i:(i+k-1)]==1)){
j<-j+1
runs[j]=i
}
}
if(j>0){
runs<-runs[1:j]###删掉runs中没用的部分
}else runs<-NULL
return(runs)
}
findruns(x,3)