如果采用向量rowid(rleid(x))
的{{1}},则每个元素的“运行”步数为*。您可以检查它是否> = 3并且元素为0。如果对于前一个元素(对于移位输出)为true,并且元素为1,则返回TRUE。然后检查该行中x
个元素的真性。
any
*这是特定行(第一行)的示例
library(data.table)
rows <-
apply(BD,1,function(r) any(shift(rowid(rleid(r)) >= 3 & r == 0) & r == 1))
BD[rows,]
# ID Jan Feb Mar Apr May Jun Jul Aug Sept Oct
# c2 1 0 0 0 1 0 0 1 1 1 0
# c3 2 0 0 0 0 0 0 1 0 0 0
# c4 3 0 0 0 0 0 0 0 0 0 1
,
您可以折叠成字符串,然后使用grep()
搜索模式。
k <- 3
grep(sprintf(paste0("%0",k + 1,"d"),1),apply(d[-1],paste,collapse=""))
# [1] 2 4 5 6 8
如果不需要以下1,则可以使用rle()
。
d
# id Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec
# c1 1 1 1 0 1 1 0 0 1 1 1 0 0
# c2 2 0 0 0 1 1 1 0 1 1 0 1 0
# c3 3 1 0 0 1 1 0 1 1 1 0 1 0
# c4 4 0 0 0 0 0 1 1 0 0 1 1 0
# c5 5 0 0 0 1 1 1 1 0 0 1 0 1
# c6 6 1 0 0 0 1 0 1 0 0 0 0 1
# c7 7 0 1 0 0 1 0 1 1 1 0 0 1
# c8 8 0 1 1 1 1 1 1 1 0 0 0 1
# c9 9 0 1 0 0 1 1 0 0 1 1 1 0
# c10 10 1 1 0 1 0 1 1 0 0 1 0 1
k <- 3
d$id[sapply(as.data.frame(t(d[-1])),function(x) any(rle(x)$lengths[rle(x)$values == 0] >= k))]
# [1] 2 4 5 6 8
数据:
set.seed(0)
d <- data.frame(id=1:10,`dimnames<-`(matrix(sample(0:1,120,r=1),10),list(paste0("c",1:10),month.abb)))
,
您可以将行合并为字符串,并使用正则表达式匹配“ 0001”:
library(tidyverse)
rows = BD %>%
purrr::pmap(function(...) paste0(list(...)[-1],collapse='')) %>%
stringr::str_detect('0001')
BD[rows,]
,
这是可以实现的基本R解决方案
BDout <- subset(BD,apply(BD[-1],function(x) head(which(x==1),1))>3)
这样
> BDout
ID Jan Feb Mar Apr May Jun Jul Aug Sept Oct
1 1 0 0 0 1 0 0 1 1 1 0
2 2 0 0 0 0 0 0 1 0 0 0
3 3 0 0 0 0 0 0 0 0 0 1
,
使用Numeric value: 755
来融合和过滤符合条件的行的选项。
data.table
对于具有稀疏数据的大型数据集,它应该更快。
本文链接:https://www.f2er.com/2824583.html