2012年10月12日金曜日

R: 左側のカラムを優先して全カラムをソートする

PeakAnnotatorを使ってみたら、順番に並んでないから無理と言われた。

こんな結果。

$ PeakAnnotator TSS peaks.bed genes.bed out/tss.txt
Starting...
Reading BED File
Files must be sorted by chromosomes,start position, end position



ということで、左のカラムを優先して全カラムをソートする関数を作った。
行列xに適用すれば並べ替えてくれる。普遍的に使える。列数の限界なし。


sort.left <- function(x,decreasing=FALSE){
n <- ncol(x)
colnum <- n
for (i in 1:n){
x <- x[order(x[,colnum],decreasing=decreasing),]
colnum <- colnum-1
}
return(x)
}


以下、挙動の確認
4列のマトリックスに1から8をランダムに入れた。

> x <- matrix(sample(1:8,4*16,replace=T),ncol=4)

xの中身を確認。

> x
      [,1] [,2] [,3] [,4]
 [1,]    2    5    5    2
 [2,]    3    4    8    2
 [3,]    5    6    8    1
 [4,]    2    6    2    4
 [5,]    2    2    2    4
 [6,]    5    6    4    7
 [7,]    7    1    6    1
 [8,]    7    1    8    7
 [9,]    4    2    8    8
[10,]    8    4    2    6
[11,]    5    2    4    4
[12,]    5    1    4    5
[13,]    8    7    4    7
[14,]    4    5    7    5
[15,]    6    5    3    7
[16,]    6    5    5    6

関数「sort.left()」を適用。
1列目が同じ場合には2列目(1行目と2行目を参照)が、2列目まで同じ場合には3列目(9行目から14行目参照)が、ちゃんと昇順になっているのがわかる。

> sort.left(x)
      [,1] [,2] [,3] [,4]
 [1,]    2    2    2    4
 [2,]    2    5    5    2
 [3,]    2    6    2    4
 [4,]    3    4    8    2
 [5,]    4    2    8    8
 [6,]    4    5    7    5
 [7,]    5    1    4    5
 [8,]    5    2    4    4
 [9,]    5    6    4    7
[10,]    5    6    8    1
[11,]    6    5    3    7
[12,]    6    5    5    6
[13,]    7    1    6    1
[14,]    7    1    8    7
[15,]    8    4    2    6
[16,]    8    7    4    7

引数の「decreasing」はデフォルトでFALSEだが、TRUEを与えると降順になる。

> sort.left(x,T)
      [,1] [,2] [,3] [,4]
 [1,]    8    7    4    7
 [2,]    8    4    2    6
 [3,]    7    1    8    7
 [4,]    7    1    6    1
 [5,]    6    5    5    6
 [6,]    6    5    3    7
 [7,]    5    6    8    1
 [8,]    5    6    4    7
 [9,]    5    2    4    4
[10,]    5    1    4    5
[11,]    4    5    7    5
[12,]    4    2    8    8
[13,]    3    4    8    2
[14,]    2    6    2    4
[15,]    2    5    5    2
[16,]    2    2    2    4


せっかくなので、右側優先の関数もつくった。

sort.right <- function(x,decreasing=FALSE){
n <- ncol(x)
colnum <- n
for (i in 1:n){
x <- x[order(x[,n-colnum+1],decreasing=decreasing),]
colnum <- colnum-1
}
return(x)
}



xに関数「sort.right()」を適用。
最右列から優先的にソートされる。

> sort.right(x)
      [,1] [,2] [,3] [,4]
 [1,]    7    1    6    1
 [2,]    5    6    8    1
 [3,]    2    5    5    2
 [4,]    3    4    8    2
 [5,]    2    2    2    4
 [6,]    2    6    2    4
 [7,]    5    2    4    4
 [8,]    5    1    4    5
 [9,]    4    5    7    5
[10,]    8    4    2    6
[11,]    6    5    5    6
[12,]    6    5    3    7
[13,]    5    6    4    7
[14,]    8    7    4    7
[15,]    7    1    8    7
[16,]    4    2    8    8

もちろん降順もできる。

> sort.right(x,T)
      [,1] [,2] [,3] [,4]
 [1,]    4    2    8    8
 [2,]    7    1    8    7
 [3,]    8    7    4    7
 [4,]    5    6    4    7
 [5,]    6    5    3    7
 [6,]    6    5    5    6
 [7,]    8    4    2    6
 [8,]    4    5    7    5
 [9,]    5    1    4    5
[10,]    5    2    4    4
[11,]    2    6    2    4
[12,]    2    2    2    4
[13,]    3    4    8    2
[14,]    2    5    5    2
[15,]    5    6    8    1
[16,]    7    1    6    1



列が増えても大丈夫。

> y <- matrix(sample(1:4,6*16,replace=T),ncol=6)
> sort.left(y)
      [,1] [,2] [,3] [,4] [,5] [,6]
 [1,]    1    1    1    3    4    3
 [2,]    1    2    3    3    1    4
 [3,]    1    3    1    1    1    2
 [4,]    1    3    3    3    2    3
 [5,]    1    4    1    3    4    1
 [6,]    1    4    3    4    1    3
 [7,]    2    1    3    4    2    3
 [8,]    2    1    4    1    2    4
 [9,]    2    1    4    2    4    4
[10,]    2    2    1    3    4    4
[11,]    2    3    1    4    3    3
[12,]    3    1    4    4    3    1
[13,]    4    3    1    1    4    3
[14,]    4    3    1    3    1    2
[15,]    4    4    3    2    1    3
[16,]    4    4    3    2    2    1

> sort.right(y,T)
      [,1] [,2] [,3] [,4] [,5] [,6]
 [1,]    2    2    1    3    4    4
 [2,]    2    1    4    2    4    4
 [3,]    2    1    4    1    2    4
 [4,]    1    2    3    3    1    4
 [5,]    1    1    1    3    4    3
 [6,]    4    3    1    1    4    3
 [7,]    2    3    1    4    3    3
 [8,]    2    1    3    4    2    3
 [9,]    1    3    3    3    2    3
[10,]    1    4    3    4    1    3
[11,]    4    4    3    2    1    3
[12,]    4    3    1    3    1    2
[13,]    1    3    1    1    1    2
[14,]    1    4    1    3    4    1
[15,]    3    1    4    4    3    1
[16,]    4    4    3    2    2    1




0 件のコメント:

コメントを投稿