2017-05-24 2 views
0

Cette question fait suite à mes previous question Au lieu de normaliser les blocs par les maxima locaux, je voudrais normaliser entre-blocs par les maxima de la bloc correspondant aux colonnes.Normaliser entre-blocs par les maxima du bloc correspondant aux colonnes

#dummy data 
mat <- matrix(round(runif(90, 0, 50),),9,9) 
rownames(mat) <- rep(LETTERS[1:3],3) 
colnames(mat) <- rep(LETTERS[1:3],3) 

#Normalizes within and between blocks by the maxima of the focal block 
ans <- mat/ave(mat, rownames(mat)[row(mat)], colnames(mat)[col(mat)], FUN = max) 

#Number of blocks 
sum(ans == 1) 
#[1] 9 

je voudrais normaliser entre-blocs, à savoir, AB, AC, BA, BC, CA, CB par les maxima du bloc correspondant aux colonnes. Par exemple, dans le cas de AB normalise par le max() dans BB et AC par le max() dans CC etc.

> mat[rownames(mat)=="A",colnames(mat)=="B"] 
    B B B 
A 26 26 14 
A 12 11 18 
A 44 44 29 

> mat[rownames(mat)=="B",colnames(mat)=="B"] 
    B B B 
B 9 23 20 
B 28 45 28 
B 14 12 45 

Dans ce cas, normalisant le bloc entre AB non par les maxima de ce bloc (c. 44), mais par les maxima du bloc BB (soit 45).

Les pointeurs sont très appréciés!

Répondre

1

Soit cn être le vecteur formé en remplaçant d'abord chaque élément de mat par son nom de colonne, puis en démêlant la matrice résultante colonne par colonne. De même faire la même chose avec les lignes donnant rn.

(cn == rn) * mat est identique à mat sauf que tous les blocs non diagonaux sont remis à zéro.

v est un vecteur dont les noms sont les noms de colonnes uniques et dont les valeurs sont les maxima des blocs diagonaux correspondants. La construction de v dépend du fait que les maxima sont 0 ou plus.

replace(mat, TRUE, v[cn]) est la matrice formée en remplaçant chaque élément de mat par le maximum du bloc diagonal dans sa colonne et finalement nous divisons mat par cela.

Notez que si un bloc diagonal est tous des zéros alors la colonne sera tout NaNs; cependant, il ne devrait pas y avoir de problème si des blocs hors diagonale sont tous des zéros.

cn <- colnames(mat)[col(mat)] 
rn <- rownames(mat)[row(mat)] 
v <- tapply((cn == rn) * mat, cn, max) 
mat/replace(mat, TRUE, v[cn]) 
+0

Magnifique! Merci beaucoup! –