R 如何用值向量填充索引矩阵
我有一个矩阵(m.idx),其中包含我要索引的向量的位置元素R 如何用值向量填充索引矩阵,r,matrix,indexing,R,Matrix,Indexing,我有一个矩阵(m.idx),其中包含我要索引的向量的位置元素 > m.idx [,1] [,2] [,3] [,4] [,5] [1,] 1 2 3 4 5 [2,] 3 4 5 6 7 [3,] 5 6 7 8 9 假设x是我的向量 x <- c(9,3,2,5,3,2,4,8,9) 我可以用下面的方法笨拙地完成它 > m.pop <- t(matrix(t(matr
> m.idx
[,1] [,2] [,3] [,4] [,5]
[1,] 1 2 3 4 5
[2,] 3 4 5 6 7
[3,] 5 6 7 8 9
假设x是我的向量
x <- c(9,3,2,5,3,2,4,8,9)
我可以用下面的方法笨拙地完成它
> m.pop <- t(matrix(t(matrix(x[c(t(m.idx))])),ncol(m.idx),nrow(m.idx)))
> m.pop
[,1] [,2] [,3] [,4] [,5]
[1,] 9 3 2 5 3
[2,] 2 5 3 2 4
[3,] 3 2 4 8 9
>m.pop m.pop
[,1] [,2] [,3] [,4] [,5]
[1,] 9 3 2 5 3
[2,] 2 5 3 2 4
[3,] 3 2 4 8 9
但似乎有一种更简单的方法来索引这些值。
实现这一点的最佳方法是什么(对于大型集合来说也是最快/最有效的方法?也许您可以在匹配向量/矩阵后使用
dim
:
matrix(x[m.idx],ncol=5)
[,1] [,2] [,3] [,4] [,5]
[1,] 9 3 2 5 3
[2,] 2 5 3 2 4
[3,] 3 2 4 8 9
`dim<-`(x[m.idx], dim(m.idx))
# [,1] [,2] [,3] [,4] [,5]
# [1,] 9 3 2 5 3
# [2,] 2 5 3 2 4
# [3,] 3 2 4 8 9
而且,由于这应该在原始维度的相同维度上返回,因此您只需重新为其指定相同的dim
为了好玩,有些时间安排:
fun1 <- function() `dim<-`(x[m.idx], dim(m.idx))
fun2 <- function() { m.idx[] <- x[m.idx]; m.idx }
fun3 <- function() matrix(x[m.idx], ncol = ncol(m.idx))
fun4 <- function() t(matrix(t(matrix(x[c(t(m.idx))])),ncol(m.idx),nrow(m.idx)))
m.idx <- matrix(c(1, 2, 3, 4, 5,
3, 4, 5, 6, 7,
5, 6, 7, 8, 9),
nrow = 3, byrow = TRUE)
x <- c(9, 3, 2, 5, 3, 2, 4, 8, 9)
set.seed(1)
nrow = 10000 ## Adjust nrow and ncol to test different sizes
ncol = 1000
m.idx <- matrix(sample(unique(m.idx), nrow*ncol, TRUE), ncol = ncol)
library(microbenchmark)
microbenchmark(fun1(), fun2(), fun3(), fun4(), times = 10)
# Unit: milliseconds
# expr min lq median uq max neval
# fun1() 388.7123 403.3614 419.5792 475.7645 553.3420 10
# fun2() 800.5524 838.2398 872.8189 912.1007 978.1500 10
# fun3() 694.1511 720.5165 737.9900 799.5069 876.2552 10
# fun4() 1941.1999 2022.6578 2095.1537 2175.4864 2341.3900 10
fun1怎么样:
m.idx[] <- x[m.idx]
m.idx
# [,1] [,2] [,3] [,4] [,5]
# [1,] 9 3 2 5 3
# [2,] 2 5 3 2 4
# [3,] 3 2 4 8 9
添加:
另一种方法是使用结构
,速度也相当快:
structure(x[m.idx], .Dim = dim(m.idx))
# [,1] [,2] [,3] [,4] [,5]
# [1,] 9 3 2 5 3
# [2,] 2 5 3 2 4
# [3,] 3 2 4 8 9
当应用于Ananda Mahto答案中的大型m.idx
矩阵时,我机器上的计时为
fun5 <- function() structure(x[m.idx], .Dim = dim(m.idx))
microbenchmark(fun1(), fun2(), fun3(), fun4(), fun5(), times = 10)
# Unit: milliseconds
# expr min lq median uq max neval
# fun1() 303.3473 307.2064 309.2275 352.5076 353.6911 10
# fun2() 548.0928 555.3363 587.6144 593.4492 596.5611 10
# fun3() 480.6181 487.5807 507.5960 529.9696 533.0403 10
# fun4() 1222.6718 1231.3384 1259.8395 1269.6629 1292.2309 10
# fun5() 401.8450 403.7216 432.7162 455.4638 487.1755 10
identical(fun1(), fun5())
# [1] TRUE
fun5可能比其他答案更有效,但任何使用dim@BenBolker,我认为理查德的答案是最恰当的,但你的答案确实更有效率(如果这真的有区别的话……我猜这里给出的三个答案中的任何一个都足够好,这一步不会成为任何计算中的瓶颈)(+1)快5毫秒。@RichardScriven,我同意这有点荒谬,但测试的尺寸不同,它的速度几乎是原来的2倍,这可能会有所不同。这比我的`DIM要好。你的矩阵有多大?我已经在我的答案中添加了一些基准点。我现在看到的可能是5e3行乘以100列。但随着我的扩大,你的答案可能会有用——tks。用于提供基准。正如我所预料的,我的笨拙方法位于底部。这实际上是一个非常好的答案,因为它不会覆盖原始的m.idx
矩阵。
m.pop <- m.idx
m.pop[] <- x[m.pop]
structure(x[m.idx], .Dim = dim(m.idx))
# [,1] [,2] [,3] [,4] [,5]
# [1,] 9 3 2 5 3
# [2,] 2 5 3 2 4
# [3,] 3 2 4 8 9
fun5 <- function() structure(x[m.idx], .Dim = dim(m.idx))
microbenchmark(fun1(), fun2(), fun3(), fun4(), fun5(), times = 10)
# Unit: milliseconds
# expr min lq median uq max neval
# fun1() 303.3473 307.2064 309.2275 352.5076 353.6911 10
# fun2() 548.0928 555.3363 587.6144 593.4492 596.5611 10
# fun3() 480.6181 487.5807 507.5960 529.9696 533.0403 10
# fun4() 1222.6718 1231.3384 1259.8395 1269.6629 1292.2309 10
# fun5() 401.8450 403.7216 432.7162 455.4638 487.1755 10
identical(fun1(), fun5())
# [1] TRUE