首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在R中求向量中的历数范围

如何在R中求向量中的历数范围
EN

Stack Overflow用户
提问于 2016-03-16 16:31:33
回答 3查看 506关注 0票数 2

我在R中有一个向量:

代码语言:javascript
复制
data <- c(1,4,6,7,8,9,20,30,31,32,33,34,35,60)

我想要的是找到一个连续延伸超过3个连续值的开始和结束。即:

代码语言:javascript
复制
start end
3  6  (stretch 6-9)
8 13 (stretch 30-35

我不知道怎么去那里。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2016-03-16 18:16:28

@eddi's answer到我的类似问题..。

代码语言:javascript
复制
runs = split(seq_along(data), cumsum(c(0, diff(data) > 1)))
lapply(runs[lengths(runs) > 1], range)

# $`2`
# [1] 3 6
# 
# $`4`
# [1]  8 13

它的工作原理:

  • seq_along(data)data的索引,来自1..length(数据)
  • c(0, diff(data) > 1)data“跳转”的每个索引处都有一个1
  • cumsum(c(0, diff(data) > 1))是跳转之间连续运行的标识符。

因此,runsdata指数的一部分,分为data值连续运行的几个部分。

票数 5
EN

Stack Overflow用户

发布于 2016-03-16 17:26:51

因此,首先取a的diff并对其执行一个运行长度序列。然后,起点是2s之前的指数,终点是这些指标的负值。很难解释,只要一步一步地看一下代码就可以了。找不到两个序列..。类似于(1,3,4,7,9)中的(3,4)我必须包括remove部分的序列,是由两个.(1、3、5、7)。那些没有被正确捕捉到。任何方法,有趣的运动。我希望有人能做得更好。这有点乱..。

代码语言:javascript
复制
data <- c(1,4,6,7,8,9,20,30,31,32,33,34,35,60)
a <- sequence(rle(diff(data))$lengths)
starts <- which(a==2) - 1
ends <- which(diff(a)<0) + 1
remove <- starts[starts %in% (ends-2)]
starts <- starts[!starts %in% remove]
ends <- ends[!ends %in% (remove+2)]
if(length(ends) < length(starts)) ends <- c(ends, length(data))
> starts
[1] 3 8
> ends
[1]  6 13
> 
票数 0
EN

Stack Overflow用户

发布于 2016-03-16 18:15:27

下面是一个严重依赖?diff的基本R解决方案

代码语言:javascript
复制
data <- c(1,4,6,7,8,9,20,30,31,32,33,34,35,60)

diff1 <- diff(data[1:(length(data)-1)]) # lag 1 difference
diff2 <- diff(data, 2) # lag 2 difference

# indices of starting consecutive stretches -- these will overlap
start_index <- which(diff1==1 & diff2==2)
end_index <- start_index + 2

# notice that these overlap:
data.frame(start_index, end_index)

# To remove overlap:
# We can remove *subsequent* consecutive start indices
#           and *initial* consecutive end indices

start_index_new <- start_index[which(c(0, diff(start_index))!=1)]
end_index_new <- end_index[which(c(diff(end_index), 0) != 1)]
data.frame(start_index_new, end_index_new)

#   start_index_new end_index_new
# 1               3             6
# 2               8            13

科里的答案很好--这个答案可能更容易理解,因为你基本上是在检查,从位置i,位置i+1值多1,位置i + 2值多2的情况。在此基础上构建范围,然后使用另一个diff函数合并范围。在我看来,这有点简单。

还有一些包可以像zoo那样使用,它们可以帮助您获得滚动的差异。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36041576

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档