File Coverage

blib/lib/Microarray/ExprSet.pm
Criterion Covered Total %
statement 112 121 92.5
branch 29 38 76.3
condition 6 11 54.5
subroutine 16 16 100.0
pod 13 13 100.0
total 176 199 88.4


line stmt bran cond sub pod time code
1             package Microarray::ExprSet;
2              
3             # Simple description of microarray data
4             # contains three elements
5             # data matrix
6             # feature (gene) names array
7             # sample names array
8              
9 4     4   133995 use List::Vectorize;
  4         88709  
  4         1738  
10 4     4   37 use Carp;
  4         632  
  4         276  
11 4     4   35 use strict;
  4         8  
  4         6443  
12              
13             our $VERSION = "0.11";
14              
15             1;
16              
17              
18             sub new {
19              
20 1     1 1 12 my $invocant = shift;
21 1   33     7 my $class = ref($invocant) || $invocant;
22 1         7 my $self = { feature => undef,
23             phenotype => undef,
24             matrix => undef,
25             error => undef,};
26 1         3 bless($self, $class);
27 1         3 return $self;
28            
29             }
30              
31              
32             # probe name
33             sub feature {
34              
35 26     26 1 364 my $self = shift;
36            
37 26         116 return $self->{feature};
38              
39             }
40              
41             sub set_feature {
42            
43 7     7 1 3514 my $self = shift;
44            
45 7         23 List::Vectorize::check_prototype(@_, '\@');
46            
47 7         265 my $feature = shift;
48            
49 7         15 $self->{feature} = $feature;
50            
51 7         22 return $self;
52              
53             }
54              
55             # sample name
56             sub phenotype {
57            
58 17     17 1 40 my $self = shift;
59            
60 17         60 return $self->{phenotype};
61              
62             }
63              
64             sub set_phenotype {
65            
66 3     3 1 4 my $self = shift;
67            
68 3         9 List::Vectorize::check_prototype(@_, '\@');
69            
70 3         75 my $phenotype = shift;
71            
72 3         6 $self->{phenotype} = $phenotype;
73            
74 3         13 return $self;
75            
76             }
77              
78             sub set_matrix {
79              
80 6     6 1 10 my $self = shift;
81            
82 6         16 List::Vectorize::check_prototype(@_, '\@');
83            
84 6         139 my $matrix = shift;
85            
86             # check whether it is a valid matrix
87 6         23 my ($nr, $nc) = dim($matrix);
88 6 50 33     4506 if(!defined($nr) or !defined($nc)) {
89 0         0 croak "ERROR: Not a valid matrix";
90             }
91            
92 6         12 $self->{matrix} = $matrix;
93            
94 6         14 return $self;
95            
96             }
97              
98             sub matrix {
99            
100 29     29 1 383 my $self = shift;
101            
102 29         109 return $self->{matrix};
103              
104             }
105              
106             sub is_valid {
107            
108 10     10 1 67 my $self = shift;
109 10         17 $self->{error} = undef;
110            
111 10 100       20 if(defined($self->matrix)) {
112            
113 9         17 my ($nr, $nc) = dim($self->matrix);
114            
115 9 100 66     6816 if(!defined($nr) or !defined($nc)) {
116 1         3 $self->{error} = "Not a matrix";
117 1         4 return 0;
118             }
119            
120 8 100       23 if(defined($self->feature)) {
121 6 100       20 if(len($self->feature) != $nr) {
122 1         12 $self->{error} = "Length of feature names is not identical to the number of matrix rows";
123 1         5 return 0;
124             }
125             }
126            
127 7 100       61 if(defined($self->phenotype)) {
128 6 100       15 if(len($self->phenotype) != $nc) {
129 1         77 $self->{error} = "Length of phenotype names is not identical to the number of matrix columns";
130 1         5 return 0;
131             }
132             }
133             }
134             else {
135 1         3 $self->{error} = "Expression matrix is not defined";
136 1         7 return 0;
137             }
138            
139 6         69 return 1;
140             }
141              
142              
143             sub remove_empty_features {
144              
145 1     1 1 2 my $self = shift;
146            
147 1         4 my $old_feature = $self->feature;
148 1         4 my $old_matrix = $self->matrix;
149            
150 1 50       4 if(is_empty($old_feature)) {
    50          
151 0         0 carp "WARN: Feature names are empty. ";
152             }
153             elsif(! $self->is_valid) {
154 0         0 croak $self->{error};
155             }
156            
157 1         2 my $new_feature;
158             my $new_matrix;
159            
160 1         5 for(my $i = 0; $i < len($old_feature); $i ++) {
161            
162 6 100       77 if($old_feature->[$i] !~ /^\s*$/) {
163 5         10 push(@$new_feature, $old_feature->[$i]);
164 5         17 push(@$new_matrix, $old_matrix->[$i]);
165             }
166             }
167            
168 1         13 $self->set_feature($new_feature);
169 1         3 $self->set_matrix($new_matrix);
170 1         3 undef($old_feature);
171 1         2 undef($old_matrix);
172              
173 1         3 return $self;
174             }
175              
176             sub n_feature {
177            
178 1     1 1 3 my $self = shift;
179            
180 1         4 return len($self->feature);
181              
182             }
183              
184             sub n_phenotype {
185            
186 1     1 1 473 my $self = shift;
187            
188 1         5 return len($self->phenotype);
189              
190             }
191              
192             # using mean or median
193             sub unique_features {
194            
195 2     2 1 5 my $self = shift;
196 2   100     11 my $method = shift || "mean";
197            
198 2         3 my $fun;
199 2 100       11 if($method eq "mean") {
    50          
200 1         3 $fun = \&mean;
201             }
202             elsif($method eq "median") {
203 1         3 $fun = \&median;
204             }
205             else {
206 0         0 $fun = \&mean;
207             }
208            
209 2         4 my $fh;
210 2         6 my $feature = $self->feature;
211            
212 2 50       7 if(is_empty($feature)) {
    50          
213 0         0 carp "WARN: Feature names are empty. ";
214             }
215             elsif(! $self->is_valid) {
216 0         0 croak $self->{error};
217             }
218            
219 2         6 for(my $i = 0; $i < len($feature); $i ++) {
220 9 100       90 if($fh->{$feature->[$i]}) {
221 3         3 push(@{$fh->{$feature->[$i]}}, $i);
  3         11  
222             }
223             else {
224 6         26 $fh->{$feature->[$i]}->[0] = $i;
225             }
226             }
227              
228 2         19 my $new_feature;
229             my $new_matrix;
230 2         5 my $matrix = $self->matrix;
231 2         6 foreach my $f (keys %$fh) {
232            
233 6         11 my $index = $fh->{$f};
234 6         7 push(@$new_feature, $f);
235            
236 6 100       13 if(len($index) == 1) {
237 4         44 push(@$new_matrix, $matrix->[$index->[0]]);
238             }
239             else {
240 2         19 my $new_array;
241 2         7 for(my $i = 0; $i < len($matrix->[0]); $i ++) {
242 12         1044 my $tmp_array;
243 12         30 for(my $j = 0; $j < len($index); $j ++) {
244            
245 30         327 push(@$tmp_array, $matrix->[$index->[$j]]->[$i]);
246            
247             }
248 12         121 push(@$new_array, &$fun($tmp_array));
249             }
250 2         205 push(@$new_matrix, $new_array);
251             }
252             }
253            
254 2         7 $self->set_feature($new_feature);
255 2         5 $self->set_matrix($new_matrix);
256 2         3 undef($feature);
257 2         5 undef($matrix);
258              
259 2         10 return $self;
260             }
261              
262             sub save {
263            
264 1     1 1 3 my $self = shift;
265            
266 1         5 List::Vectorize::check_prototype(@_, '$');
267            
268 1         55 my $file = shift;
269            
270 1 50       4 if(is_empty($self->feature)) {
    50          
    50          
271 0         0 croak "ERROR: Feature names are required. ";
272             } elsif(is_empty($self->phenotype)) {
273 0         0 croak "ERROR: Phenotype names are required. ";
274             } elsif(! $self->is_valid) {
275 0         0 croak "ERROR: not a valid ".__PACKAGE__." object";
276             }
277            
278 1         4 write_table($self->matrix, "file" => $file, "row.names" => $self->feature, "col.names" => $self->phenotype);
279            
280 1         1251 return 1;
281             }
282              
283              
284             __END__