1

I have a list of all possible binary 12-length vectors in R via

all_possible_permutations <- expand.grid(replicate(12, 0:1, simplify = FALSE))

I'd like to flag all vectors where two non-zero cells are adjacent to one another.

So for instance

1 0 1 0 1 0 1 0 1 0 1 0 <- Not Flagged
1 1 0 1 0 1 0 1 0 1 0 1 <- Flagged (due to the first 2)
user1357015
  • 11,168
  • 22
  • 66
  • 111

2 Answers2

2

For any binary vector x, we can use the following logic to detect existing pattern of two adjacent 1:

flag <- function (x) sum(x == 1 & c(diff(x) == 0, FALSE)) > 0

x <- c(1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1)
flag(x)
#[1] TRUE

x <- c(1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0)
flag(x)
#[1] FALSE

So we can apply this to all columns of your data frame DF:

sapply(DF, flag)

As r2evans commented, this also works:

flag <- function (x) any(x == 1 & c(diff(x) == 0, FALSE))

Using sum gives you a by-product: it tells you the number of matches.


Gosh, you want to apply flag for every row not every column of DF. So I should not use sapply. In this case, let's do a full vectorization:

MAT <- t(DF)
result <- colSums(MAT == 1 & rbind(diff(MAT) == 0, FALSE)) > 0
table(result)
#FALSE  TRUE 
#  377  3719 

In this case colSums can not be changed to any. The vectorization comes at more memory usage, but is probably worthwhile.

Zheyuan Li
  • 71,365
  • 17
  • 180
  • 248
2

You can use rle since this is binary ie 0 and 1s:

flag = function(x)any(with(rle(x),lengths[values==1]>1))

if non binary, yet you want to check if two adjacent elements are non zero then:

flag = function(x)any(with(rle(x>0),lengths[values]>1))

which is a generalized case taking into account the binary and non-binary

Onyambu
  • 67,392
  • 3
  • 24
  • 53