使用data.table中的rleid()
有帮助:
library(data.table)
set.seed(1)
dt <- data.table(in_vec = sample(1:10000,5000,replace = F))
dt[order(in_vec),.(start = min(in_vec),end = max(in_vec)),by = .(grp = rleid(c(0,cumsum(diff(in_vec) > 1))))
]
grp start end
1: 1 4 4
2: 2 6 7
3: 3 14 16
4: 4 19 19
5: 5 26 27
---
2483: 2483 9980 9980
2484: 2484 9988 9988
2485: 2485 9991 9992
2486: 2486 9994 9994
2487: 2487 9997 9998
对于完全基础的解决方案,这应该是性能最高的,因为它不是分组操作:
set.seed(1)
in_vec <- sample(1:10000,replace = F)
in_vec <- sort(in_vec)
grp <- c(0,cumsum(diff(in_vec) > 1))
data.frame(grp = unique(grp),start = in_vec[!duplicated(grp)],end = in_vec[!duplicated(grp,fromLast = T)]
)
,
像这样吗?
dt[,.(start = first(vec),end = last(vec)),int_id]
编辑:我想以下操作将在data.table中完成您需要的工作,根据值的实际范围调整fill = -1
。
set.seed(1)
in_vec <- sample(1:10000,replace = F)
dt <- data.table(vec = in_vec,key = 'vec')
dt[,int_id := cumsum(!shift(vec,1,fill = -1) == vec - 1)]
dt[,int_id]
,
您快到了,只需要使用已排序向量之间的差异来创建一个组。然后对它们进行瞄准。
set.seed(1)
in_vec <- sample(1:10000,replace = F)
in_vec <- sort(in_vec)
grps <- cumsum(c(1,diff(in_vec)>1))
output <- data.frame(do.call(rbind,tapply(in_vec,grps,range)))
names(output) <- c("start","end")
还有dplyr解决方案
set.seed(1)
in_vec <- sample(1:10000,replace = F)
data.frame(x=in_vec) %>%
arrange(x) %>%
mutate(grps=cumsum(c(1,diff(x)>1))) %>%
group_by(grps) %>%
summarise(start=min(x),end=max(x)) %>%
select(start,end)
本文链接:https://www.f2er.com/3133074.html