line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Statistics::Multtest;
|
2
|
|
|
|
|
|
|
|
3
|
6
|
|
|
6
|
|
139382
|
use List::Vectorize;
|
|
6
|
|
|
|
|
121108
|
|
|
6
|
|
|
|
|
2390
|
|
4
|
6
|
|
|
6
|
|
643
|
use Carp;
|
|
6
|
|
|
|
|
11
|
|
|
6
|
|
|
|
|
440
|
|
5
|
6
|
|
|
6
|
|
46
|
use strict;
|
|
6
|
|
|
|
|
11
|
|
|
6
|
|
|
|
|
244
|
|
6
|
6
|
|
|
6
|
|
31
|
use constant {EPS => 1e-10};
|
|
6
|
|
|
|
|
19
|
|
|
6
|
|
|
|
|
992
|
|
7
|
|
|
|
|
|
|
|
8
|
|
|
|
|
|
|
require Exporter;
|
9
|
|
|
|
|
|
|
our @ISA = qw(Exporter);
|
10
|
|
|
|
|
|
|
our @EXPORT_OK = qw(bonferroni holm hommel hochberg BH BY qvalue);
|
11
|
|
|
|
|
|
|
our %EXPORT_TAGS = (all => [qw(bonferroni holm hommel hochberg BH BY qvalue)]);
|
12
|
|
|
|
|
|
|
|
13
|
|
|
|
|
|
|
our $VERSION = '0.13';
|
14
|
|
|
|
|
|
|
|
15
|
|
|
|
|
|
|
1;
|
16
|
|
|
|
|
|
|
|
17
|
|
|
|
|
|
|
BEGIN {
|
18
|
6
|
|
|
6
|
|
35
|
no strict 'refs';
|
|
6
|
|
|
|
|
14
|
|
|
6
|
|
|
|
|
1035
|
|
19
|
6
|
|
|
6
|
|
18
|
for my $adjp (qw(bonferroni holm hommel hochberg BH BY qvalue)) {
|
20
|
42
|
|
|
|
|
20132
|
*{$adjp} = sub {
|
21
|
20
|
|
|
20
|
|
52867
|
my $p = shift;
|
22
|
20
|
|
|
|
|
38
|
my $name;
|
23
|
20
|
|
|
|
|
63
|
($name, $p) = initial($p);
|
24
|
20
|
|
|
|
|
36
|
*private = *{"_$adjp"};
|
|
20
|
|
|
|
|
112
|
|
25
|
20
|
|
|
|
|
64
|
my $adjp = private($p, @_);
|
26
|
18
|
|
|
|
|
3171
|
return get_result($adjp, $name);
|
27
|
|
|
|
|
|
|
}
|
28
|
42
|
|
|
|
|
173
|
}
|
29
|
|
|
|
|
|
|
}
|
30
|
|
|
|
|
|
|
|
31
|
|
|
|
|
|
|
sub initial {
|
32
|
20
|
|
|
20
|
0
|
29
|
my $p = shift;
|
33
|
|
|
|
|
|
|
|
34
|
20
|
50
|
66
|
|
|
70
|
if(! List::Vectorize::is_array_ref($p) and ! List::Vectorize::is_hash_ref($p)) {
|
35
|
0
|
|
|
|
|
0
|
croak "ERROR: P-values should be stored in an array reference or a hash reference.\n";
|
36
|
|
|
|
|
|
|
}
|
37
|
|
|
|
|
|
|
|
38
|
20
|
|
|
|
|
255
|
my $name = [];
|
39
|
20
|
100
|
|
|
|
60
|
if(List::Vectorize::is_hash_ref($p)) {
|
40
|
9
|
|
|
|
|
61
|
$name = [ keys %{$p} ];
|
|
9
|
|
|
|
|
81
|
|
41
|
9
|
|
|
|
|
24
|
$p = [ values %{$p} ];
|
|
9
|
|
|
|
|
38
|
|
42
|
|
|
|
|
|
|
}
|
43
|
|
|
|
|
|
|
|
44
|
20
|
50
|
33
|
|
|
138
|
if(max($p) > 1 or min($p) < 0) {
|
45
|
0
|
|
|
|
|
0
|
croak "ERROR: P-values should between 0 and 1.\n";
|
46
|
|
|
|
|
|
|
}
|
47
|
|
|
|
|
|
|
|
48
|
20
|
|
|
|
|
2454
|
return ($name, $p);
|
49
|
|
|
|
|
|
|
}
|
50
|
|
|
|
|
|
|
|
51
|
|
|
|
|
|
|
sub get_result {
|
52
|
18
|
|
|
18
|
0
|
40
|
my ($adjp, $name) = @_;
|
53
|
|
|
|
|
|
|
|
54
|
18
|
100
|
|
|
|
64
|
if(is_empty($name)) {
|
55
|
10
|
|
|
|
|
255
|
return $adjp;
|
56
|
|
|
|
|
|
|
}
|
57
|
|
|
|
|
|
|
else {
|
58
|
8
|
|
|
|
|
109
|
my $result;
|
59
|
8
|
|
|
|
|
22
|
for (0..$#$name) {
|
60
|
82
|
|
|
|
|
194
|
$result->{$name->[$_]} = $adjp->[$_];
|
61
|
|
|
|
|
|
|
}
|
62
|
8
|
|
|
|
|
67
|
return $result;
|
63
|
|
|
|
|
|
|
}
|
64
|
|
|
|
|
|
|
}
|
65
|
|
|
|
|
|
|
|
66
|
|
|
|
|
|
|
# R code: pmin(1, n * p)
|
67
|
|
|
|
|
|
|
sub _bonferroni {
|
68
|
2
|
|
|
2
|
|
4
|
my $p = shift;
|
69
|
2
|
|
|
|
|
10
|
my $n = len($p);
|
70
|
|
|
|
|
|
|
|
71
|
2
|
|
|
|
|
30
|
my $adjp = multiply($n, $p);
|
72
|
|
|
|
|
|
|
|
73
|
2
|
|
|
|
|
2567
|
return pmin(1, $adjp);
|
74
|
|
|
|
|
|
|
}
|
75
|
|
|
|
|
|
|
|
76
|
|
|
|
|
|
|
# R code: i = 1:n
|
77
|
|
|
|
|
|
|
# o = order(p)
|
78
|
|
|
|
|
|
|
# ro = order(o)
|
79
|
|
|
|
|
|
|
# pmin(1, cummax((n - i + 1) * p[o]))[ro]
|
80
|
|
|
|
|
|
|
sub _holm {
|
81
|
2
|
|
|
2
|
|
4
|
my $p = shift;
|
82
|
2
|
|
|
|
|
7
|
my $n = len($p);
|
83
|
|
|
|
|
|
|
|
84
|
2
|
|
|
|
|
28
|
my $i = seq(1, $n);
|
85
|
2
|
|
|
|
|
154
|
my $o = order($p);
|
86
|
2
|
|
|
|
|
193
|
my $ro = order($o);
|
87
|
|
|
|
|
|
|
|
88
|
2
|
|
|
|
|
139
|
my $adjp = multiply(minus($n + 1, $i), subset($p, $o));
|
89
|
2
|
|
|
|
|
4925
|
$adjp = cumf($adjp, \&max);
|
90
|
2
|
|
|
|
|
980
|
$adjp = pmin(1, $adjp);
|
91
|
|
|
|
|
|
|
|
92
|
2
|
|
|
|
|
127
|
return subset($adjp, $ro);
|
93
|
|
|
|
|
|
|
}
|
94
|
|
|
|
|
|
|
|
95
|
|
|
|
|
|
|
# R code: i = 1:n
|
96
|
|
|
|
|
|
|
# o = order(p)
|
97
|
|
|
|
|
|
|
# p = p[o]
|
98
|
|
|
|
|
|
|
# ro = order[o]
|
99
|
|
|
|
|
|
|
# q = pa = rep.int(min(n * p/i), n)
|
100
|
|
|
|
|
|
|
# for (j in (n - 1):2) {
|
101
|
|
|
|
|
|
|
# ij = 1:(n - j + 1)
|
102
|
|
|
|
|
|
|
# i2 = (n - j + 2):n
|
103
|
|
|
|
|
|
|
# q1 <- min(j * p[i2]/(2:j))
|
104
|
|
|
|
|
|
|
# q[ij] <- pmin(j * p[ij], q1)
|
105
|
|
|
|
|
|
|
# q[i2] <- q[n - j + 1]
|
106
|
|
|
|
|
|
|
# pa <- pmax(pa, q)
|
107
|
|
|
|
|
|
|
# }
|
108
|
|
|
|
|
|
|
# pmax(pa, p)[ro]
|
109
|
|
|
|
|
|
|
sub _hommel {
|
110
|
2
|
|
|
2
|
|
10
|
my $p = shift;
|
111
|
2
|
|
|
|
|
31
|
my $n = len($p);
|
112
|
|
|
|
|
|
|
|
113
|
2
|
|
|
|
|
25
|
my $i = seq(1, $n);
|
114
|
2
|
|
|
|
|
142
|
my $o = order($p);
|
115
|
2
|
|
|
|
|
209
|
$p = subset($p, $o);
|
116
|
2
|
|
|
|
|
520
|
my $ro = order($o);
|
117
|
|
|
|
|
|
|
|
118
|
2
|
|
|
|
|
172
|
my $pa = rep(min(divide(multiply($n, $p), $i)), $n);
|
119
|
2
|
|
|
|
|
4760
|
my $q = copy($pa);
|
120
|
|
|
|
|
|
|
|
121
|
|
|
|
|
|
|
# set the first index as 1
|
122
|
2
|
|
|
|
|
824
|
unshift(@$p, 0);
|
123
|
2
|
|
|
|
|
7
|
unshift(@$q, 0);
|
124
|
2
|
|
|
|
|
4
|
unshift(@$pa, 0);
|
125
|
|
|
|
|
|
|
|
126
|
2
|
|
|
|
|
6
|
my $ij;
|
127
|
|
|
|
|
|
|
my $i2;
|
128
|
0
|
|
|
|
|
0
|
my $q1;
|
129
|
2
|
|
|
|
|
4
|
for my $j (@{seq($n - 1, 2)}) {
|
|
2
|
|
|
|
|
8
|
|
130
|
|
|
|
|
|
|
|
131
|
16
|
|
|
|
|
983
|
$ij = seq(1, $n - $j + 1);
|
132
|
16
|
|
|
|
|
992
|
$i2 = seq($n - $j + 2, $n);
|
133
|
16
|
|
|
|
|
755
|
$q1 = min(divide(multiply($j, subset($p, $i2)), seq(2, $j)));
|
134
|
16
|
|
|
|
|
32279
|
subset_value($q, $ij, pmin(multiply($j, subset($p, $ij)), $q1));
|
135
|
16
|
|
|
|
|
5310
|
subset_value($q, $i2, $q->[$n - $j + 1]);
|
136
|
16
|
|
|
|
|
6013
|
$pa = pmax($pa, $q);
|
137
|
|
|
|
|
|
|
}
|
138
|
|
|
|
|
|
|
|
139
|
2
|
|
|
|
|
114
|
shift(@$p);
|
140
|
2
|
|
|
|
|
4
|
shift(@$q);
|
141
|
2
|
|
|
|
|
5
|
shift(@$pa);
|
142
|
|
|
|
|
|
|
|
143
|
2
|
|
|
|
|
7
|
my $adjp = pmax($pa, $p);
|
144
|
2
|
|
|
|
|
110
|
return subset($adjp, $ro);
|
145
|
|
|
|
|
|
|
}
|
146
|
|
|
|
|
|
|
|
147
|
|
|
|
|
|
|
# R code: i = n:1
|
148
|
|
|
|
|
|
|
# o <- order(p, decreasing = TRUE)
|
149
|
|
|
|
|
|
|
# ro <- order(o)
|
150
|
|
|
|
|
|
|
# pmin(1, cummin((n - i + 1) * p[o]))[ro]
|
151
|
|
|
|
|
|
|
sub _hochberg {
|
152
|
|
|
|
|
|
|
|
153
|
2
|
|
|
2
|
|
4
|
my $p = shift;
|
154
|
2
|
|
|
|
|
8
|
my $n = len($p);
|
155
|
2
|
|
|
|
|
25
|
my $i = seq($n, 1);
|
156
|
|
|
|
|
|
|
|
157
|
2
|
|
|
44
|
|
153
|
my $o = order($p, sub {$_[1] <=> $_[0]});
|
|
44
|
|
|
|
|
282
|
|
158
|
2
|
|
|
|
|
25
|
my $ro = order($o);
|
159
|
|
|
|
|
|
|
|
160
|
2
|
|
|
|
|
165
|
my $adjp = multiply(minus($n+1, $i), subset($p, $o));
|
161
|
2
|
|
|
|
|
5362
|
$adjp = cumf($adjp, \&min);
|
162
|
2
|
|
|
|
|
1070
|
$adjp = pmin(1, $adjp);
|
163
|
2
|
|
|
|
|
128
|
return subset($adjp, $ro);
|
164
|
|
|
|
|
|
|
}
|
165
|
|
|
|
|
|
|
|
166
|
|
|
|
|
|
|
# R code: i <- n:1
|
167
|
|
|
|
|
|
|
# o <- order(p, decreasing = TRUE)
|
168
|
|
|
|
|
|
|
# ro <- order(o)
|
169
|
|
|
|
|
|
|
# pmin(1, cummin(n/i * p[o]))[ro]
|
170
|
|
|
|
|
|
|
sub _BH {
|
171
|
2
|
|
|
2
|
|
4
|
my $p = shift;
|
172
|
2
|
|
|
|
|
7
|
my $n = len($p);
|
173
|
2
|
|
|
|
|
24
|
my $i = seq($n, 1);
|
174
|
|
|
|
|
|
|
|
175
|
2
|
|
|
44
|
|
142
|
my $o = order($p, sub {$_[1] <=> $_[0]});
|
|
44
|
|
|
|
|
263
|
|
176
|
2
|
|
|
|
|
12
|
my $ro = order($o);
|
177
|
|
|
|
|
|
|
|
178
|
2
|
|
|
|
|
136
|
my $adjp = multiply(divide($n, $i), subset($p, $o));
|
179
|
2
|
|
|
|
|
5184
|
$adjp = cumf($adjp, \&min);
|
180
|
2
|
|
|
|
|
1147
|
$adjp = pmin(1, $adjp);
|
181
|
2
|
|
|
|
|
123
|
return subset($adjp, $ro);
|
182
|
|
|
|
|
|
|
|
183
|
|
|
|
|
|
|
}
|
184
|
|
|
|
|
|
|
|
185
|
|
|
|
|
|
|
# R code: i <- n:1
|
186
|
|
|
|
|
|
|
# o <- order(p, decreasing = TRUE)
|
187
|
|
|
|
|
|
|
# ro <- order(o)
|
188
|
|
|
|
|
|
|
# q <- sum(1/(1L:n))
|
189
|
|
|
|
|
|
|
# pmin(1, cummin(q * n/i * p[o]))[ro]
|
190
|
|
|
|
|
|
|
sub _BY {
|
191
|
|
|
|
|
|
|
|
192
|
2
|
|
|
2
|
|
4
|
my $p = shift;
|
193
|
2
|
|
|
|
|
8
|
my $n = len($p);
|
194
|
2
|
|
|
|
|
24
|
my $i = seq($n, 1);
|
195
|
|
|
|
|
|
|
|
196
|
2
|
|
|
44
|
|
153
|
my $o = order($p, sub {$_[1] <=> $_[0]});
|
|
44
|
|
|
|
|
277
|
|
197
|
2
|
|
|
|
|
19
|
my $ro = order($o);
|
198
|
|
|
|
|
|
|
|
199
|
2
|
|
|
|
|
156
|
my $q = sum(divide(1, seq(1, $n)));
|
200
|
2
|
|
|
|
|
3508
|
my $adjp = multiply(divide($q*$n, $i), subset($p, $o));
|
201
|
2
|
|
|
|
|
5468
|
$adjp = cumf($adjp, \&min);
|
202
|
2
|
|
|
|
|
1052
|
$adjp = pmin(1, $adjp);
|
203
|
2
|
|
|
|
|
128
|
return subset($adjp, $ro);
|
204
|
|
|
|
|
|
|
}
|
205
|
|
|
|
|
|
|
|
206
|
|
|
|
|
|
|
sub pmin {
|
207
|
26
|
|
|
26
|
0
|
21100
|
my $array1 = shift;
|
208
|
26
|
|
|
|
|
74
|
my $array2 = shift;
|
209
|
|
|
|
|
|
|
|
210
|
26
|
|
|
188
|
|
131
|
return mapply($array1, $array2, sub {min(\@_)});
|
|
188
|
|
|
|
|
41586
|
|
211
|
|
|
|
|
|
|
}
|
212
|
|
|
|
|
|
|
|
213
|
|
|
|
|
|
|
sub pmax {
|
214
|
18
|
|
|
18
|
0
|
28
|
my $array1 = shift;
|
215
|
18
|
|
|
|
|
24
|
my $array2 = shift;
|
216
|
|
|
|
|
|
|
|
217
|
18
|
|
|
196
|
|
89
|
return mapply($array1, $array2, sub {max(\@_)});
|
|
196
|
|
|
|
|
28226
|
|
218
|
|
|
|
|
|
|
}
|
219
|
|
|
|
|
|
|
|
220
|
|
|
|
|
|
|
|
221
|
|
|
|
|
|
|
# the default setting can not assure the success of calculation
|
222
|
|
|
|
|
|
|
# so this function should run under eval
|
223
|
|
|
|
|
|
|
# eval(q(qvalue $p));
|
224
|
|
|
|
|
|
|
# if ($@) change_other_settings
|
225
|
|
|
|
|
|
|
# @p = qw(0.76 0.30 0.40 0.43 0.27 0.79 0.66 0.36 0.12 0.16 0.52 0.04 0.67 0.44 0.40 0.09 0.51 0.38 0.49 0.68)
|
226
|
|
|
|
|
|
|
sub _qvalue {
|
227
|
8
|
|
|
8
|
|
16
|
my $p = shift;
|
228
|
8
|
|
|
|
|
33
|
my %setup = ('lambda' => multiply(seq(0, 90, 5), 0.01),
|
229
|
|
|
|
|
|
|
'robust' => 0,
|
230
|
|
|
|
|
|
|
@_ );
|
231
|
|
|
|
|
|
|
|
232
|
8
|
|
|
|
|
15665
|
my $lambda = $setup{'lambda'};
|
233
|
8
|
|
|
|
|
20
|
my $robust = $setup{'robust'};
|
234
|
|
|
|
|
|
|
|
235
|
8
|
50
|
|
|
|
27
|
if(! List::Vectorize::is_array_ref($lambda)) {
|
236
|
0
|
|
|
|
|
0
|
croak "ERROR: lambda should be an array reference. If your lambda is a single number, you should set it as an array reference containing one element, such as [0.1].";
|
237
|
|
|
|
|
|
|
}
|
238
|
|
|
|
|
|
|
|
239
|
8
|
50
|
66
|
|
|
80
|
if(len($lambda) > 1 and len($lambda) < 4) {
|
240
|
0
|
|
|
|
|
0
|
croak "ERROR: If length of lambda greater than 1, you need at least 4 values.";
|
241
|
|
|
|
|
|
|
}
|
242
|
8
|
50
|
33
|
|
|
165
|
if(len($lambda) > 1 and (min($lambda) < 0 or max($lambda) >= 1)) {
|
|
|
|
66
|
|
|
|
|
243
|
0
|
|
|
|
|
0
|
croak "ERROR: Lambda must be within [0, 1).";
|
244
|
|
|
|
|
|
|
}
|
245
|
|
|
|
|
|
|
|
246
|
|
|
|
|
|
|
# m <- length(p)
|
247
|
8
|
|
|
|
|
819
|
my $m = len($p);
|
248
|
8
|
|
|
|
|
79
|
my $pi0;
|
249
|
|
|
|
|
|
|
|
250
|
8
|
100
|
|
|
|
22
|
if(len($lambda) == 1) {
|
251
|
2
|
|
|
|
|
19
|
$lambda = $lambda->[0];
|
252
|
2
|
50
|
33
|
|
|
16
|
if($lambda < 0 or $lambda >= 1) {
|
253
|
0
|
|
|
|
|
0
|
croak "ERROR: Lambda must be within [0, 1).";
|
254
|
|
|
|
|
|
|
}
|
255
|
|
|
|
|
|
|
# pi0 <- mean(p >= lambda)/(1-lambda)
|
256
|
2
|
|
|
20
|
|
14
|
$pi0 = mean(test($p, sub {_approximately_compare($_[0], ">=", $lambda)})) / (1 - $lambda);
|
|
20
|
|
|
|
|
254
|
|
257
|
|
|
|
|
|
|
# pi0 <- min(pi0,1)
|
258
|
2
|
|
|
|
|
367
|
$pi0 = min(c($pi0, 1));
|
259
|
|
|
|
|
|
|
}
|
260
|
|
|
|
|
|
|
else {
|
261
|
|
|
|
|
|
|
# pi0 <- rep(0,length(lambda))
|
262
|
6
|
|
|
|
|
65
|
$pi0 = rep(0, len($lambda));
|
263
|
|
|
|
|
|
|
# for(i in 1:length(lambda)) {
|
264
|
|
|
|
|
|
|
# pi0[i] <- mean(p >= lambda[i])/(1-lambda[i])
|
265
|
|
|
|
|
|
|
# }
|
266
|
|
|
|
|
|
|
$pi0 = sapply(seq(0, len($lambda) - 1),
|
267
|
|
|
|
|
|
|
sub {
|
268
|
114
|
|
|
114
|
|
24351
|
my $current_lambda = $lambda->[$_[0]];
|
269
|
114
|
|
|
|
|
864
|
mean(test($p, sub {_approximately_compare($_[0], ">=", $current_lambda)})) / (1 - $current_lambda);
|
|
1197
|
|
|
|
|
18375
|
|
270
|
6
|
|
|
|
|
997
|
});
|
271
|
|
|
|
|
|
|
|
272
|
|
|
|
|
|
|
# minpi0 <- min(pi0)
|
273
|
6
|
|
|
|
|
1128
|
my $minpi0 = min($pi0);
|
274
|
|
|
|
|
|
|
|
275
|
|
|
|
|
|
|
# mse <- rep(0,length(lambda))
|
276
|
6
|
|
|
|
|
323
|
my $mse = rep(0, len($lambda));
|
277
|
|
|
|
|
|
|
# pi0.boot <- rep(0,length(lambda))
|
278
|
6
|
|
|
|
|
1092
|
my $pi0_boot = rep(0, len($lambda));
|
279
|
6
|
|
|
|
|
623
|
for (1..100) {
|
280
|
|
|
|
|
|
|
# p.boot <- sample(p,size=m,replace=TRUE)
|
281
|
600
|
|
|
|
|
894920
|
my $p_boot = sample($p, $m, 'replace' => 1);
|
282
|
|
|
|
|
|
|
# for(i in 1:length(lambda)) {
|
283
|
|
|
|
|
|
|
# pi0.boot[i] <- mean(p.boot>lambda[i])/(1-lambda[i])
|
284
|
|
|
|
|
|
|
# }
|
285
|
|
|
|
|
|
|
$pi0_boot = sapply(seq(0, len($lambda) - 1),
|
286
|
|
|
|
|
|
|
sub {
|
287
|
11400
|
|
|
11400
|
|
2261607
|
my $current_lambda = $lambda->[$_[0]];
|
288
|
11400
|
|
|
|
|
55030
|
mean(test($p_boot, sub {$_[0] > $current_lambda})) / (1 - $current_lambda);
|
|
119700
|
|
|
|
|
1810943
|
|
289
|
600
|
|
|
|
|
1349899
|
});
|
290
|
|
|
|
|
|
|
# mse <- mse + (pi0.boot-minpi0)^2
|
291
|
600
|
|
|
|
|
133890
|
$mse = plus($mse, power(minus($pi0_boot, $minpi0), 2));
|
292
|
|
|
|
|
|
|
}
|
293
|
|
|
|
|
|
|
|
294
|
|
|
|
|
|
|
# pi0 <- min(pi0[mse==min(mse)])
|
295
|
6
|
|
|
|
|
8861
|
my $min_mse = min($mse);
|
296
|
|
|
|
|
|
|
|
297
|
6
|
|
|
114
|
|
487
|
$pi0 = min(subset($pi0, which(test($mse, sub {_approximately_compare($_[0], "==", $min_mse)}))));
|
|
114
|
|
|
|
|
1540
|
|
298
|
6
|
|
|
|
|
1949
|
$pi0 = min(c($pi0, 1));
|
299
|
|
|
|
|
|
|
}
|
300
|
|
|
|
|
|
|
|
301
|
8
|
100
|
|
|
|
1214
|
if($pi0 <= 0) {
|
302
|
2
|
|
|
|
|
704
|
croak "ERROR: The estimated pi0 ($pi0) <= 0. Check that you have valid p-values or use another lambda method.";
|
303
|
|
|
|
|
|
|
}
|
304
|
|
|
|
|
|
|
|
305
|
|
|
|
|
|
|
# u <- order(p)
|
306
|
6
|
|
|
|
|
26
|
my $u = order($p);
|
307
|
|
|
|
|
|
|
|
308
|
|
|
|
|
|
|
# this function is not the same to the function in qvalue
|
309
|
|
|
|
|
|
|
# but returns the same result
|
310
|
|
|
|
|
|
|
# returns number of observations less than or equal to
|
311
|
|
|
|
|
|
|
sub qvalue_rank {
|
312
|
6
|
|
|
6
|
0
|
12
|
my $x = shift;
|
313
|
|
|
|
|
|
|
return sapply($x, sub {
|
314
|
62
|
|
|
62
|
|
8855
|
my $current_x = $_[0];
|
315
|
62
|
|
|
|
|
648
|
sum(test($x, sub {$_[0] <= $current_x}));
|
|
642
|
|
|
|
|
8780
|
|
316
|
6
|
|
|
|
|
35
|
});
|
317
|
|
|
|
|
|
|
}
|
318
|
|
|
|
|
|
|
|
319
|
|
|
|
|
|
|
# v <- qvalue.rank(p)
|
320
|
6
|
|
|
|
|
677
|
my $v = qvalue_rank($p);
|
321
|
|
|
|
|
|
|
# qvalue <- pi0*m*p/v
|
322
|
6
|
|
|
|
|
904
|
my $qvalue = divide(multiply($pi0, $m, $p), $v);
|
323
|
|
|
|
|
|
|
|
324
|
6
|
100
|
|
|
|
25338
|
if($robust) {
|
325
|
|
|
|
|
|
|
# qvalue <- pi0*m*p/(v*(1-(1-p)^m))
|
326
|
2
|
|
|
|
|
13
|
$qvalue = divide(multiply($pi0, $m, $p), multiply($v, minus(1, power(minus(1, $p), $m))));
|
327
|
|
|
|
|
|
|
}
|
328
|
|
|
|
|
|
|
|
329
|
|
|
|
|
|
|
# qvalue[u[m]] <- min(qvalue[u[m]],1)
|
330
|
6
|
|
|
|
|
6190
|
$qvalue->[$u->[$#$u]] = min(c($qvalue->[$u->[$#$u]], 1));
|
331
|
|
|
|
|
|
|
# for(i in (m-1):1) {
|
332
|
|
|
|
|
|
|
# qvalue[u[i]] <- min(qvalue[u[i]],qvalue[u[i+1]],1)
|
333
|
|
|
|
|
|
|
# }
|
334
|
6
|
|
|
|
|
933
|
for my $i (@{seq($#$u-1, 0)}) {
|
|
6
|
|
|
|
|
29
|
|
335
|
56
|
|
|
|
|
2362
|
$qvalue->[$u->[$i]] = min([$qvalue->[$u->[$i]], $qvalue->[$u->[$i+1]], 1]);
|
336
|
|
|
|
|
|
|
}
|
337
|
|
|
|
|
|
|
|
338
|
6
|
|
|
|
|
238
|
return $qvalue;
|
339
|
|
|
|
|
|
|
}
|
340
|
|
|
|
|
|
|
|
341
|
|
|
|
|
|
|
# vectorized power calculation
|
342
|
|
|
|
|
|
|
sub power {
|
343
|
602
|
|
|
602
|
0
|
1188457
|
my $array = shift;
|
344
|
602
|
|
|
|
|
1240
|
my $power = shift;
|
345
|
|
|
|
|
|
|
|
346
|
602
|
|
|
11420
|
|
3257
|
my $res = sapply($array, sub {$_[0]**($power)});
|
|
11420
|
|
|
|
|
70869
|
|
347
|
602
|
|
|
|
|
7761
|
return $res;
|
348
|
|
|
|
|
|
|
}
|
349
|
|
|
|
|
|
|
|
350
|
|
|
|
|
|
|
# approximately
|
351
|
|
|
|
|
|
|
sub _approximately_compare {
|
352
|
1331
|
|
|
1331
|
|
3282
|
my $left = shift;
|
353
|
1331
|
|
|
|
|
1304
|
my $sign = shift;
|
354
|
1331
|
|
|
|
|
1852
|
my $right = shift;
|
355
|
|
|
|
|
|
|
|
356
|
1331
|
100
|
66
|
|
|
5991
|
if($sign eq ">" or $sign eq ">=") {
|
|
|
50
|
33
|
|
|
|
|
|
|
50
|
|
|
|
|
|
357
|
1217
|
100
|
|
|
|
2820
|
if($left > $right) {
|
|
|
100
|
|
|
|
|
|
358
|
593
|
|
|
|
|
1305
|
return 1;
|
359
|
|
|
|
|
|
|
}
|
360
|
|
|
|
|
|
|
elsif(abs($left - $right) < EPS) {
|
361
|
38
|
|
|
|
|
1255
|
return 1;
|
362
|
|
|
|
|
|
|
}
|
363
|
|
|
|
|
|
|
else {
|
364
|
586
|
|
|
|
|
19715
|
return 0;
|
365
|
|
|
|
|
|
|
}
|
366
|
|
|
|
|
|
|
}
|
367
|
|
|
|
|
|
|
elsif($sign eq "<" or $sign eq "<=") {
|
368
|
0
|
0
|
|
|
|
0
|
if($left < $right) {
|
|
|
0
|
|
|
|
|
|
369
|
0
|
|
|
|
|
0
|
return 1;
|
370
|
|
|
|
|
|
|
}
|
371
|
|
|
|
|
|
|
elsif(abs($left - $right) < EPS) {
|
372
|
0
|
|
|
|
|
0
|
return 1;
|
373
|
|
|
|
|
|
|
}
|
374
|
|
|
|
|
|
|
else {
|
375
|
0
|
|
|
|
|
0
|
return 0;
|
376
|
|
|
|
|
|
|
}
|
377
|
|
|
|
|
|
|
}
|
378
|
|
|
|
|
|
|
elsif($sign eq "==") {
|
379
|
114
|
100
|
|
|
|
314
|
if(abs($left - $right) < EPS) {
|
380
|
26
|
|
|
|
|
737
|
return 1;
|
381
|
|
|
|
|
|
|
}
|
382
|
|
|
|
|
|
|
else {
|
383
|
88
|
|
|
|
|
2592
|
return 0;
|
384
|
|
|
|
|
|
|
}
|
385
|
|
|
|
|
|
|
}
|
386
|
|
|
|
|
|
|
}
|
387
|
|
|
|
|
|
|
|
388
|
|
|
|
|
|
|
__END__
|