我想从向量x
得到一个滑动窗口em
,大概是这样的
x <- 1:10
em <- embed(x,dimension = 3) [,3:1]
em <- rbind(matrix(NA,nrow = length(x)-nrow(em),ncol = ncol(em)),em)
..
em
[,1] [,2] [,3]
[1,] NA NA NA
[2,] NA NA NA
[3,] 1 2 3
[4,] 2 3 4
[5,] 3 4 5
[6,] 4 5 6
[7,] 5 6 7
[8,] 6 7 8
[9,] 7 8 9
[10,] 8 9 10
> x
[1] 1 2 3 4 5 6 7 8 9 10
但我绝对不喜欢这个代码,它很繁琐,也很难理解. 你能给我推荐一些你觉得更简洁的 Select 吗?
= 做了一个小小的比较
n <- 5
x <- 1:200
fu1 <- function(x, n){
m <- embed(x,dimension = n) [,n:1]
rbind(matrix(NA,nrow = length(x)-nrow(m),ncol = ncol(m)),m)
m
}
fu2 <- function(x, n){
m <- matrix(NA, nrow = length(x), ncol = n)
m[n:length(x),] <- t(sapply(1:(length(x)-(n-1)), function(i) x[i:(i+(n-1))]))
m
}
fu3 <- function(x, n){
m <- matrix(NA, nrow = length(x), ncol = n)
for (i in n:length(x)) m[i,] <- x[(i-(n-1)):(i)]
m
}
fu4 <- function(x, n){
m <- zoo::rollapply(data = x, width = n, FUN = as.list)
m <- rbind(matrix(NA,nrow = length(x)-nrow(m),ncol = ncol(m)),m)
m
}
fu5 <- function(x, n){
zoo::rollapplyr(x, n, c, fill = NA)
}
fu6 <- function(x, n){
k <- seq_along(x)
idx <- c(outer(head(k, 1 - n), head(k - 1, n), `+`))
m <- matrix(x[idx], ncol = n)
rbind(matrix(NA,nrow = length(x)-nrow(m),ncol = ncol(m)),m)
}
fu7 <- function(x, n){
m <- t(sapply(head(seq_along(x), 1 - n), \(k) x[k:(k + (n-1))]))
rbind(matrix(NA,nrow = length(x)-nrow(m),ncol = ncol(m)),m)
}
.....
microbenchmark::microbenchmark( fu1(x,n),
fu2(x,n),
fu3(x,n),
fu4(x,n),
fu5(x,n),
fu6(x,n),
fu7(x,n))
Unit: microseconds
expr min lq mean median uq max neval
fu1(x, n) 90.657 120.5910 140.4726 133.4195 142.5420 511.441 100
fu2(x, n) 898.586 1011.4790 1295.2010 1071.6320 1174.2625 11882.315 100
fu3(x, n) 322.716 371.4650 851.5983 387.4300 417.3635 23120.339 100
fu4(x, n) 8308.497 9917.2290 11594.9786 10481.1260 11391.4000 37111.138 100
fu5(x, n) 23263.451 26653.6745 29845.5357 27709.9120 30243.4565 80859.609 100
fu6(x, n) 192.147 238.0455 271.7939 270.2610 291.3560 522.844 100
fu7(x, n) 933.936 1078.7590 1343.0666 1146.6095 1203.3410 11592.100 100