bpp-core3  3.0.0
ContingencyTableTest.cpp
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: The Bio++ Development Group
2 //
3 // SPDX-License-Identifier: CECILL-2.1
4 
5 #include <algorithm>
6 #include <iostream>
7 
8 #include "../../App/ApplicationTools.h"
9 #include "../Random/ContingencyTableGenerator.h"
10 #include "../Random/RandomTools.h"
11 #include "../VectorTools.h"
12 #include "ContingencyTableTest.h"
13 
14 using namespace bpp;
15 using namespace std;
16 
17 ContingencyTableTest::ContingencyTableTest(const std::vector< std::vector<size_t>>& table, unsigned int nbPermutations, bool warn) :
18  statistic_(0),
19  pvalue_(0),
20  df_(0),
21  margin1_(table.size()),
22  margin2_(0)
23 {
24  // Compute marginals:
25  size_t n = table.size();
26  if (n < 2)
27  throw Exception("ContingencyTableTest. Table size should be at least 2x2!");
28  size_t m = table[0].size();
29  if (m < 2)
30  throw Exception("ContingencyTableTest. Table size should be at least 2x2!");
31  margin2_.resize(m);
32  for (size_t j = 0; j < m; ++j)
33  {
34  margin2_[j] = 0;
35  }
36  bool test = false;
37  for (size_t i = 0; i < n; ++i)
38  {
39  if (table[i].size() != m)
40  throw Exception("ContingencyTableTest. Input array has non-homogeneous dimensions!");
41  for (size_t j = 0; j < m; ++j)
42  {
43  size_t c = table[i][j];
44  if (c <= 5)
45  test = true;
46  margin1_[i] += c;
47  margin2_[j] += c;
48  }
49  }
50  for (size_t i = 0; i < n; ++i)
51  {
52  if (margin1_[i] == 0)
53  throw Exception("ContingencyTableTest. Row " + TextTools::toString(i) + " sums to 0.");
54  }
55  for (size_t j = 0; j < m; ++j)
56  {
57  if (margin2_[j] == 0)
58  throw Exception("ContingencyTableTest. Column " + TextTools::toString(j) + " sums to 0.");
59  }
60 
61 
62  size_t tot = VectorTools::sum(margin1_);
63  df_ = static_cast<double>((m - 1) * (n - 1));
64 
65  RowMatrix<long double> expc(n, m);
66  for (size_t i = 0; i < n; ++i)
67  {
68  for (size_t j = 0; j < m; ++j)
69  {
70  long double c = table[i][j];
71  long double e = static_cast<long double>(margin1_[i] * margin2_[j]) / static_cast<long double>(tot);
72  expc(i, j) = e;
73  statistic_ += static_cast<double>(std::pow(c - e, 2.L) / e);
74  }
75  }
76 
77  if (nbPermutations > 0)
78  {
79  size_t count = 0;
81  for (unsigned int k = 0; k < nbPermutations; ++k)
82  {
83  // Randomize:
84  RowMatrix<size_t> table_rep = ctgen.rcont2();
85  // Recompute statistic:
86  double stat_rep = 0;
87  for (size_t i = 0; i < n; ++i)
88  {
89  for (size_t j = 0; j < m; ++j)
90  {
91  long double c = table_rep(i, j);
92  long double e = expc(i, j);
93  stat_rep += static_cast<double>(std::pow(c - e, 2.L) / e);
94  }
95  }
96  if (stat_rep >= statistic_)
97  count++;
98  }
99  pvalue_ = static_cast<double>(count + 1) / static_cast<double>(nbPermutations + 1);
100  }
101  else
102  {
103  if (test && warn)
104  ApplicationTools::displayWarning("Unsufficient observations, p-value might be incorrect.");
105 
106  // Compute p-value:
108  }
109 }
static void displayWarning(const std::string &text)
Print a warning message.
static double pChisq(double x, double v)
cumulative probability function.
Definition: RandomTools.h:516
static T sum(const std::vector< T > &v1)
Definition: VectorTools.h:587
std::size_t count(const std::string &s, const std::string &pattern)
Count the occurences of a given pattern in a string.
Definition: TextTools.cpp:388
STL namespace.
std::vector< size_t > margin2_
ContingencyTableTest(const std::vector< std::vector< size_t >> &table, unsigned int nbPermutations=0, bool warn=true)
Build a new test object and perform computations.
Matrix storage by row.
Definition: Matrix.h:92
Exception base class. Overload exception constructor (to control the exceptions mechanism). Destructor is already virtual (from std::exception)
Definition: Exceptions.h:20
Generate a random contingency matrix with given marginal counts.
std::string toString(T t)
General template method to convert to a string.
Definition: TextTools.h:115
std::vector< size_t > margin1_