欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

R语言-寻找向量内的游程

程序员文章站 2024-02-25 22:22:51
...

前言:根据scong123的文章的启发,利用for循环和all函数,寻找向量内连续为某个数的游程。

向量中,由同一元素组成且被另一元素分隔的每一段连续子集,称做一个游程。

假定我们要寻找的是连续为1的游程,k为所规定的游程的长度。代码和解释如下:


findruns<-function(x,k){#寻找连续为1的游程
  n<-length(x)#x的长度
  runs<-NULL#创建向量容器
  
  for(i in 1:(n-(k-1))){#1到n-(k-1)
    if(all(x[i:(i+k-1)]==1))#若全部x[i:(i+(k-1))]均为1
      runs<-c(runs,i)
    }#在runs中依次填入i
  
  return(runs)
}

x<-round(runif(10),0);n<-length(x);x
findruns(x,1)#k=1时,1到n-0内,若x[i]==1,即x内任一元素为1,则该位置计为游程起点
findruns(x,2)#k=2时,1到n-1内,若x[i:i+1]==1,即x内相邻2个元素均为1,则该位置计为游程起点
findruns(x,3)#k=3时,1到n-2内,若x[i:i+2]==1,即x内相邻3个元素均为1,则该位置计为游程起点
findruns(x,n-2)#k=n-2时,1到3内,若x[i:(n-3)+i]==1,即c(x[1:n-2],x[2:n-1],x[3,n])均为1,则该位置计为游程起点
findruns(x,n-1)#k=n-1时,1到2内,若x[i:(n-2)+i]==1,即c(x[1:n-1],x[2:n])均为1,则该位置计为游程起点
findruns(x,n)#k=n时,若x[1:n]==1,即全体x内元素均为1,则向量起点即为游程起点

举例: 

以x生成向量:(1 1 1 0 1 1 1 0 0 0)为例

x<-round(runif(10),0);n<-length(x);x

k=1时,1出现在第1 2 3 5 6 7个元素上。(R中向量从1开始计数,而Python从0开始计数)

(一般以向量内,长度为2≤k≤n-1的连续子集,算为一个游程。)

k=2时,相邻2个数均为1的游程,出现在x的第1 2 5 6位上。

k=3时,相邻3个数均为1的游程,出现在x的第1 5位上。

k大于3时,游程不存在,结果为NULL

再以长度为10的向量(1 1 1 1 1 1 1 1 1 0)为例

x<-c(rep(1,9),0);n<-length(x);x

k=10-2=8时,x[1:8],x[2:9]均为1,相邻8个数均为1的游程,出现在x的第1 2位上。

k=10-1=9时,x[1:9]均为1,相邻9个数均为1的游程,出现在x的第1位上,即x的前9个元素组成一个游程。

并非x内所有元素均为10,所以k=10时,结果为NULL

(一般规定游程是由同一元素组成且被另一元素分隔的每一段连续子集,所以游程长度k的定义范围一般为2到n-1)


引申思考:

若寻找向量内,任意连续子集的位置,该如何编写函数呢?提示:设定all(x[i:(i+k-1)]==?),然后循环所有元素,查找向量内所有元素的连续子集。

请问除此以外,还有没有其他方法呢?


参考文献:

https://blog.csdn.net/scong123/article/details/70184038

https://cn.bing.com