Find all related combinations

I have a vector:

data <- c("ta", "tb", "tc", "tk", "tf")

How to convert this vector to a list that includes every possible combination of n (where n contains adjacent elements from 2 to length (data) -1)? The list should look like this (each line represents a list item):

"ta", "tb"
"tb", "tc"
"tc", "tk"
"tk", "tf"
"ta", "tb", "tc"
"tb", "tc", "tk"
"tc", "tk", "tf"
"ta", "tb", "tc", "tk"
"tb", "tc", "tk", "tf"

I need to perform this operation many times, so speed is important. Thanks!

+4
source share
3 answers

Edit: new feature

myFun <- function(Data) {
  A <- lapply(2:(length(Data)-1), sequence)
  B <- lapply(rev(vapply(A, length, 1L))-1, function(x) c(0, sequence(x)))
  unlist(lapply(seq_along(A), function(x) {
    lapply(B[[x]], function(y) Data[A[[x]]+y])
  }), recursive = FALSE, use.names = FALSE)
}

Using:

myFun(data)

Original Function

Here is a solution using rollapplyfrom "zoo":

myFun <- function(Data, singles = FALSE) {
  require(zoo)
  x <- 2:(length(Data)-1)
  out <- lapply(x, function(y) rollapply(Data, FUN = c, width = y))
  if (isTRUE(singles)) {
    out <- unlist(lapply(out, function(y) split(y, sequence(nrow(y)))),
                  recursive = FALSE, use.names = FALSE)
  }
  out
}

( ), singles = TRUE:

myFun(data, singles = TRUE)
# [[1]]
# [1] "ta" "tb"
# 
# [[2]]
# [1] "tb" "tc"
# 
#######
# SNIP
#######
# 
# [[8]]
# [1] "ta" "tb" "tc" "tk"
# 
# [[9]]
# [1] "tb" "tc" "tk" "tf"
+2

:

adj.poss <- function(x) {
  n <- length(x)
  stopifnot(n > 2L)
  idx <- expand.grid(start = 1L:n, len = 2L:(n-1L))
  idx$end <- idx$start + idx$len - 1L
  idx <- idx[idx$end <= n, ]
  Map(function(start, end) x[start:end], idx$start, idx$end)
}

adj.poss(data) , .

+2

data.table vecseq. , vecseq(x, y, clamp) x y x: (x + len). vecseq(c(1L, 4L), c(2L, 6L), 5L) c(1L, 2L, 4L, 5L, 6L). clamp - , >= . , .

, vecseq, , . , , ( :)).

data <- c("ta", "tb", "tc", "tk", "tf")
require(data.table)
ff <- data.table:::vecseq
my_fun <- function(data) {
    xmin = 2L
    xmax = length(data)-1L
    len = xmax-xmin+1L
    tot = sum(xmax:xmin)

    t1 = ff(rep(1L, len), xmax:xmin, tot)
    t2 = rep.int(xmin:xmax, xmax:xmin)
    idx = ff(t1,t2,sum(t2))
    dt = data.table(x=data[idx], id=rep.int(seq_along(t2), t2))
    setattr(dt, 'sorted', 'id')
    dt[J(seq_along(t2)), list(list(x))]$V1
}

This seems pretty fast and matches the @flodel rating (excellent). When the data length reaches 250, the difference is about 0.2 seconds (this solution is faster). So there is not much difference.

+2
source

All Articles