-
Notifications
You must be signed in to change notification settings - Fork 0
/
FDR.py
58 lines (52 loc) · 2.31 KB
/
FDR.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
#!/usr/bin/env python3
# Copyright 2017 Francisco Pina Martins <f.pinamartins@gmail.com>
# This file is part of structure_threader.
# structure_threader is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# structure_threader is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with structure_threader. If not, see <http://www.gnu.org/licenses/>.
# Taken from https://stackoverflow.com/a/21739593/3091595, ported to python 3
# and improved readability.
def multiple_testing_correction(pvalues, correction_type="FDR"):
"""
Consistent with R - print
correct_pvalues_for_multiple_testing([0.0, 0.01, 0.029, 0.03, 0.031, 0.05,
0.069, 0.07, 0.071, 0.09, 0.1])
"""
from numpy import array, empty
pvalues = array(pvalues)
sample_size = pvalues.shape[0]
qvalues = empty(sample_size)
if correction_type == "Bonferroni":
# Bonferroni correction
qvalues = sample_size * pvalues
elif correction_type == "Bonferroni-Holm":
# Bonferroni-Holm correction
values = [(pvalue, i) for i, pvalue in enumerate(pvalues)]
values.sort()
for rank, vals in enumerate(values):
pvalue, i = vals
qvalues[i] = (sample_size-rank) * pvalue
elif correction_type == "FDR":
# Benjamini-Hochberg, AKA - FDR test
values = [(pvalue, i) for i, pvalue in enumerate(pvalues)]
values.sort()
values.reverse()
new_values = []
for i, vals in enumerate(values):
rank = sample_size - i
pvalue, index = vals
new_values.append((sample_size/rank) * pvalue)
for i in range(0, int(sample_size)-1):
if new_values[i] < new_values[i+1]:
new_values[i+1] = new_values[i]
for i, vals in enumerate(values):
pvalue, index = vals
qvalues[index] = new_values[i]
return qvalues