| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
package Statistics::Multtest; |
|
2
|
|
|
|
|
|
|
|
|
3
|
6
|
|
|
6
|
|
233318
|
use List::Vectorize; |
|
|
6
|
|
|
|
|
73802
|
|
|
|
6
|
|
|
|
|
1772
|
|
|
4
|
6
|
|
|
6
|
|
55
|
use Carp; |
|
|
6
|
|
|
|
|
17
|
|
|
|
6
|
|
|
|
|
386
|
|
|
5
|
6
|
|
|
6
|
|
38
|
use strict; |
|
|
6
|
|
|
|
|
12
|
|
|
|
6
|
|
|
|
|
181
|
|
|
6
|
6
|
|
|
6
|
|
58
|
use constant {EPS => 1e-10}; |
|
|
6
|
|
|
|
|
23
|
|
|
|
6
|
|
|
|
|
941
|
|
|
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.14'; |
|
14
|
|
|
|
|
|
|
|
|
15
|
|
|
|
|
|
|
1; |
|
16
|
|
|
|
|
|
|
|
|
17
|
|
|
|
|
|
|
BEGIN { |
|
18
|
6
|
|
|
6
|
|
44
|
no strict 'refs'; |
|
|
6
|
|
|
|
|
13
|
|
|
|
6
|
|
|
|
|
836
|
|
|
19
|
6
|
|
|
6
|
|
29
|
for my $adjp (qw(bonferroni holm hommel hochberg BH BY qvalue)) { |
|
20
|
42
|
|
|
|
|
12771
|
*{$adjp} = sub { |
|
21
|
20
|
|
|
20
|
|
40037
|
my $p = shift; |
|
22
|
20
|
|
|
|
|
45
|
my $name; |
|
23
|
20
|
|
|
|
|
69
|
($name, $p) = initial($p); |
|
24
|
20
|
|
|
|
|
38
|
*private = *{"_$adjp"}; |
|
|
20
|
|
|
|
|
157
|
|
|
25
|
20
|
|
|
|
|
89
|
my $adjp = private($p, @_); |
|
26
|
18
|
|
|
|
|
2730
|
return get_result($adjp, $name); |
|
27
|
|
|
|
|
|
|
} |
|
28
|
42
|
|
|
|
|
148
|
} |
|
29
|
|
|
|
|
|
|
} |
|
30
|
|
|
|
|
|
|
|
|
31
|
|
|
|
|
|
|
sub initial { |
|
32
|
20
|
|
|
20
|
0
|
55
|
my $p = shift; |
|
33
|
|
|
|
|
|
|
|
|
34
|
20
|
50
|
66
|
|
|
69
|
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
|
|
|
|
|
279
|
my $name = []; |
|
39
|
20
|
100
|
|
|
|
66
|
if(List::Vectorize::is_hash_ref($p)) { |
|
40
|
9
|
|
|
|
|
64
|
$name = [ keys %{$p} ]; |
|
|
9
|
|
|
|
|
53
|
|
|
41
|
9
|
|
|
|
|
23
|
$p = [ values %{$p} ]; |
|
|
9
|
|
|
|
|
35
|
|
|
42
|
|
|
|
|
|
|
} |
|
43
|
|
|
|
|
|
|
|
|
44
|
20
|
50
|
33
|
|
|
152
|
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
|
|
|
|
|
2779
|
return ($name, $p); |
|
49
|
|
|
|
|
|
|
} |
|
50
|
|
|
|
|
|
|
|
|
51
|
|
|
|
|
|
|
sub get_result { |
|
52
|
18
|
|
|
18
|
0
|
64
|
my ($adjp, $name) = @_; |
|
53
|
|
|
|
|
|
|
|
|
54
|
18
|
100
|
|
|
|
67
|
if(is_empty($name)) { |
|
55
|
10
|
|
|
|
|
227
|
return $adjp; |
|
56
|
|
|
|
|
|
|
} |
|
57
|
|
|
|
|
|
|
else { |
|
58
|
8
|
|
|
|
|
127
|
my $result; |
|
59
|
8
|
|
|
|
|
32
|
for (0..$#$name) { |
|
60
|
82
|
|
|
|
|
234
|
$result->{$name->[$_]} = $adjp->[$_]; |
|
61
|
|
|
|
|
|
|
} |
|
62
|
8
|
|
|
|
|
97
|
return $result; |
|
63
|
|
|
|
|
|
|
} |
|
64
|
|
|
|
|
|
|
} |
|
65
|
|
|
|
|
|
|
|
|
66
|
|
|
|
|
|
|
# R code: pmin(1, n * p) |
|
67
|
|
|
|
|
|
|
sub _bonferroni { |
|
68
|
2
|
|
|
2
|
|
4
|
my $p = shift; |
|
69
|
2
|
|
|
|
|
8
|
my $n = len($p); |
|
70
|
|
|
|
|
|
|
|
|
71
|
2
|
|
|
|
|
31
|
my $adjp = multiply($n, $p); |
|
72
|
|
|
|
|
|
|
|
|
73
|
2
|
|
|
|
|
2935
|
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
|
|
6
|
my $p = shift; |
|
82
|
2
|
|
|
|
|
9
|
my $n = len($p); |
|
83
|
|
|
|
|
|
|
|
|
84
|
2
|
|
|
|
|
33
|
my $i = seq(1, $n); |
|
85
|
2
|
|
|
|
|
188
|
my $o = order($p); |
|
86
|
2
|
|
|
|
|
281
|
my $ro = order($o); |
|
87
|
|
|
|
|
|
|
|
|
88
|
2
|
|
|
|
|
221
|
my $adjp = multiply(minus($n + 1, $i), subset($p, $o)); |
|
89
|
2
|
|
|
|
|
5714
|
$adjp = cumf($adjp, \&max); |
|
90
|
2
|
|
|
|
|
1021
|
$adjp = pmin(1, $adjp); |
|
91
|
|
|
|
|
|
|
|
|
92
|
2
|
|
|
|
|
100
|
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
|
|
4
|
my $p = shift; |
|
111
|
2
|
|
|
|
|
7
|
my $n = len($p); |
|
112
|
|
|
|
|
|
|
|
|
113
|
2
|
|
|
|
|
26
|
my $i = seq(1, $n); |
|
114
|
2
|
|
|
|
|
162
|
my $o = order($p); |
|
115
|
2
|
|
|
|
|
239
|
$p = subset($p, $o); |
|
116
|
2
|
|
|
|
|
529
|
my $ro = order($o); |
|
117
|
|
|
|
|
|
|
|
|
118
|
2
|
|
|
|
|
191
|
my $pa = rep(min(divide(multiply($n, $p), $i)), $n); |
|
119
|
2
|
|
|
|
|
5622
|
my $q = copy($pa); |
|
120
|
|
|
|
|
|
|
|
|
121
|
|
|
|
|
|
|
# set the first index as 1 |
|
122
|
2
|
|
|
|
|
828
|
unshift(@$p, 0); |
|
123
|
2
|
|
|
|
|
7
|
unshift(@$q, 0); |
|
124
|
2
|
|
|
|
|
8
|
unshift(@$pa, 0); |
|
125
|
|
|
|
|
|
|
|
|
126
|
2
|
|
|
|
|
7
|
my $ij; |
|
127
|
|
|
|
|
|
|
my $i2; |
|
128
|
2
|
|
|
|
|
0
|
my $q1; |
|
129
|
2
|
|
|
|
|
5
|
for my $j (@{seq($n - 1, 2)}) { |
|
|
2
|
|
|
|
|
11
|
|
|
130
|
|
|
|
|
|
|
|
|
131
|
16
|
|
|
|
|
1051
|
$ij = seq(1, $n - $j + 1); |
|
132
|
16
|
|
|
|
|
1282
|
$i2 = seq($n - $j + 2, $n); |
|
133
|
16
|
|
|
|
|
838
|
$q1 = min(divide(multiply($j, subset($p, $i2)), seq(2, $j))); |
|
134
|
16
|
|
|
|
|
34829
|
subset_value($q, $ij, pmin(multiply($j, subset($p, $ij)), $q1)); |
|
135
|
16
|
|
|
|
|
5181
|
subset_value($q, $i2, $q->[$n - $j + 1]); |
|
136
|
16
|
|
|
|
|
6061
|
$pa = pmax($pa, $q); |
|
137
|
|
|
|
|
|
|
} |
|
138
|
|
|
|
|
|
|
|
|
139
|
2
|
|
|
|
|
95
|
shift(@$p); |
|
140
|
2
|
|
|
|
|
6
|
shift(@$q); |
|
141
|
2
|
|
|
|
|
5
|
shift(@$pa); |
|
142
|
|
|
|
|
|
|
|
|
143
|
2
|
|
|
|
|
6
|
my $adjp = pmax($pa, $p); |
|
144
|
2
|
|
|
|
|
94
|
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
|
|
5
|
my $p = shift; |
|
154
|
2
|
|
|
|
|
6
|
my $n = len($p); |
|
155
|
2
|
|
|
|
|
25
|
my $i = seq($n, 1); |
|
156
|
|
|
|
|
|
|
|
|
157
|
2
|
|
|
48
|
|
141
|
my $o = order($p, sub {$_[1] <=> $_[0]}); |
|
|
48
|
|
|
|
|
264
|
|
|
158
|
2
|
|
|
|
|
44
|
my $ro = order($o); |
|
159
|
|
|
|
|
|
|
|
|
160
|
2
|
|
|
|
|
263
|
my $adjp = multiply(minus($n+1, $i), subset($p, $o)); |
|
161
|
2
|
|
|
|
|
5145
|
$adjp = cumf($adjp, \&min); |
|
162
|
2
|
|
|
|
|
1008
|
$adjp = pmin(1, $adjp); |
|
163
|
2
|
|
|
|
|
91
|
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
|
|
8
|
my $p = shift; |
|
172
|
2
|
|
|
|
|
7
|
my $n = len($p); |
|
173
|
2
|
|
|
|
|
31
|
my $i = seq($n, 1); |
|
174
|
|
|
|
|
|
|
|
|
175
|
2
|
|
|
48
|
|
241
|
my $o = order($p, sub {$_[1] <=> $_[0]}); |
|
|
48
|
|
|
|
|
286
|
|
|
176
|
2
|
|
|
|
|
14
|
my $ro = order($o); |
|
177
|
|
|
|
|
|
|
|
|
178
|
2
|
|
|
|
|
240
|
my $adjp = multiply(divide($n, $i), subset($p, $o)); |
|
179
|
2
|
|
|
|
|
4858
|
$adjp = cumf($adjp, \&min); |
|
180
|
2
|
|
|
|
|
1378
|
$adjp = pmin(1, $adjp); |
|
181
|
2
|
|
|
|
|
105
|
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
|
|
5
|
my $p = shift; |
|
193
|
2
|
|
|
|
|
6
|
my $n = len($p); |
|
194
|
2
|
|
|
|
|
24
|
my $i = seq($n, 1); |
|
195
|
|
|
|
|
|
|
|
|
196
|
2
|
|
|
48
|
|
138
|
my $o = order($p, sub {$_[1] <=> $_[0]}); |
|
|
48
|
|
|
|
|
232
|
|
|
197
|
2
|
|
|
|
|
12
|
my $ro = order($o); |
|
198
|
|
|
|
|
|
|
|
|
199
|
2
|
|
|
|
|
187
|
my $q = sum(divide(1, seq(1, $n))); |
|
200
|
2
|
|
|
|
|
2912
|
my $adjp = multiply(divide($q*$n, $i), subset($p, $o)); |
|
201
|
2
|
|
|
|
|
5520
|
$adjp = cumf($adjp, \&min); |
|
202
|
2
|
|
|
|
|
1074
|
$adjp = pmin(1, $adjp); |
|
203
|
2
|
|
|
|
|
135
|
return subset($adjp, $ro); |
|
204
|
|
|
|
|
|
|
} |
|
205
|
|
|
|
|
|
|
|
|
206
|
|
|
|
|
|
|
sub pmin { |
|
207
|
26
|
|
|
26
|
0
|
21511
|
my $array1 = shift; |
|
208
|
26
|
|
|
|
|
56
|
my $array2 = shift; |
|
209
|
|
|
|
|
|
|
|
|
210
|
26
|
|
|
188
|
|
164
|
return mapply($array1, $array2, sub {min(\@_)}); |
|
|
188
|
|
|
|
|
38896
|
|
|
211
|
|
|
|
|
|
|
} |
|
212
|
|
|
|
|
|
|
|
|
213
|
|
|
|
|
|
|
sub pmax { |
|
214
|
18
|
|
|
18
|
0
|
36
|
my $array1 = shift; |
|
215
|
18
|
|
|
|
|
33
|
my $array2 = shift; |
|
216
|
|
|
|
|
|
|
|
|
217
|
18
|
|
|
196
|
|
105
|
return mapply($array1, $array2, sub {max(\@_)}); |
|
|
196
|
|
|
|
|
29453
|
|
|
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
|
|
18
|
my $p = shift; |
|
228
|
8
|
|
|
|
|
34
|
my %setup = ('lambda' => multiply(seq(0, 90, 5), 0.01), |
|
229
|
|
|
|
|
|
|
'robust' => 0, |
|
230
|
|
|
|
|
|
|
@_ ); |
|
231
|
|
|
|
|
|
|
|
|
232
|
8
|
|
|
|
|
18951
|
my $lambda = $setup{'lambda'}; |
|
233
|
8
|
|
|
|
|
21
|
my $robust = $setup{'robust'}; |
|
234
|
|
|
|
|
|
|
|
|
235
|
8
|
50
|
|
|
|
30
|
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
|
|
|
78
|
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
|
|
|
186
|
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
|
|
|
|
|
1068
|
my $m = len($p); |
|
248
|
8
|
|
|
|
|
90
|
my $pi0; |
|
249
|
|
|
|
|
|
|
|
|
250
|
8
|
100
|
|
|
|
23
|
if(len($lambda) == 1) { |
|
251
|
2
|
|
|
|
|
24
|
$lambda = $lambda->[0]; |
|
252
|
2
|
50
|
33
|
|
|
17
|
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
|
|
15
|
$pi0 = mean(test($p, sub {_approximately_compare($_[0], ">=", $lambda)})) / (1 - $lambda); |
|
|
20
|
|
|
|
|
253
|
|
|
257
|
|
|
|
|
|
|
# pi0 <- min(pi0,1) |
|
258
|
2
|
|
|
|
|
315
|
$pi0 = min(c($pi0, 1)); |
|
259
|
|
|
|
|
|
|
} |
|
260
|
|
|
|
|
|
|
else { |
|
261
|
|
|
|
|
|
|
# pi0 <- rep(0,length(lambda)) |
|
262
|
6
|
|
|
|
|
72
|
$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
|
|
25507
|
my $current_lambda = $lambda->[$_[0]]; |
|
269
|
114
|
|
|
|
|
602
|
mean(test($p, sub {_approximately_compare($_[0], ">=", $current_lambda)})) / (1 - $current_lambda); |
|
|
1197
|
|
|
|
|
19747
|
|
|
270
|
6
|
|
|
|
|
1281
|
}); |
|
271
|
|
|
|
|
|
|
|
|
272
|
|
|
|
|
|
|
# minpi0 <- min(pi0) |
|
273
|
6
|
|
|
|
|
1469
|
my $minpi0 = min($pi0); |
|
274
|
|
|
|
|
|
|
|
|
275
|
|
|
|
|
|
|
# mse <- rep(0,length(lambda)) |
|
276
|
6
|
|
|
|
|
462
|
my $mse = rep(0, len($lambda)); |
|
277
|
|
|
|
|
|
|
# pi0.boot <- rep(0,length(lambda)) |
|
278
|
6
|
|
|
|
|
1289
|
my $pi0_boot = rep(0, len($lambda)); |
|
279
|
6
|
|
|
|
|
910
|
for (1..100) { |
|
280
|
|
|
|
|
|
|
# p.boot <- sample(p,size=m,replace=TRUE) |
|
281
|
600
|
|
|
|
|
999910
|
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
|
|
2340940
|
my $current_lambda = $lambda->[$_[0]]; |
|
288
|
11400
|
|
|
|
|
49756
|
mean(test($p_boot, sub {$_[0] > $current_lambda})) / (1 - $current_lambda); |
|
|
119700
|
|
|
|
|
1816079
|
|
|
289
|
600
|
|
|
|
|
1432254
|
}); |
|
290
|
|
|
|
|
|
|
# mse <- mse + (pi0.boot-minpi0)^2 |
|
291
|
600
|
|
|
|
|
129036
|
$mse = plus($mse, power(minus($pi0_boot, $minpi0), 2)); |
|
292
|
|
|
|
|
|
|
} |
|
293
|
|
|
|
|
|
|
|
|
294
|
|
|
|
|
|
|
# pi0 <- min(pi0[mse==min(mse)]) |
|
295
|
6
|
|
|
|
|
10072
|
my $min_mse = min($mse); |
|
296
|
|
|
|
|
|
|
|
|
297
|
6
|
|
|
114
|
|
507
|
$pi0 = min(subset($pi0, which(test($mse, sub {_approximately_compare($_[0], "==", $min_mse)})))); |
|
|
114
|
|
|
|
|
1708
|
|
|
298
|
6
|
|
|
|
|
2331
|
$pi0 = min(c($pi0, 1)); |
|
299
|
|
|
|
|
|
|
} |
|
300
|
|
|
|
|
|
|
|
|
301
|
8
|
100
|
|
|
|
1168
|
if($pi0 <= 0) { |
|
302
|
2
|
|
|
|
|
467
|
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
|
13
|
my $x = shift; |
|
313
|
|
|
|
|
|
|
return sapply($x, sub { |
|
314
|
62
|
|
|
62
|
|
8473
|
my $current_x = $_[0]; |
|
315
|
62
|
|
|
|
|
233
|
sum(test($x, sub {$_[0] <= $current_x})); |
|
|
642
|
|
|
|
|
8503
|
|
|
316
|
6
|
|
|
|
|
29
|
}); |
|
317
|
|
|
|
|
|
|
} |
|
318
|
|
|
|
|
|
|
|
|
319
|
|
|
|
|
|
|
# v <- qvalue.rank(p) |
|
320
|
6
|
|
|
|
|
679
|
my $v = qvalue_rank($p); |
|
321
|
|
|
|
|
|
|
# qvalue <- pi0*m*p/v |
|
322
|
6
|
|
|
|
|
989
|
my $qvalue = divide(multiply($pi0, $m, $p), $v); |
|
323
|
|
|
|
|
|
|
|
|
324
|
6
|
100
|
|
|
|
19182
|
if($robust) { |
|
325
|
|
|
|
|
|
|
# qvalue <- pi0*m*p/(v*(1-(1-p)^m)) |
|
326
|
2
|
|
|
|
|
14
|
$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
|
|
|
|
|
6524
|
$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
|
|
|
|
|
845
|
for my $i (@{seq($#$u-1, 0)}) { |
|
|
6
|
|
|
|
|
26
|
|
|
335
|
56
|
|
|
|
|
2298
|
$qvalue->[$u->[$i]] = min([$qvalue->[$u->[$i]], $qvalue->[$u->[$i+1]], 1]); |
|
336
|
|
|
|
|
|
|
} |
|
337
|
|
|
|
|
|
|
|
|
338
|
6
|
|
|
|
|
235
|
return $qvalue; |
|
339
|
|
|
|
|
|
|
} |
|
340
|
|
|
|
|
|
|
|
|
341
|
|
|
|
|
|
|
# vectorized power calculation |
|
342
|
|
|
|
|
|
|
sub power { |
|
343
|
602
|
|
|
602
|
0
|
1370691
|
my $array = shift; |
|
344
|
602
|
|
|
|
|
1387
|
my $power = shift; |
|
345
|
|
|
|
|
|
|
|
|
346
|
602
|
|
|
11420
|
|
3203
|
my $res = sapply($array, sub {$_[0]**($power)}); |
|
|
11420
|
|
|
|
|
78503
|
|
|
347
|
602
|
|
|
|
|
6353
|
return $res; |
|
348
|
|
|
|
|
|
|
} |
|
349
|
|
|
|
|
|
|
|
|
350
|
|
|
|
|
|
|
# approximately |
|
351
|
|
|
|
|
|
|
sub _approximately_compare { |
|
352
|
1331
|
|
|
1331
|
|
2273
|
my $left = shift; |
|
353
|
1331
|
|
|
|
|
2226
|
my $sign = shift; |
|
354
|
1331
|
|
|
|
|
1891
|
my $right = shift; |
|
355
|
|
|
|
|
|
|
|
|
356
|
1331
|
100
|
66
|
|
|
4627
|
if($sign eq ">" or $sign eq ">=") { |
|
|
|
50
|
33
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
357
|
1217
|
100
|
|
|
|
2918
|
if($left > $right) { |
|
|
|
100
|
|
|
|
|
|
|
358
|
593
|
|
|
|
|
1483
|
return 1; |
|
359
|
|
|
|
|
|
|
} |
|
360
|
|
|
|
|
|
|
elsif(abs($left - $right) < EPS) { |
|
361
|
38
|
|
|
|
|
1420
|
return 1; |
|
362
|
|
|
|
|
|
|
} |
|
363
|
|
|
|
|
|
|
else { |
|
364
|
586
|
|
|
|
|
18941
|
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
|
|
|
|
277
|
if(abs($left - $right) < EPS) { |
|
380
|
26
|
|
|
|
|
1062
|
return 1; |
|
381
|
|
|
|
|
|
|
} |
|
382
|
|
|
|
|
|
|
else { |
|
383
|
88
|
|
|
|
|
2575
|
return 0; |
|
384
|
|
|
|
|
|
|
} |
|
385
|
|
|
|
|
|
|
} |
|
386
|
|
|
|
|
|
|
} |
|
387
|
|
|
|
|
|
|
|
|
388
|
|
|
|
|
|
|
__END__ |