2012-06-19 23 views
5

Bir matrisin satırlarını aynı boyuttaki başka bir matrisin satırlarıyla aynı sıraya koymaya çalışıyorum. Bununla birlikte, bunu açık bir döngü olmadan nasıl yapacağımı anlayamıyorum. Görünüşe göre bunu bir alt-ayarlama ve bir uygulama ya da Harita işleviyle yapabilmem gerekiyor, ama nasıl yapılacağını anlayamıyorum. Elde edilen sorted matris sortBy matris ile aynı sırada kriteri sortMe değerleri içerir, bu yöntem kullanılarakBaşka bir matrise dayalı bir matrisi sırala

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

:

Burada bir oyuncak bir örnektir. Bunu döngü olmadan nasıl yapardım?

cevap

8

Bu hile yapmak gerekir (matrisin iki boyutlu endeksine iki sütunlu tamsayı matrisi kullanılarak):

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

lapply'u kullanır.

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

Ancak daha verimli bir şekilde muhtemelen yoktur ...

3

Size orijinal versiyonunuzu yapıştırmanızı önereceğim. Yazdığınız orijinal döngünün, sunulan diğer çözümlerden daha kolay okunması ve anlaşılması (muhtemelen yazması daha kolay) olduğunu ileri süreceğim.

Ayrıca, döngü başka çözümler gibi neredeyse hızlıdır: (görevinden kaldırmasıyla önce @Josh O'Brien'ın zamanlama kodunu ödünç aldı.) Profilleme için

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

teşekkürler. Bu gerçekten ilginç! –

İlgili konular