2012-08-14 8 views
1

Supposons que j'ai une matrice de la forme suivante:Faire une matrice à distance à partir des informations de position en utilisant le langage R

Residue Can.Count SideChain XCoord YCoord ZCoord 
1  MET   1   A 62.935 97.579 30.223 
2  THR   2   A 63.155 95.525 27.079 
3  GLU   3   A 65.289 96.895 24.308 
4  TYR   4   A 64.899 96.220 20.615 
8  LYS   8   A 67.593 96.715 18.023 
9  LEU   9   A 65.898 97.863 14.816 
10  VAL  10   A 67.664 98.557 11.533 

Notez que les numéros 5-6-7 sont ignorés. Ce que je veux faire est de faire une "matrice de distance" entre chaque résidu à chaque autre résidu. Dans ce cas, je veux faire une matrice 7x7 avec l'élément (1,3) étant la distance entre ces positions.

Maintenant, je me rends compte que je n'ai pas besoin de remplir la moitié inférieure, tout ce qui est au-dessus de la diagonale est suffisant. Je vois aussi comment je pourrais le faire en utilisant 2 pour les boucles comme suit:

for(i in 1:7) { 
    for(j in i:7){ 
    mymatrix[i,j] <- calcdistance(xyz1,xyz2) #I have the distance function already coded. 

} 
} 

Je me rends compte que ce sera toujours O (n^2), mais je me demande si je peux tirer parti de la puissance de R pour faire de cette matrice en utilisant une déclaration d'application (ou quelque chose d'encore plus intelligent)? J'ai essayé de le faire mais je n'ai pas réussi. Merci pour votre hep!

Répondre

4

Qu'est-ce que vous cherchez est la dist fonction. Voir ?dist pour plus de détails. Je ne comprends pas ce que vous voulez dire en espérant une matrice de 7 par 7, et ensuite pour l'élément [1,3] de se référer à la distance entre ceux-ci (après avoir noté qu'il n'y a pas 5,6,7) . Je prends cela pour signifier que vous souhaitez faire référence à la Can.Count. Vous pouvez le faire en nommant les lignes et les colonnes et en vous référant à ces noms.

En supposant que vos données est un data.frame appelé residues, ce qui suit travaillera

  • RemarqueCet calcule la distance 2-D en utilisant les coordonnées x-y, c('XCoord','YCoord'). Vous pouvez facilement faire ce 3-D en utilisant c('XCoord','YCoord', 'ZCoord').

dist_matrix <- as.matrix(dist(residues[, c('XCoord','YCoord')], diag = T)) 
# this gives a 7 by 7 matrix 
dist_matrix 
##   1  2   3   4  5  6  7 
## 1 0.000000 2.065748 2.4513613 2.3883419 4.737453 2.976579 4.829071 
## 2 2.065748 0.000000 2.5359132 1.8773814 4.594774 3.604205 5.433609 
## 3 2.451361 2.535913 0.0000000 0.7795672 2.311021 1.143637 2.898770 
## 4 2.388342 1.877381 0.7795672 0.0000000 2.739099 1.922875 3.620331 
## 5 4.737453 4.594774 2.3110206 2.7390986 0.000000 2.047176 1.843368 
## 6 2.976579 3.604205 1.1436367 1.9228755 2.047176 0.000000 1.897470 
## 7 4.829071 5.433609 2.8987703 3.6203306 1.843368 1.897470 0.000000 

# set the dimension names to the Can.Count so we can refer to them 
dimnames(dist_matrix) <- list(residues[['Can.Count']],residues[['Can.Count']]) 

# now you can refer to the distance between Can.Count 1 and Can.Count 8 
dist_matrix['1','8'] 

## [1] 4.737453 

# note that you need to refer to the dimension names as characters, 
# as this is 7 by 7 matrix, so the following will give 
# an (obvious) error message 
dist_matrix[1,8] 

## Error: subscript out of bounds 
+0

Parfait. Juste ce dont j'avais besoin. Je vous remercie! – user1357015

Questions connexes