我需要找到并计算3个或多个连续零后以1出现的ID。
这是我所拥有的一个例子:
# ID Jan Feb Mar Apr May Jun Jul Aug Sept Oct
# 1 0 0 0 1 0 0 1 1 1 0
# 2 0 0 0 0 0 0 1 0 0 0
# 3 0 0 0 0 0 0 0 0 0 1
# 4 1 0 0 1 0 1 0 1 0 1
# 5 0 0 1 0 0 1 1 0 0 1
c1<- c("ID","Jan","Feb", "Mar","Apr", "May","Jun", "Jul", "Aug", "Sept", "Oct")
c2<- c(1,0,0,0,1,0,0,1,1,1,0)
c3<- c(2,0,0,0,0,0,0,1,0,0,0)
c4<- c(3,0,0,0,0,0,0,0,0,0,1)
c5<- c(4,1,0,0,1,0,1,0,1,0,1)
c6<- c(5,0,0,1,0,0,1,1,0,0,1)
BD<-data.frame(rbind(c2,c3,c4,c5,c6))
colnames(BD)<-c1
我期望的结果是这样的:
# ID Jan Feb Mar Apr May Jun Jul Aug Sept Oct
# 1 0 0 0 1 0 0 1 1 1 0
# 2 0 0 0 0 0 0 1 0 0 1
# 3 0 0 0 0 0 0 0 0 0 1
有人知道怎么做吗?谢谢!
答案 0 :(得分:2)
如果采用向量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
答案 1 :(得分:2)
您可以折叠成字符串,然后使用grep()
搜索模式。
k <- 3
grep(sprintf(paste0("%0", k + 1, "d"), 1), apply(d[-1], 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)))
答案 2 :(得分:1)
您可以将行合并为字符串,并使用正则表达式匹配“ 0001”:
library(tidyverse)
rows = BD %>%
purrr::pmap(function(...) paste0(list(...)[-1], collapse='')) %>%
stringr::str_detect('0001')
BD[rows,]
答案 3 :(得分:1)
这是可以实现的基本R解决方案
BDout <- subset(BD,apply(BD[-1], 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
答案 4 :(得分:1)
使用Numeric value: 755
来融合和过滤符合条件的行的选项。
data.table
对于具有稀疏数据的大型数据集,它应该更快。