2014-02-15 31 views
6

我有一個名爲「mat」的矩陣和一個名爲「center」的較小矩陣。如何使用一些應用函數來解決什麼需要兩個for循環在R

temp = c(1.8421,5.6586,6.3526,2.904,3.232,4.6076,4.8,3.2909,4.6122,4.9399) 
mat = matrix(temp, ncol=2) 
     [,1] [,2] 
[1,] 1.8421 4.6076 
[2,] 5.6586 4.8000 
[3,] 6.3526 3.2909 
[4,] 2.9040 4.6122 
[5,] 3.2320 4.9399 

center = matrix(c(3, 6, 3, 2), ncol=2) 

    [,1] [,2] 
[1,] 3 3 
[2,] 6 2 

我需要計算每行墊與中心的每一行之間的距離。例如,墊[1]和中心的距離[1,]可以被計算爲

diff = mat[1,]-center[1,] 
t(diff)%*%diff 
     [,1] 
[1,] 3.92511 

同樣,我可以找到墊[1]和中心的距離[2,1]

diff = mat[1,]-center[2,] 
t(diff)%*%diff 
     [,1] 
[1,] 24.08771 

重複此過程,墊的每一行,我將結束與

  [,1]  [,2] 
[1,] 3.925110 24.087710 
[2,] 10.308154 7.956554 
[3,] 11.324550 1.790750 
[4,] 2.608405 16.408805 
[5,] 3.817036 16.304836 

我知道如何用for循環實現它。我真的希望有人能告訴我如何用某種apply()函數來做到這一點,也許我猜mapply()。

感謝

回答

1

這將解決這個問題

t(apply(mat,1,function(row){ 
    d1<-sum((row-center[1,])^2) 
    d2<-sum((row-center[2,])^2) 
    return(c(d1,d2)) 
})) 

結果:

  [,1]  [,2] 
[1,] 3.925110 24.087710 
[2,] 10.308154 7.956554 
[3,] 11.324550 1.790750 
[4,] 2.608405 16.408805 
[5,] 3.817036 16.304836 
+1

這個答案不正確。你之前有一個合適的。你需要將矩陣轉置爲數學回收才能正常工作,然後採用colSums當然。 – John

4
apply(center, 1, function(x) colSums((x - t(mat))^2)) 
#   [,1]  [,2] 
# [1,] 3.925110 24.087710 
# [2,] 10.308154 7.956554 
# [3,] 11.324550 1.790750 
# [4,] 2.608405 16.408805 
# [5,] 3.817036 16.304836 
+0

請注意,這與我的非常相似,它也只是在中心而不是墊子上循環。這大大加速了循環過程中的事情。 – John

+0

@John,關於從循環中移除不變計算的好處。 – BrodieG

4

如果你想apply的代碼,一兩件事表現,但它仍然是循環的,只是不同的語法。這可以在沒有任何循環的情況下完成,或者使用跨越center而非mat的非常小的循環來完成。我只是首先進行轉置,因爲養成應用語句儘可能多的習慣是明智的。 (BrodieG的答案在功能上幾乎完全相同。)這些工作正常,因爲R會自動回收矩陣中較小的矢量,並且比applyfor快得多。

tm <- t(mat) 
apply(center, 1, function(m){ 
    colSums((tm - m)^2) }) 
+0

+1,以明智地評論「應用」優化。 – BrodieG

1

你可以使用outer以及

d <- function(i, j) sum((mat[i, ] - center[j, ])^2) 
outer(1:nrow(mat), 1:nrow(center), Vectorize(d)) 
2

使用dist然後提取相關的子矩陣:

ix <- 1:nrow(mat) 
as.matrix(dist(rbind(mat, center))^2)[ix, -ix] 

      6   7 
# 1 3.925110 24.087710 
# 2 10.308154 7.956554 
# 3 11.324550 1.790750 
# 4 2.608405 16.408805 
# 5 3.817036 16.304836 

修訂:略微簡化。

相關問題