I want to split a parent sub-vectors such that these conditions hold:
- Each sub-vector has equal and constant length
l
. - The sub-vectors overlap on one another with
l -1
- Number of sub-vector is given as
length(ts) - l 2
- The last sub-vector should include the first element of the parent vector as its last sub-element.
.
ts <- 1:11 # the parent vector
l <- 7 # constant length of sub-vectors to be
m <- length(ts) - l 1 # number of sub-vector to be
split(t(embed(ts, m))[m:1,], 1:m)
When I tried this (with m <- length(ts) - l 1
) I got my l = 7
like I want but m = 5
instead of m = 6
like I want.
#$`1`
#[1] 1 2 3 4 5 6 7
#$`2`
#[1] 2 3 4 5 6 7 8
#$`3`
#[1] 3 4 5 6 7 8 9
#$`4`
#[1] 4 5 6 7 8 9 10
#$`5`
#[1] 5 6 7 8 9 10 11
When I tried this (with m <- length(ts) - l 2
) I got m = 6
like I want but l = 6
instead of l = 7
.
ts <- 1:11 # the parent vector
l <- 7 # constant length of sub-vectors to be
m <- length(ts) - l 2 # number of sub-vector to be
split(t(embed(ts, m))[m:1,], 1:m)
This is what I got
#$`1`
#[1] 1 2 3 4 5 6
#$`2`
#[1] 2 3 4 5 6 7
#$`3`
#[1] 3 4 5 6 7 8
#$`4`
#[1] 4 5 6 7 8 9
#$`5`
#[1] 5 6 7 8 9 10
#$`6`
#[1] 6 7 8 9 10 11
What I Want
#$`1`
#[1] 1 2 3 4 5 6 7
#$`2`
#[1] 2 3 4 5 6 7 8
#$`3`
#[1] 3 4 5 6 7 8 9
#$`4`
#[1] 4 5 6 7 8 9 10
#$`5`
#[1] 5 6 7 8 9 10 11
#$`6`
#[1] 6 7 8 9 10 11 1
CodePudding user response:
If it only has to work for parent vectors that contain sequences of integers from 1 (like 1:10
, 1:8
) then this should do:
ts <- 1:11
l <- 7
m <- length(ts) - l 2
lapply(1:m, function(x) {
y <- x:(x l-1)
y <- ifelse(y>max(ts), y-max(ts), y)} #here you make sure that 12 becomes 1 etc.
)
But if you want this to work for any type of atomic vector (e.g. the letters A, B, C...K) , do this:
ts2 <- LETTERS[1:11]
l <- 7
m <- length(ts) - l 2
# the output from the code above is stored to be used as index
idx <- lapply(1:m, function(x) {
y <- x:(x l-1)
y <- ifelse(y>length(ts2), y-length(ts2), y)}
)
# apply index to the parent vector
lapply(idx, function(x) ts2[x])
CodePudding user response:
I would use filter
:
ts <- 1:11
l <- 7
lapply(seq_len(length(ts) - l 2), function(i) {
p <- rep(0, l)
p[i] <- 1
res <- c(stats::filter(rev(ts), filter = p,
circular = TRUE, sides = 1))
rev(res)[seq_len(l)]
})
#[[1]]
#[1] 1 2 3 4 5 6 7
#
#[[2]]
#[1] 2 3 4 5 6 7 8
#
#[[3]]
#[1] 3 4 5 6 7 8 9
#
#[[4]]
#[1] 4 5 6 7 8 9 10
#
#[[5]]
#[1] 5 6 7 8 9 10 11
#
#[[6]]
#[1] 6 7 8 9 10 11 1
CodePudding user response:
Fill a matrix with appropriate dimensions, index, and split
asplit(
matrix(ts, nrow = length(ts) 1, ncol = length(ts) - l 1)[1:(l 1), ],
MARGIN = 2)
#[[1]]
#[1] 1 2 3 4 5 6 7
#
#[[2]]
#[1] 2 3 4 5 6 7 8
#
#[[3]]
#[1] 3 4 5 6 7 8 9
#
#[[4]]
#[1] 4 5 6 7 8 9 10
#
#[[5]]
#[1] 5 6 7 8 9 10 11
#
#[[6]]
#[1] 6 7 8 9 10 11 1
CodePudding user response:
Here you go:
ts <- 1:11 # the parent vector
l <- 7 # constant length of sub-vectors to be
m <- length(ts) - l 2 # number of sub-vector to be
library(magrittr)
lapply(1:m, function(i){
c(0, rep(ts, 4)) %>% # Adding leading zero (cut in first iter; repeat a few times to not run out if we increase m
tail(-i) %>% # Cut first i elements (including added zero)
head(l) # Retain first l of the remaining part
})