第二章开始就是正式、深入了解R语言的知识点,首先开始了解的是向量相关的知识,牢记三大要点,贯穿始终:
循环补齐、筛选、向量化。
增加向量主要用插入法,利用向量索引,去达到增加的目的,如下例所示:
> x<-c(1:4)
> x
[1] 1 2 3 4
> x<-(1:2,5,3:4)
> x<-c(x[1:2],5,x[3:4])
> x
[1] 1 2 5 3 4
删除向量主要利用负数的下标,负数后面跟哪个下标就代表删除向量中第几个元素
> x
[1] 1 2 5 3 4
> x[-5]
[1] 1 2 5 3
> x<-c(12,14,13,22,67,39,15)
> length(x)
[1] 7
Tips:利用length()函数获取向量中某个值第一次出现的索引值(位置)
first1<-function(x){
for(i in 1:length(x)){
if (x[i]==15) break #循环排查,直到第一次出现向量值为15,结束排查
}
return(i)
}
运行结果:
> first1<-function(x){
+ for(i in 1:length(x)){
+ if (x[i]==15) break #循环排查,直到第一次出现向量值为15,结束排查
+ }
+ return(i)
+ }
> first1(x)
[1] 7
循环补齐:就是较短的向量会被循环补齐
> x
[1] 12 14 13 22 67 39 15
> y<-c(1:3)
> y
[1] 1 2 3
> x+y
[1] 13 16 16 23 69 42 16
Warning message:
In x + y : longer object length is not a multiple of shorter object length
会有警告提示,但是仍然算出了结果,因为y<-c(1,2,3)为了匹配x中的7个向量,被自动补齐为y<-c(1,2,3,1,2,3,1)与x中对应的1到7个元素相加。
> x<-matrix(1:6,nrow=3)
> x
[,1] [,2]
[1,] 1 4
[2,] 2 5
[3,] 3 6
> x+1:4
[,1] [,2]
[1,] 2 8
[2,] 4 6
[3,] 6 8
Warning message:
In x + 1:4 :
longer object length is not a multiple of shorter object length
上述例子很好说明了这一点,1:4被自动循环补齐为,因为矩阵是按列排序,再次强调
[,1] [,2]
[1,] 1 4
[2,] 2 1
[3,] 3 2
所以,x中对应6个元素,与上述矩阵6个元素对应相加,得出结果。
运算符优先级从高到低,按照如下顺序排列:注意,冒号优先级高于加减乘除,括号高于冒号
? help (unary and binary)
findruns<-function(x,k){ #函数findruns有两个变量x,k,x指向向量,k指向游程的长度
n<-length(x) #n指向向量的长度
runs<-NULL #runs最初赋值为空
for(i in 1:(n-k+1)){
if(all(x[i:(i+k-1)]==1)) runs<-c(runs,i)#这里的变量i指定从第一个向量开始,到最后一个组不成游程的值为止(这里的n-k+1就是最后一个组不成游程的值,请好好体会一下)
}
return(runs)
}
x<-c(1,0,0,1,1,1,1,1,0,1,1)
findruns(x,3)
> findruns<-function(x,k){ #函数findruns有两个变量x,k,x指向向量,k指向游程的长度
+ n<-length(x) #n指向向量的长度
+ runs<-NULL #runs最初赋值为空
+ for(i in 1:(n-k+1)){
+ if(all(x[i:(i+k-1)]==1)) runs<-c(runs,i)
+ }
+ return(runs)
+ }
> x<-c(1,0,0,1,1,1,1,1,0,1,1)
> findruns(x,3)
[1] 4 5 6
本案例同样经典,理解这个案例就会知道如何编写函数,all()函数要求向量中每一个值都必须为1,以及为什么遍历循环只到最后一个组不成游程的值。
preda<-function(x,k){
n<-length(x) #n指向向量的长度
k2<-k/2 #k2指向最近k期一半长度
pred<-vector(length=n-k) #预测值长度必须比全量向量长度少一个k值,否则就不存在预测了
for (i in 1:(n-k)){
if(sum(x[i:(i+(k-1))])>=k2)pred[i]<-1 else pred[i]<-0 #i到i+k-1恰好一个k值长,超过半数,当前预测值指向下雨,从而得到一个由预测值组成的长度为n-k向量
}
return(means(abs(pred-x[(k+1):n]))) #用预测值去减实际值,求出平均误差,误差范围[-1,1]之间,越接近0,误差越小
}
z12<-function(z) return(c(z,z^2))
sapply(1:8,z12)
输出结果:
> z12<-function(z) return(c(z,z^2))
> sapply(1:8,z12)
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]
[1,] 1 2 3 4 5 6 7 8
[2,] 1 4 9 16 25 36 49 64
>
这里sapply()函数的作用是对1:8的每个元素,使用函数function(),返回结果是元素的平方
最典型的用法是在循环中创建向量,上面的每章案例1用的就是这个方法,不了解的请回看。NULL也不会被计数。
> x<-c(6,1:3,NA,12)
> subset(x,x>5) #第一个是向量,第二个是筛选条件
[1] 6 12
(2)使用which()函数返回索引的位置
first1<-function(x){
for(i in 1:length(x)){
if(x[i]==1) break
}
return(i)
}
x<-c(2:5,1,3:6)
first1(x)
输出结果:
> first1<-function(x){
+ for(i in 1:length(x)){
+ if(x[i]==1) break
+ }
+ return(i)
+ }
> x<-c(2:5,1,3:6)
> first1(x)
[1] 5
这里案例如果有统计学背景,会帮助理解,当然,没有统计学背景也很好理解。这个案例将前面几个函数的运用串联起来
案例简述:有两个时间序列x和y,代表每小时收集的气温和气压的测量值,定义x和y的相关性为他们同时上升和下降次数占总观测数的比例,看清题目很重要,这是你编程思路的基础(实际的工作中根本没有题目,只有业务问题,要把业务问题梳理成可以解决的题目是我们要做的),首先是要算出x和y上升和下降的次数,另外要算出它们同时上升和下降的次数,最后算出这些同步次数占总观测数的比例,先上代码:
findud<-function(v)
{vud<-v[-1]-v[-length(v)] #这行代码巧妙实现了后一个值减前一个值,利用-号
return(ifelse(vud>0,1,-1)) #上升趋势返回1,下降趋势返回-1
}
udcorr<-function(x,y){
ud<-lapply(list(x,y),findud)#利用lapply()函数求出由x和y的上升、下降行成的向量
return(mean(ud[[1]]==ud[[2]]))#默认将列表均分为两列,找出第一列和第二列趋势相同的值,相同默认返回true(即1),最后求出均值
}
x<-c(5,12,13,3,6,0,1,15,16,8,88)
y<-c(4,2,3,23,6,10,11,12,6,3,2)
udcorr(x,y)
输出结果:
findud<-function(v){
+ vud<-v[-1]-v[-length(v)] #这行代码巧妙实现了后一个值减前一个值,利用-号
+ return(ifelse(vud>0,1,-1)) #上升趋势返回1,下降趋势返回-1
+ }
> udcorr<-function(x,y){
+ ud<-lapply(list(x,y),findud)#利用lapply()函数求出由x和y的上升、下降行成的向量
+ return(mean(ud[[1]]==ud[[2]]))#默认将列表均分为两列,找出第一列和第二列趋势相同的值,相同默认返回true(即1),最后求出均值
+ }
> x<-c(5,12,13,3,6,0,1,15,16,8,88)
> y<-c(4,2,3,23,6,10,11,12,6,3,2)
> udcorr(x,y)
[1] 0.4
本例中,x和y在10次中同时上升3次,得到相关性应为4/10=0.4,代码输出结果一致。当编程技巧提高时,上述代码可以简化
findud<-function(v){
vud<-v[-1]-v[-length(v)] #这行代码巧妙实现了后一个值减前一个值,利用-号
return(ifelse(vud>0,1,-1)) #上升趋势返回1,下降趋势返回-1
}
udcorr<-function(x,y) mean(sign(diff(x))==sign(diff(y))) #diff()函数代表滞后,即后面的值减前面的值,滞后1期就是后一个减前一个,滞后2期是第3个减第1个,第4个减第2个
如果这些案例完全理解,相信会对向量有比较深刻的印象!
第二章向量学习笔记到此结束,下章矩阵和数组再见!