Home > Software design >  How to generate all possible consecutive tuples of a vector in R?
How to generate all possible consecutive tuples of a vector in R?

Time:08-07

How can to generate all possible consecutive n-tuples of a vector in R ?

# Input 
x <- c('a', 'b', 'c', 'b')
n = 2
# Output 
list(c('a', 'b'), c('b', 'c'), c('c', 'b')) # a list equal to this list

CodePudding user response:

We may remove the first and last elements and concatenate by looping over the corresponding elements with Map

Map(c, x[-length(x)], x[-1])
$a
[1] "a" "b"

$b
[1] "b" "c"

$c
[1] "c" "b"

Or cbind to a matrix and split by row with asplit

asplit(cbind(x[-length(x)], x[-1]), 1)
[[1]]
[1] "a" "b"

[[2]]
[1] "b" "c"

[[3]]
[1] "c" "b"

If the n values can be more than 2, we may also do this with shift

library(data.table)
Filter(\(x) all(complete.cases(x)), 
  data.table::transpose(shift(x, seq_len(n)-1, type = 'lead')))
[[1]]
[1] "a" "b"

[[2]]
[1] "b" "c"

[[3]]
[1] "c" "b"

CodePudding user response:

I prefer to using a matrix to store the results:

n <- 2
mat2 <- matrix(x[sequence(rep(length(x) - n   1, n), 1:n)], ncol = n)
#     [,1] [,2]
#[1,] "a"  "b" 
#[2,] "b"  "c" 
#[3,] "c"  "b" 

n <- 3
mat3 <- matrix(x[sequence(rep(length(x) - n   1, n), 1:n)], ncol = n)
#     [,1] [,2] [,3]
#[1,] "a"  "b"  "c" 
#[2,] "b"  "c"  "b" 

If you insist on using a list, then:

n <- 2
lst2 <- split(x[sequence(rep(length(x) - n   1, n), 1:n)], seq_len(length(x) - n   1))
#$`1`
#[1] "a" "b"
#
#$`2`
#[1] "b" "c"
#
#$`3`
#[1] "c" "b"

n <- 3
lst3 <- split(x[sequence(rep(length(x) - n   1, n), 1:n)], seq_len(length(x) - n   1))
#$`1`
#[1] "a" "b" "c"
#
#$`2`
#[1] "b" "c" "b"

I don't use embed or asplit. They have a for-loop inside.

  • Related