簡體   English   中英

基於另一個矩陣對一個矩陣排序

[英]Sort one matrix based on another matrix

我試圖將一個矩陣的行放在與相同維度的另一個矩陣的行相同的順序中。 但是,如果沒有顯式循環,我無法弄清楚如何做到這一點。 似乎我應該能夠通過子集和應用或Map功能來實現這一點,但我無法弄清楚如何做到這一點。

這是一個玩具示例:

sortMe <- matrix(rnorm(6), ncol=2)
sortBy <- matrix(c(2,1,3, 1,3,2), ncol=2)

sorted <- sortMe 
for (i in 1:ncol(sortMe)) {
  sorted[,i] <- sortMe[,i][sortBy[,i]]
}

使用此方法,生成的sorted矩陣包含sortMe的值, sortMe排序順序與sortBy矩陣相同。 知道如何在沒有循環的情況下做到這一點嗎?

這(使用兩列整數矩陣來索引矩陣的兩個維度)應該可以解決這個問題:

sorted <- sortMe
sorted[] <- sortMe[cbind(as.vector(sortBy), as.vector(col(sortBy)))]

使用lapply會起作用。

matrix(unlist(lapply(1:2, function(n) sortMe[,n][sortBy[,n]])), ncol=2)

但可能有一種更有效的方式......

我打算建議你堅持原來的版本。 我認為你寫的原始循環比其他提供的解決方案更容易閱讀和理解(也可能更容易編寫)。

此外,循環幾乎與其他解決方案一樣快:(在他從帖子中刪除之前,我借用了@Josh O'Brien的計時代碼。)

set.seed(444)
n = 1e7
sortMe <- matrix(rnorm(2 * n), ncol=2)
sortBy <- matrix(c(sample(n), sample(n)), ncol=2)

#---------------------------------------------------------------------------
# @JD Long, original post.
system.time({
    sorted_JD <- sortMe
    for (i in 1:ncol(sortMe)) {
        sorted_JD[, i] <- sortMe[, i][sortBy[, i]]
    } 
})
#   user  system elapsed 
#  1.190   0.165   1.334 

#---------------------------------------------------------------------------
# @Julius (post is now deleted).
system.time({
    sorted_Jul2 <- sortMe
    sorted_Jul2[] <- sortMe[as.vector(sortBy) + 
        rep(0:(ncol(sortMe) - 1) * nrow(sortMe), each = nrow(sortMe))]
})
#   user  system elapsed 
#  1.023   0.218   1.226 

#---------------------------------------------------------------------------
# @Josh O'Brien
system.time({
    sorted_Jos <- sortMe
    sorted_Jos[] <- sortMe[cbind(as.vector(sortBy), as.vector(col(sortBy)))]
})
#   user  system elapsed 
#  1.070   0.217   1.274 

#---------------------------------------------------------------------------
# @Justin
system.time({
    sorted_Just = matrix(unlist(lapply(1:2,
        function(n) sortMe[,n][sortBy[,n]])), ncol=2)
})
#   user  system elapsed 
#  0.989   0.199   1.162 


all.equal(sorted_JD, sorted_Jul2)
# [1] TRUE
all.equal(sorted_JD, sorted_Jos)
# [1] TRUE
all.equal(sorted_JD, sorted_Just)
# [1] TRUE

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM