2012-06-19 23 views
5

Sto provando a inserire le righe di una matrice nello stesso ordine delle righe di un'altra matrice della stessa dimensione. Tuttavia non riesco a capire come farlo senza un ciclo esplicito. Sembra che dovrei essere in grado di farlo con subsetting e una funzione apply o Map, ma non riesco a capire come farlo.Ordinare una matrice basata su un'altra matrice

Ecco un esempio giocattolo:

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]] 
} 

Usando questo metodo, il sorted matrice risultante contiene i valori da sortMe filtrate nello stesso ordine come matrice sortBy. Qualche idea su come farei questo senza il ciclo?

risposta

8

Questa (utilizzando una matrice numero intero a due colonne per indicizzare due dimensioni della matrice) dovrebbe fare il trucco:

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

Utilizzare lapply funzionerebbe.

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

Ma v'è probabilmente un modo più efficiente ...

3

Ti suggerisco di incollarti la versione originale. Direi che il ciclo originale che hai scritto è in qualche modo più facile da leggere e comprendere (probabilmente anche più facile da scrivere) rispetto alle altre soluzioni offerte.

Inoltre, il ciclo è quasi veloce come le altre soluzioni: (ho preso in prestito codice di temporizzazione di @Josh O'Brien prima rimosso dal suo posto.)

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 
+0

Grazie per profilatura. È davvero interessante! –

Problemi correlati