annotate cluster.tools/partition.R @ 8:a58527c632b7 draft

Uploaded
author peter-waltman
date Mon, 11 Mar 2013 16:31:29 -0400
parents 0decf3fd54bc
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
1 #!/usr/bin/env Rscript
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
2
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
3 argspec <- c("partition.R help TBD
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
4 \n\n")
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
5 args <- commandArgs(TRUE)
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
6 if ( length( args ) == 1 && args =="--help") {
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
7 write(argspec, stderr())
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
8 q();
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
9 }
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
10
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
11 lib.load.quiet <- function( package ) {
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
12 package <- as.character(substitute(package))
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
13 suppressPackageStartupMessages( do.call( "library", list( package=package ) ) )
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
14 }
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
15 lib.load.quiet(getopt)
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
16 lib.load.quiet( amap )
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
17 lib.load.quiet( cluster )
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
18
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
19 ## we're going to use the amap Dist function, but they misname their correlation
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
20 ## functions, so re-name them correctly
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
21 amap.distance <- c( "euclidean", "maximum", "manhattan", "canberra", "binary",
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
22 "pearson", "abspearson", "correlation", "abscorrelation", "spearman", "kendall" )
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
23 names( amap.distance ) <- c( "euclidean", "maximum", "manhattan", "canberra", "binary",
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
24 "cosine", "abscosine", "pearson", "abspearson", "spearman", "kendall" )
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
25
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
26 spec <- matrix( c( "data.fname", "d", 1, "character",
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
27 "algorithm", "a", 2, "character",
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
28 "distance.metric", "m", 2, "character", ## must be one supported by R's dist function
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
29 "dist.obj", "D", 2, "logical",
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
30 "direction", "n", 2, "character",
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
31 "num.k", "k", 2, "integer",
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
32 "output.name", "o", 2, "character"
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
33 ),
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
34 nc=4,
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
35 byrow=TRUE
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
36 )
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
37
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
38 opt <- getopt( spec=spec )
8
a58527c632b7 Uploaded
peter-waltman
parents: 0
diff changeset
39 data <- as.matrix( read.delim( opt$data.fname, header=T, row.names=1 , check.names=FALSE ) )
0
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
40
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
41 if ( is.null( opt$distance.metric ) ) { opt$distance.metric <- "euclidean" }
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
42 if ( is.null( opt$algorithm ) ) { opt$algorithm <- "km" }
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
43 if ( is.null( opt$dist.obj ) ) { opt$dist.obj <- FALSE }
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
44 if ( is.null( opt$direction ) ) { opt$direction <- "cols" }
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
45 if ( is.null( opt$output.name ) ) { opt$output.name <- "partition.result" }
8
a58527c632b7 Uploaded
peter-waltman
parents: 0
diff changeset
46 if ( is.null( opt$num.k ) || ( opt$num.k == -1 )) {
a58527c632b7 Uploaded
peter-waltman
parents: 0
diff changeset
47 if ( opt$direction == 'cols' ) {
a58527c632b7 Uploaded
peter-waltman
parents: 0
diff changeset
48 opt$num.k <- 5
a58527c632b7 Uploaded
peter-waltman
parents: 0
diff changeset
49 } else if ( opt$direction == 'rows' ) {
a58527c632b7 Uploaded
peter-waltman
parents: 0
diff changeset
50 opt$num.k <- nrow( data ) / 30 ## we use an estimated average size of gene clusters to be 30
a58527c632b7 Uploaded
peter-waltman
parents: 0
diff changeset
51 if ( opt$num.k > 1000 ) {
a58527c632b7 Uploaded
peter-waltman
parents: 0
diff changeset
52 opt$num.k <- ( opt$num.k %/% 10 ) * 10
a58527c632b7 Uploaded
peter-waltman
parents: 0
diff changeset
53 } else {
a58527c632b7 Uploaded
peter-waltman
parents: 0
diff changeset
54 opt$num.k <- ( opt$num.k %/% 5 ) * 5
a58527c632b7 Uploaded
peter-waltman
parents: 0
diff changeset
55 }
a58527c632b7 Uploaded
peter-waltman
parents: 0
diff changeset
56 }
a58527c632b7 Uploaded
peter-waltman
parents: 0
diff changeset
57 }
0
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
58
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
59
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
60 if ( opt$direction == "cols" ) {
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
61 ## need to transpose b/c both kmeans & pam cluster the rows
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
62 ## this shouldn't have an effect upon a distance matrix
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
63 data <- t( data )
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
64 }
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
65 if ( opt$num.k > nrow( data ) ) {
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
66 err.msg <- paste( "K specified is greater than the number of elements (", opt$direction, ") in data matrix to be clustereed\n", sep="" )
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
67 stop( err.msg )
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
68 }
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
69
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
70 mat.2.b.clustered <- data
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
71 if ( opt$dist.obj ) {
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
72 ## To be updated
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
73
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
74 mat.2.b.clustered <- as.dist( data )
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
75
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
76 if ( opt$algorithm=="km" ) {
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
77 ##clusterAlg is kmeans
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
78 if (verbose) warning()
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
79 }
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
80 } else {
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
81 ## this is a data matrix -- we always generate a dist.mat object (b/c we need it
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
82 ## in case this result is used with a heatmap
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
83
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
84 ## PAM clustering
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
85 if ( opt$algorithm != "km" ) {
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
86
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
87 if ( ! opt$distance.metric %in% names( amap.distance ) ) stop("unsupported distance.")
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
88 mat.2.b.clustered <- Dist( data, method=as.character( amap.distance[ opt$distance.metric ] ) )
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
89 attr( mat.2.b.clustered, "method" ) <- opt$distance.metric
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
90
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
91 } else {
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
92 mat.2.b.clustered <- data
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
93 }
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
94 }
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
95
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
96 ## now run the clustering
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
97 partcl.res <- cl <- NA
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
98 if ( opt$algorithm=="pam" ) {
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
99 partcl.res <- pam( x=mat.2.b.clustered,
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
100 k=opt$num.k,
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
101 metric=( ifelse( inherits(data, "dist" ),
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
102 attr( data, "method" ), ## this is ok if data is a dist object (b/c pam will ignore it)
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
103 opt$distance.metric) ) ) ##,
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
104 ##cluster.only=TRUE )
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
105 cl <- partcl.res$clustering
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
106
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
107 if ( is.character( partcl.res$medoids ) ) {
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
108 medoids <- data[ partcl.res$medoids, ]
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
109 } else {
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
110 ##partcl.res$medoids is a matrix -- we shouldn't get this (only if mat.2.b.clustered is a data matrix)
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
111 medoids <- partcl.res$medoids
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
112 }
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
113 med.names <- rownames( medoids )
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
114 med.hc <- hclust( as.dist( as.matrix( mat.2.b.clustered )[ med.names, med.names ] ) )
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
115 med.cls <- as.numeric( cl[ med.names[ med.hc$order ] ] )
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
116
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
117 cl.list <- lapply( med.cls, function(i) names( cl[ cl %in% i ] ) )
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
118 names( cl.list ) <- med.cls
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
119
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
120 cl.list <- lapply( cl.list,
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
121 function( elts ) {
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
122 if ( length( elts ) == 1 ) {
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
123 retval <- 1
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
124 names( retval ) <- elts
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
125 } else {
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
126 subdist <- as.dist( as.matrix( mat.2.b.clustered )[ elts, elts ] )
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
127 sub.hc <- hclust( subdist )
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
128 retval <- sub.hc$order
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
129 names( retval ) <- sub.hc$labels
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
130 retval <- sort( retval )
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
131 }
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
132 return( retval )
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
133 }
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
134 )
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
135
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
136 fnl.ord <- as.character( unlist( lapply( cl.list, names ) ) )
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
137 cl <- cl[ fnl.ord ]
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
138 } else {
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
139 partcl.res <- kmeans( x=mat.2.b.clustered,
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
140 centers=opt$num.k )
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
141 cl <- partcl.res$cluster
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
142 centroids <- partcl.res$centers
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
143 cent.hc <- hclust( Dist( centroids, method=as.character( amap.distance[ opt$distance.metric ] ) ) )
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
144 cent.cls <- as.numeric( cent.hc$labels[ cent.hc$order ] )
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
145
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
146 cl.list <- lapply( cent.cls, function(i) names( cl[ cl %in% i ] ) )
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
147 names( cl.list ) <- cent.cls
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
148
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
149 cl.list <- lapply( cl.list,
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
150 function( elts ) {
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
151 if ( length( elts ) == 1 ) {
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
152 retval <- 1
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
153 names( retval ) <- elts
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
154 } else {
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
155 if ( all( elts %in% colnames( mat.2.b.clustered ) ) ) {
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
156 submat <- mat.2.b.clustered[ elts, elts ]
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
157 } else {
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
158 submat <- mat.2.b.clustered[ elts, ]
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
159 }
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
160 subdist <- Dist( submat, method=as.character( amap.distance[ opt$distance.metric ] ) )
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
161 sub.hc <- hclust( subdist )
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
162 retval <- sub.hc$order
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
163 names( retval ) <- sub.hc$labels
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
164 retval <- sort( retval )
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
165 }
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
166 return( retval )
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
167 }
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
168 )
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
169
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
170 fnl.ord <- as.character( unlist( lapply( cl.list, names ) ) )
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
171 cl <- cl[ fnl.ord ]
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
172 }
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
173
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
174 if ( opt$direction == "cols" ) {
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
175 ## need to transpose back
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
176 data <- t( data )
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
177 }
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
178 save( file=opt$output.name, partcl.res, cl, data )
0decf3fd54bc Uploaded
peter-waltman
parents:
diff changeset
179