annotate cluster.tools/partition.R @ 2:b442996b66ae draft

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