質問はタイトルで説明されています。私の問題では、ベクトルはかなり長く、約 1,500 です。私が試みていた1つの方法は、次のように行列を生成することです.
大まかに言えば、この行列はrbind
3 つの対角行列 、diag(1, 3)
、diag(1,2)
およびdiag(1,1)
です。ただし、これらの行列の列数は異なります。したがってrbind
、ここでは適用されません。この問題を解決する効率的な方法はありますか。
を使用して、これを非常に簡単に行うこともできますlower.tri
。
vec <- 1:4
m <- matrix(rep(vec, length(vec)), length(vec))
m[lower.tri(m, diag=TRUE)]
# [1] 1 2 3 4 2 3 4 3 4 4
これは、@ Juliusの賢い答えよりも少し遅いです。ベンチマークについては彼を参照してください。
すでにいくつかの優れたソリューションがあります。zoo
それでも、別の方法で試してみます。
library(zoo)
# the vector
x1 <- c("a1", "a2", "a3")
n <- length(x1)
# convert to zoo object
x2 <- zoo(x1)
# lag the vector with a vector of lags
x3 <- lag(x2, k = seq(from = 0, by = 1, length.out = n))
# convert back to vector
na.omit(as.vector(x3))
# [1] "a1" "a2" "a3" "a2" "a3" "a3"
効率についてはわかりませんが、使用したソリューションは次のとおりです。
lst <- list(
diag(1, 3),
diag(1,2) ,
diag(1,1)
)
cols <- sapply(lst, ncol)
mcol <- max(cols)
rows <- sapply(lst, nrow)
nums <- (mcol - cols)*rows
compile <- function(x, y, z) {
if (y == 0) return(z)
cbind(matrix(rep(0, y), nrow = x), z)
}
do.call(rbind, mapply(compile, rows, nums, lst))
#' [,1] [,2] [,3]
#' [1,] 1 0 0
#' [2,] 0 1 0
#' [3,] 0 0 1
#' [4,] 0 1 0
#' [5,] 0 0 1
#' [6,] 0 0 1