2013-12-08 49 views
1

我有一個R例程與for循環一起工作,它似乎是一個明顯的候選人轉換爲「應用」,但我無法弄清楚如何編寫適當的功能,因爲它需要來自兩個矩陣的行/列,並行處理相同的索引。R應用函數與矩陣和選擇器

該函數需要兩個相同大小的矩陣。第二個是第一個的舍入和截斷版本。它根據「邊距」的值 ,按行或逐列返回圓形矩陣和未矩形矩陣之間最小和最大差異的自定義版本 。計算最小/最大值時忽略四捨五入的值被截斷的單元格,因此我計算每個函數的選擇器給出適當的值。

diff.minmax <- function(unrounded, rounded, margin, min.threshold=0, max.threshold=100, rounding=0) { 
    diff <- rounded - unrounded 
    min.sel <- rounded < max.threshold | (unrounded >= max.threshold & round(unrounded,rounding) < max.threshold) 
    max.sel <- rounded > min.threshold | (unrounded <= min.threshold & round(unrounded,rounding) > min.threshold) 
    len <- dim(diff)[margin] 
    mm <- matrix(0, nrow=len, ncol=2) 
    for (i in 1:len) { 
    if (margin == 1) { 
     # min/max values by row 
     mm[i,1] <- min(diff[i,min.sel[i,]]) 
     mm[i,2] <- max(diff[i,max.sel[i,]]) 
    } 
    else { 
     # min/max values by column 
     mm[i,1] <- min(diff[min.sel[,i],i]) 
     mm[i,2] <- max(diff[max.sel[,i],i]) 
    } 
    } 
    return(mm) 
} 

雖然這種日常工作,並且它的時候我用的矩陣的大小合理的量來執行,我想知道是否可以作出與「應用」更有效。我特別想避免必須爲索引變量中的行/列顯式編寫代碼。能夠將此功能擴展到任意數量的維度是很好的,正如「apply」一樣。

一些測試數據:

U <- matrix(c(-0.825, -0.031, 1.398, 3.148, 4.604, 
       0.662, 1.457, 2.886, 4.636, 6.091, 
       2.487, 3.281, 4.710, 6.460, 7.916, 
       4.513, 5.308, 6.737, 8.487, 9.942, 
       6.758, 7.553, 8.982, 10.732, 12.187), nrow=5) 

R <- matrix(c(0, 0, 1, 3, 5, 1, 1, 3, 5, 6, 2, 3, 5, 6, 8, 
       5, 5, 7, 8, 10, 7, 8, 9, 11, 12), nrow=5) 

diff.minmax(U, R, 1) 

     [,1] [,2] 
[1,] -0.487 0.487 
[2,] -0.457 0.447 
[3,] -0.398 0.290 
[4,] -0.487 0.364 
[5,] -0.187 0.396 

diff.minmax(U, R, 2) 
     [,1] [,2] 
[1,] -0.398 0.396 
[2,] -0.457 0.364 
[3,] -0.487 0.290 
[4,] -0.487 0.487 
[5,] -0.187 0.447 

回答

3

如果不是在頂部邏輯的東西,我會說,

apply(diff, margin, range) 

但是這會做你想要的設置的那些你不想要Inf:

function(unrounded, rounded, margin, min.threshold=0, max.threshold=100, rounding=0) { 
    diff <- rounded - unrounded 
    min.sel <- rounded < max.threshold | (unrounded >= max.threshold & round(unrounded,rounding) < max.threshold) 
    max.sel <- rounded > min.threshold | (unrounded <= min.threshold & round(unrounded,rounding) > min.threshold) 
    len <- dim(diff)[margin] 
    mm <- matrix(0, nrow=len, ncol=2) 

    mm[,1] <- apply(diff + ifelse(min.sel, 0, Inf), margin, min) 
    mm[,2] <- apply(diff + ifelse(max.sel, 0, -Inf), margin, max) 

    return(mm) 
} 
+0

在更大的數據集上試用這個,你的版本的性能提高將近7倍。非常感謝。 –