是否有一种优雅的方式将同一行的多个副本添加到矩阵?下面是一个解决问题的例子。但是,这个例子很慢而且不优雅。
m <- matrix(c(1,2,3,4,5,6,7,8,9),ncol=3)
m0 <- m
r <- c(10,20,30)
#Correct example
for (i in c(1,2))
m[i,] <- r
print(m)
# [,1] [,2] [,3]
#[1,] 10 20 30
#[2,] 10 20 30
#[3,] 3 6 9
#Attempts below look straightforward but lead to incorrect results
m <- m0
m[1:2,] <- apply(m[1:2,],1,function(x)r)
print(m)
# [,1] [,2] [,3]
#[1,] 10 30 20
#[2,] 20 10 30
#[3,] 3 6 9
m <- m0
m[1:2,] <- r
print(m)
# [,1] [,2] [,3]
#[1,] 10 30 20
#[2,] 20 10 30
#[3,] 3 6 9
答案 0 :(得分:1)
您可以从向量r
构建第二个矩阵,并将其插入m
,如下所示:
m[1:2, ] <- matrix(r, ncol = 3, nrow = 2, byrow = TRUE)
m
# [,1] [,2] [,3]
#[1,] 10 20 30
#[2,] 10 20 30
#[3,] 3 6 9
另一个选择是t
转机m
,再次插入r
和t
:
m <- t(m)
m[, 1:2] <- r
m <- t(m)
m
# [,1] [,2] [,3]
#[1,] 10 20 30
#[2,] 10 20 30
#[3,] 3 6 9
但我没有对性能进行基准测试。
答案 1 :(得分:0)
据我所知, for-loop 最快解决问题的方法。更快的解决方案是在R中选择不同的数据结构,其中记录在列而不是在行中。
以下是@ docendo-discimus和我的解决方案的速度测量以及记录在列而不是行中的其他示例。在这种情况下,直接分配可以正常工作。
m <- matrix(c(1,2,3,4,5,6,7,8,9),ncol=3)
m0 <- m
r <- c(10,20,30)
#For loop
print(
system.time(
for (k in 1:100000){
for (i in c(1,2))
m[i,] <- r
}))
print(m)
# User System verstrichen
# 0.524 0.011 0.552
# [,1] [,2] [,3]
# [1,] 10 20 30
# [2,] 10 20 30
# [3,] 3 6 9
#@docendo-discimus: Create new matrix
m <- m0
print(
system.time(
for (k in 1:100000){
m[1:2, ] <- matrix(r, ncol = 3, nrow = 2, byrow = TRUE)})
)
print(m)
# User System verstrichen
# 0.818 0.011 0.833
# [,1] [,2] [,3]
# [1,] 10 20 30
# [2,] 10 20 30
# [3,] 3 6 9
#@docendo-discimus Transpose, modify columns, transpose again
m <- m0
print(
system.time(
for (k in 1:100000){
m <- t(m)
m[, 1:2] <- r
m <- t(m)
m}))
print(m)
# User System verstrichen
# 1.870 0.010 1.895
# [,1] [,2] [,3]
# [1,] 10 20 30
# [2,] 10 20 30
# [3,] 3 6 9
#Usage of different data structure with a transposed matrix
m <- matrix(c(1,2,3,4,5,6,7,8,9),nrow=3)
m0 <- m
print(m)
# [,1] [,2] [,3]
# [1,] 1 4 7
# [2,] 2 5 8
# [3,] 3 6 9
print(
system.time(
for (k in 1:100000){
m[,1:2] <- r
}))
print(m)
# User System verstrichen
# 0.241 0.013 0.255
# [,1] [,2] [,3]
# [1,] 10 10 7
# [2,] 20 20 8
# [3,] 30 30 9