Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
248 views
in Technique[技术] by (71.8m points)

r - Normalize between-blocks by the maxima of the block corresponding to the columns

This question is a follow-up on my previous question Instead of normalizing blocks by the local maxima, I would like to normalize between-blocks by the maxima of the block corresponding to the columns.

#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

I would like to normalize between-blocks, i.e.,AB, AC, BA, BC, CA, CB by the maxima of the block corresponding to the columns. E.g., in the case of AB normalize it by the max() in BB, and AC by the max() in 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

In this case, normalizing the between-block AB not by the maxima of this block (i.e. 44), but by the maxima of block BB (i.e. 45).

Any pointers are highly appreciated!

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Let cn be the vector formed by first replacing each element of mat with its column name and then unravelling the resulting matrix column by column. Similarly do the same thing with the rows giving rn.

(cn == rn) * mat is the same as mat except all non-diagonal blocks are zeroed out.

v is a vector whose names are the unique column names and whose values are the maxima of the corresponding diagonal blocks. The construction of v depnds on the fact that the maxima are 0 or more.

replace(mat, TRUE, v[cn]) is the matrix formed by replacing each element of mat with the maximum of the diagonal block in its column and finally we divide mat by that.

Note that if any diagonal block is all zeros then the column will be all NaNs; however, there should not be any problem if any off-diagonal blocks are all zeros.

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

1.4m articles

1.4m replys

5 comments

57.0k users

...