我有这样的矢量
t<-c(9,9,9,9,9,9,10,10,10,10,8,8,8,8,8,200,8,8,7,9,9,9,9,9)
我想得到的是每次运行相同字符的每个开始和结束的索引。取9.输出将是1到6和20到24.对于7,它将只有19.有没有办法编写一个函数,在其中输入特定的数字(如9或7),然后只输出R?
中概述的不明印迹答案 0 :(得分:1)
使用基本编程方法和简单的可调代码。基数R可能会有所帮助:
t<-c(9,9,9,9,9,9,10,10,10,10,8,8,8,8,8,200,8,8,7,9,9,9,9,9)
i = 1; j=1
while(!is.na(t[i+2])){
while(t[i]==t[i+1]) {i=i+1; if(is.na(t[i+1]))break; }
i=i+1
cat("number=",t[i-1],"times=",(i-j),"start=",j,"end=",i-1,'\n')
j = i
}
number= 9 times= 6 start= 1 end= 6
number= 10 times= 4 start= 7 end= 10
number= 8 times= 5 start= 11 end= 15
number= 200 times= 1 start= 16 end= 16
number= 8 times= 2 start= 17 end= 18
number= 7 times= 1 start= 19 end= 19
number= 9 times= 5 start= 20 end= 24
获取数据框:
outdf = data.frame(number=numeric(), start=numeric(), end=numeric(), times=numeric())
i = 1; j=1
while(!is.na(t[i+2])){
while(t[i]==t[i+1]) {i=i+1; if(is.na(t[i+1]))break; }
i=i+1
outdf[nrow(outdf)+1,] = c(t[i-1], j, i-1, i-j)
j = i
}
outdf
number start end times
1 9 1 6 6
2 10 7 10 4
3 8 11 15 5
4 200 16 16 1
5 8 17 18 2
6 7 19 19 1
7 9 20 24 5
对于一个数字的函数:
myfn = function(num){
outdf = data.frame(number=numeric(), start=numeric(), end=numeric(), times=numeric())
i = 1; j=1
while(!is.na(t[i+2])){
while(t[i]==t[i+1]) {i=i+1; if(is.na(t[i+1]))break; }
i=i+1
if(t[i-1]==num) {outdf[nrow(outdf)+1,] = c(t[i-1], j, i-1, i-j)}
j = i
}
outdf
}
myfn(10)
number start end times
1 10 7 10 4
myfn(9)
number start end times
1 9 1 6 6
2 9 20 24 5
myfn(8)
number start end times
1 8 11 15 5
2 8 17 18 2
编辑:正如beginneR和Carl Witthoft在评论中所建议的那样:
rle(t)
Run Length Encoding
lengths: int [1:7] 6 4 5 1 2 1 5
values : num [1:7] 9 10 8 200 8 7 9
但这里的输出有点神秘。
答案 1 :(得分:1)
正如beginneR所说,只需使用rle
即可。输出为您提供每次值变化的起点,因此很容易计算出运行位置。
t<-c(9,9,9,9,9,9,10,10,10,10,8,8,8,8,8,200,8,8,7,9,9,9,9,9)
rlet<-rle(t)
rlet
Run Length Encoding
lengths: int [1:7] 6 4 5 1 2 1 5
values : num [1:7] 9 10 8 200 8 7 9
只需将lengths
值汇总到values==9
的每个实例,依此类推。
答案 2 :(得分:1)
以下是rle
解决方案
f <- function(t, n) {
x <- rle(t)
i <- x$values == n
end.pos <- cumsum(x$lengths)[i]
start.pos <- end.pos - x$lengths[i] + 1
data.frame(from = start.pos, to = end.pos)
}
t <- c(9,9,9,9,9,9,10,10,10,10,8,8,8,8,8,200,8,8,7,9,9,9,9,9)
f(t, 9)
# from to
# 1 6
# 20 24
f(t, 7)
# from to
# 19 19
您可以修改f
的返回值,以获得所需格式的输出。
或者,将which
与diff
一起使用,从而提供更好的效果
f2 <- function(t, n) {
i <- which(t == n)
start.i <- c(0, which(diff(i) != 1)) + 1
end.i <- c(start.i[-1] - 1, length(i))
data.frame(from = i[start.i], to = i[end.i])
}
比较表现:
tt <- rep(t, 100)
library(microbenchmark)
microbenchmark(f = f(tt, 9), f2 = f2(tt, 9))
# Unit: microseconds
# expr min lq median uq max neval
# f 578.733 582.0575 584.7530 594.4130 1177.366 100
# f2 350.153 354.1275 358.5175 378.0135 1186.022 100
答案 3 :(得分:0)
bool started = false;
int start = -1;
int end = -1;
for(i in t.length) :
if(t[i]==wantedNumber) started = true ; start = i ;
else if (started && t[i]!=wantedNumber) end = i ; break;