Reputation: 357
I have a df looking like this:
I want to get all the Names which have at least 2 consecutive appearences of 1.
In this case, I want to get back only B C D F.
Is there way of doing this?
Upvotes: 2
Views: 52
Reputation: 20095
An option using zoo::rollapply
:
library(zoo)
#One can increase the n for 3, 4 etc consecutive values
# For consecutive 2 values
n =2
df1[apply(df1[-1], 1, function(x)
length(which(rollapply(x, width=n, function(x)all(x==rep(1,n)), align = "left")))>0),1]
#[1] "B" "C" "D" "F"
Upvotes: 2
Reputation: 323326
By using lag
, this will only fit for consecutive 2 , if you need increase the limit , you can check akrun's answer
s=df$Name[apply(df[,c(2:6)],1,function(x) any((lag(x)==x)&x==1))]
s[!is.na(s)]
[1] "B" "C" "D" "F"
Upvotes: 3
Reputation: 887601
We can loop through the rows, use rle
(to find if there are consecutive elements) and create a logical index to subset the 'Names'
df1$Name[apply(df1[-1], 1, function(x) {
rl <- rle(x==1)
any(rl$lengths[rl$values]>=2)})]
#[1] "B" "C" "D" "F"
A faster approach could be to paste
the elements in each row and then use regex lookaround to find if 1 is followed by 1
df1$Name[grepl("(?<=1)1", do.call(paste0, df1[-1]), perl = TRUE)]
#[1] "B" "C" "D" "F"
df1 <- structure(list(Name = c("A", "B", "C", "D", "E", "F"), `2000` = c(1L,
0L, 1L, 1L, 0L, 0L), `2001` = c(0L, 0L, 1L, 1L, 1L, 1L), `2002` = c(0L,
1L, 0L, 1L, 0L, 0L), `2003` = c(1L, 1L, 0L, 1L, 1L, 1L), `2004` = c(0L,
0L, 1L, 1L, 0L, 1L), `2005` = c(1L, 1L, 1L, 0L, 1L, 1L)), .Names = c("Name",
"2000", "2001", "2002", "2003", "2004", "2005"), class = "data.frame",
row.names = c(NA, -6L))
Upvotes: 5