围绕现有值将序列放入矩阵中
Putting a sequence into a matrix around existing values
我想生成一个围绕零对角线的对称矩阵以及围绕它们的预定序列。理论上,这些行应该显示为
0 1 3 5 7 9
1 0 3 5 7 9
我试过调整条件,但我怀疑它因为索引而变得不稳定,我还远没有足够的技能来修复它。
bend <- function(n){
m <- seq(1, n, by=2)
a <- length(m)
y <- matrix(nrow= a, ncol = a, byrow= TRUE)
y <- ifelse(row(y) == col(y), 0, m)
y
}
假设输入是 9,预期输出是
0 1 3 5 7 9
1 0 3 5 7 9
1 3 0 5 7 9
1 3 5 0 7 9
1 3 5 7 0 9
1 3 5 7 9 0
实际输出为
0 3 5 7 9 1
3 0 7 9 1 3
5 7 0 1 3 5
7 9 1 0 5 7
9 1 3 5 0 9
1 3 5 7 9 0
有一种更简单的方法可以满足您的需要。您可以先创建一个包含 length(x) + 1
列和行的 matrix
,并将所有元素作为逻辑 TRUE
。然后使用 diag()
制作对角线 FALSE
。现在您可以将 TRUE
替换为您想要的向量。 FALSE
的对角线不受影响。由于值被替换 column-wise 您需要最终转置 t()
以获得正确的结果。
这样,您就无需担心跟踪索引。
x <- c(1,3,5,7,9)
make_matrix <- function(x) {
m <- matrix(TRUE, ncol = length(x) + 1, nrow = length(x) + 1)
diag(m) <- FALSE
m[m] <- x
t(m)
}
make_matrix(x)
[,1] [,2] [,3] [,4] [,5] [,6]
[1,] 0 1 3 5 7 9
[2,] 1 0 3 5 7 9
[3,] 1 3 0 5 7 9
[4,] 1 3 5 0 7 9
[5,] 1 3 5 7 0 9
[6,] 1 3 5 7 9 0
这是 sapply
的另一种方式。这会在每次迭代中创建必要的行元素,并将它们按列放入矩阵中。同样,您需要 t()
才能获得正确的结果。 -
sapply(0:length(x), function(a) append(x, 0, after = a)) %>% t()
[,1] [,2] [,3] [,4] [,5] [,6]
[1,] 0 1 3 5 7 9
[2,] 1 0 3 5 7 9
[3,] 1 3 0 5 7 9
[4,] 1 3 5 0 7 9
[5,] 1 3 5 7 0 9
[6,] 1 3 5 7 9 0
基准 -
sapply
较慢,可能是因为它一次创建一行矩阵元素并为每一行调用 append
。 make_matrix()
方法避免了所有这些开销。
x <- sample(100)
microbenchmark(
make_matrix = make_matrix(x),
sapply = t(sapply(0:length(x), function(a) append(x, 0, after = a))),
akrun_forloop = {
n <- length(x) + 1
m1 <- matrix(0, n, n)
for(i in seq_len(nrow(m1))) m1[i, -i] <- x
},
times = 1000
)
Unit: microseconds
expr min lq mean median uq max neval
make_matrix 111.495 117.5610 128.3135 126.890 135.7540 225.323 1000
sapply 520.620 551.1765 592.2642 573.335 602.2585 10477.221 1000
akrun_forloop 3380.292 3526.3080 3837.1570 3648.765 3812.5075 20943.245 1000
使用简单的 for
循环
n <- length(x) + 1
m1 <- matrix(0, n, n)
for(i in seq_len(nrow(m1))) m1[i, -i] <- x
m1
# [,1] [,2] [,3] [,4] [,5] [,6]
#[1,] 0 1 3 5 7 9
#[2,] 1 0 3 5 7 9
#[3,] 1 3 0 5 7 9
#[4,] 1 3 5 0 7 9
#[5,] 1 3 5 7 0 9
#[6,] 1 3 5 7 9 0
数据
x <- c(1,3,5,7,9)
我想生成一个围绕零对角线的对称矩阵以及围绕它们的预定序列。理论上,这些行应该显示为
0 1 3 5 7 9
1 0 3 5 7 9
我试过调整条件,但我怀疑它因为索引而变得不稳定,我还远没有足够的技能来修复它。
bend <- function(n){
m <- seq(1, n, by=2)
a <- length(m)
y <- matrix(nrow= a, ncol = a, byrow= TRUE)
y <- ifelse(row(y) == col(y), 0, m)
y
}
假设输入是 9,预期输出是
0 1 3 5 7 9
1 0 3 5 7 9
1 3 0 5 7 9
1 3 5 0 7 9
1 3 5 7 0 9
1 3 5 7 9 0
实际输出为
0 3 5 7 9 1
3 0 7 9 1 3
5 7 0 1 3 5
7 9 1 0 5 7
9 1 3 5 0 9
1 3 5 7 9 0
有一种更简单的方法可以满足您的需要。您可以先创建一个包含 length(x) + 1
列和行的 matrix
,并将所有元素作为逻辑 TRUE
。然后使用 diag()
制作对角线 FALSE
。现在您可以将 TRUE
替换为您想要的向量。 FALSE
的对角线不受影响。由于值被替换 column-wise 您需要最终转置 t()
以获得正确的结果。
这样,您就无需担心跟踪索引。
x <- c(1,3,5,7,9)
make_matrix <- function(x) {
m <- matrix(TRUE, ncol = length(x) + 1, nrow = length(x) + 1)
diag(m) <- FALSE
m[m] <- x
t(m)
}
make_matrix(x)
[,1] [,2] [,3] [,4] [,5] [,6]
[1,] 0 1 3 5 7 9
[2,] 1 0 3 5 7 9
[3,] 1 3 0 5 7 9
[4,] 1 3 5 0 7 9
[5,] 1 3 5 7 0 9
[6,] 1 3 5 7 9 0
这是 sapply
的另一种方式。这会在每次迭代中创建必要的行元素,并将它们按列放入矩阵中。同样,您需要 t()
才能获得正确的结果。 -
sapply(0:length(x), function(a) append(x, 0, after = a)) %>% t()
[,1] [,2] [,3] [,4] [,5] [,6]
[1,] 0 1 3 5 7 9
[2,] 1 0 3 5 7 9
[3,] 1 3 0 5 7 9
[4,] 1 3 5 0 7 9
[5,] 1 3 5 7 0 9
[6,] 1 3 5 7 9 0
基准 -
sapply
较慢,可能是因为它一次创建一行矩阵元素并为每一行调用 append
。 make_matrix()
方法避免了所有这些开销。
x <- sample(100)
microbenchmark(
make_matrix = make_matrix(x),
sapply = t(sapply(0:length(x), function(a) append(x, 0, after = a))),
akrun_forloop = {
n <- length(x) + 1
m1 <- matrix(0, n, n)
for(i in seq_len(nrow(m1))) m1[i, -i] <- x
},
times = 1000
)
Unit: microseconds
expr min lq mean median uq max neval
make_matrix 111.495 117.5610 128.3135 126.890 135.7540 225.323 1000
sapply 520.620 551.1765 592.2642 573.335 602.2585 10477.221 1000
akrun_forloop 3380.292 3526.3080 3837.1570 3648.765 3812.5075 20943.245 1000
使用简单的 for
循环
n <- length(x) + 1
m1 <- matrix(0, n, n)
for(i in seq_len(nrow(m1))) m1[i, -i] <- x
m1
# [,1] [,2] [,3] [,4] [,5] [,6]
#[1,] 0 1 3 5 7 9
#[2,] 1 0 3 5 7 9
#[3,] 1 3 0 5 7 9
#[4,] 1 3 5 0 7 9
#[5,] 1 3 5 7 0 9
#[6,] 1 3 5 7 9 0
数据
x <- c(1,3,5,7,9)