bpp-core3  3.0.0
DataTable.cpp
Go to the documentation of this file.
1 //
2 // File: DataTable.cpp
3 // Authors:
4 // Julien Dutheil
5 // Created: 2005-08-07 00:00:00
6 //
7 
8 /*
9  Copyright or © or Copr. Bio++ Development Team, (November 17, 2004)
10 
11  This software is a computer program whose purpose is to provide classes
12  for numerical calculus.
13 
14  This software is governed by the CeCILL license under French law and
15  abiding by the rules of distribution of free software. You can use,
16  modify and/ or redistribute the software under the terms of the CeCILL
17  license as circulated by CEA, CNRS and INRIA at the following URL
18  "http://www.cecill.info".
19 
20  As a counterpart to the access to the source code and rights to copy,
21  modify and redistribute granted by the license, users are provided only
22  with a limited warranty and the software's author, the holder of the
23  economic rights, and the successive licensors have only limited
24  liability.
25 
26  In this respect, the user's attention is drawn to the risks associated
27  with loading, using, modifying and/or developing or reproducing the
28  software by the user in light of its specific status of free software,
29  that may mean that it is complicated to manipulate, and that also
30  therefore means that it is reserved for developers and experienced
31  professionals having in-depth computer knowledge. Users are therefore
32  encouraged to load and test the software's suitability as regards their
33  requirements in conditions enabling the security of their systems and/or
34  data to be ensured and, more generally, to use and operate it in the
35  same conditions as regards security.
36 
37  The fact that you are presently reading this means that you have had
38  knowledge of the CeCILL license and that you accept its terms.
39 */
40 
41 
42 #include "../Io/FileTools.h"
43 #include "../Text/StringTokenizer.h"
44 #include "../Text/TextTools.h"
45 #include "DataTable.h"
46 #include "VectorTools.h"
47 
48 using namespace bpp;
49 using namespace std;
50 
51 /******************************************************************************/
52 
53 DataTable::DataTable(size_t nRow, size_t nCol) :
54  nRow_(nRow),
55  nCol_(nCol),
56  data_(nCol),
57  rowNames_(0),
58  colNames_(0)
59 {
60  for (size_t i = 0; i < nCol; i++)
61  {
62  data_[i].resize(nRow);
63  }
64 }
65 
66 DataTable::DataTable(size_t nCol) :
67  nRow_(0),
68  nCol_(nCol),
69  data_(nCol),
70  rowNames_(0),
71  colNames_(0)
72 {}
73 
74 DataTable::DataTable(size_t nRow, const std::vector<std::string>& colNames) :
75  nRow_(nRow),
76  nCol_(colNames.size()),
77  data_(colNames.size()),
78  rowNames_(0),
79  colNames_(0)
80 {
81  for (size_t i = 0; i < nCol_; i++)
82  {
83  data_[i].resize(nRow);
84  }
85 
86  setColumnNames(colNames); // May throw an exception.
87 }
88 
89 DataTable::DataTable(const std::vector<std::string>& colNames) :
90  nRow_(0),
91  nCol_(colNames.size()),
92  data_(colNames.size()),
93  rowNames_(0),
94  colNames_(0)
95 
96 {
97  setColumnNames(colNames); // May throw an exception.
98 }
99 
101  nRow_(table.nRow_),
102  nCol_(table.nCol_),
103  data_(table.data_),
104  rowNames_(0),
105  colNames_(0)
106 {
107  if (table.rowNames_)
108  rowNames_ = new vector<string>(*table.rowNames_);
109  if (table.colNames_)
110  colNames_ = new vector<string>(*table.colNames_);
111 }
112 
114 {
115  nRow_ = table.nRow_;
116  nCol_ = table.nCol_;
117  data_ = table.data_;
118  if (rowNames_)
119  delete rowNames_;
120  if (colNames_)
121  delete colNames_;
122  rowNames_ = 0;
123  colNames_ = 0;
124  if (table.rowNames_)
125  rowNames_ = new vector<string>(*table.rowNames_);
126  if (table.colNames_)
127  colNames_ = new vector<string>(*table.colNames_);
128  return *this;
129 }
130 
131 /******************************************************************************/
132 
134 {
135  if (rowNames_ != NULL)
136  delete rowNames_;
137  if (colNames_ != NULL)
138  delete colNames_;
139 }
140 
141 /******************************************************************************/
142 /* Cell access */
143 /******************************************************************************/
144 
145 string& DataTable::operator()(size_t rowIndex, size_t colIndex)
146 {
147  if (colIndex >= nCol_)
148  throw IndexOutOfBoundsException("DataTable::operator(size_t, size_t).", colIndex, 0, nCol_ - 1);
149  if (rowIndex >= data_[colIndex].size())
150  throw IndexOutOfBoundsException("DataTable::operator(size_t, size_t).", rowIndex, 0, data_[colIndex].size() - 1);
151  return data_[colIndex][rowIndex];
152 }
153 
154 const string& DataTable::operator()(size_t rowIndex, size_t colIndex) const
155 {
156  if (colIndex >= nCol_)
157  throw IndexOutOfBoundsException("DataTable::operator(size_t, size_t).", colIndex, 0, nCol_ - 1);
158  if (rowIndex >= data_[colIndex].size())
159  throw IndexOutOfBoundsException("DataTable::operator(size_t, size_t).", rowIndex, 0, data_[colIndex].size() - 1);
160  return data_[colIndex][rowIndex];
161 }
162 
163 /******************************************************************************/
164 
165 string& DataTable::operator()(const string& rowName, const string& colName)
166 {
167  if (rowNames_ == NULL)
168  throw NoTableRowNamesException("DataTable::operator(const string &, const string &).");
169  if (colNames_ == NULL)
170  throw NoTableColumnNamesException("DataTable::operator(const string &, const string &).");
171  try
172  {
173  size_t rowIndex = VectorTools::which(*rowNames_, rowName);
174  size_t colIndex = VectorTools::which(*colNames_, colName);
175  return (*this)(rowIndex, colIndex);
176  }
178  {
179  throw TableNameNotFoundException("DataTable::operator(const string &, const string &).", *ex.getElement());
180  }
181 }
182 
183 const string& DataTable::operator()(const string& rowName, const string& colName) const
184 {
185  if (rowNames_ == NULL)
186  throw NoTableRowNamesException("DataTable::operator(const string &, const string &).");
187  if (colNames_ == NULL)
188  throw NoTableColumnNamesException("DataTable::operator(const string &, const string &).");
189  try
190  {
191  size_t rowIndex = VectorTools::which(*rowNames_, rowName);
192  size_t colIndex = VectorTools::which(*colNames_, colName);
193  return (*this)(rowIndex, colIndex);
194  }
196  {
197  throw TableNameNotFoundException("DataTable::operator(const string &, const string &).", *ex.getElement());
198  }
199 }
200 
201 /******************************************************************************/
202 
203 string& DataTable::operator()(const string& rowName, size_t colIndex)
204 {
205  if (rowNames_ == NULL)
206  throw NoTableRowNamesException("DataTable::operator(const string &, size_t).");
207  if (colIndex >= nCol_)
208  throw IndexOutOfBoundsException("DataTable::operator(const string &, size_t).", colIndex, 0, nCol_ - 1);
209  try
210  {
211  size_t rowIndex = VectorTools::which(*rowNames_, rowName);
212  return (*this)(rowIndex, colIndex);
213  }
215  {
216  throw TableNameNotFoundException("DataTable::operator(const string &, size_t).", *ex.getElement());
217  }
218 }
219 
220 const string& DataTable::operator()(const string& rowName, size_t colIndex) const
221 {
222  if (rowNames_ == NULL)
223  throw NoTableRowNamesException("DataTable::operator(const string &, size_t).");
224  if (colIndex >= nCol_)
225  throw IndexOutOfBoundsException("DataTable::operator(const string &, size_t).", colIndex, 0, nCol_ - 1);
226  try
227  {
228  size_t rowIndex = VectorTools::which(*rowNames_, rowName);
229  return (*this)(rowIndex, colIndex);
230  }
232  {
233  throw TableNameNotFoundException("DataTable::operator(const string &, size_t).", *ex.getElement());
234  }
235 }
236 
237 /******************************************************************************/
238 
239 string& DataTable::operator()(size_t rowIndex, const string& colName)
240 {
241  if (colNames_ == NULL)
242  throw NoTableColumnNamesException("DataTable::operator(size_t, const string &).");
243  try
244  {
245  size_t colIndex = VectorTools::which(*colNames_, colName);
246  if (rowIndex >= data_[colIndex].size())
247  throw IndexOutOfBoundsException("DataTable::operator(size_t, const string &).", rowIndex, 0, data_[colIndex].size() - 1);
248  return (*this)(rowIndex, colIndex);
249  }
251  {
252  throw TableNameNotFoundException("DataTable::operator(const string &, const string &).", *ex.getElement());
253  }
254 }
255 
256 const string& DataTable::operator()(size_t rowIndex, const string& colName) const
257 {
258  if (colNames_ == NULL)
259  throw NoTableColumnNamesException("DataTable::operator(size_t, const string &).");
260  try
261  {
262  size_t colIndex = VectorTools::which(*colNames_, colName);
263  if (rowIndex >= data_[colIndex].size())
264  throw IndexOutOfBoundsException("DataTable::operator(size_t, const string &).", rowIndex, 0, data_[colIndex].size() - 1);
265  return (*this)(rowIndex, colIndex);
266  }
268  {
269  throw TableNameNotFoundException("DataTable::operator(const string &, const string &).", *ex.getElement());
270  }
271 }
272 
273 /******************************************************************************/
274 /* Work with names */
275 /******************************************************************************/
276 
277 void DataTable::setRowNames(const vector<string>& rowNames)
278 {
279  if (!VectorTools::isUnique(rowNames))
280  {
281  throw DuplicatedTableRowNameException("DataTable::setRowNames(...). Row names must be unique.");
282  }
283  if (rowNames.size() != nRow_)
284  throw DimensionException("DataTable::setRowNames.", rowNames.size(), nRow_);
285  else
286  {
287  if (rowNames_ != NULL)
288  delete rowNames_;
289  rowNames_ = new vector<string>(rowNames.begin(), rowNames.end());
290  }
291 }
292 
293 void DataTable::setRowName(size_t rowId, const string& rowName)
294 {
295  if (VectorTools::contains(*rowNames_, rowName))
296  {
297  throw DuplicatedTableRowNameException("DataTable::setRowName(...). New row name " + rowName + " already exists");
298  }
299  if (rowId >= nRow_)
300  throw DimensionException("DataTable::setRowName.", rowId, nRow_);
301  else
302  {
303  (*rowNames_)[rowId] = rowName;
304  }
305 }
306 
307 vector<string> DataTable::getRowNames() const
308 {
309  if (rowNames_ == NULL)
310  throw NoTableRowNamesException("DataTable::getRowNames().");
311  return *rowNames_;
312 }
313 
314 string DataTable::getRowName(size_t index) const
315 {
316  if (rowNames_ == NULL)
317  throw NoTableRowNamesException("DataTable::getRowName(size_t).");
318  if (index >= nRow_)
319  throw IndexOutOfBoundsException("DataTable::getRowName(size_t).", index, 0, nRow_ - 1);
320  return (*rowNames_)[index];
321 }
322 
323 /******************************************************************************/
324 
325 void DataTable::setColumnNames(const vector<string>& colNames)
326 {
327  if (!VectorTools::isUnique(colNames))
328  throw DuplicatedTableColumnNameException("DataTable::setColumnNames(...). Column names must be unique.");
329  if (colNames.size() != nCol_)
330  throw DimensionException("DataTable::setColumnNames.", colNames.size(), nCol_);
331  else
332  {
333  if (colNames_ != NULL)
334  delete colNames_;
335  colNames_ = new vector<string>(colNames.begin(), colNames.end());
336  }
337 }
338 
339 vector<string> DataTable::getColumnNames() const
340 {
341  if (colNames_ == NULL)
342  throw NoTableColumnNamesException("DataTable::getColumnNames().");
343  return *colNames_;
344 }
345 
346 string DataTable::getColumnName(size_t index) const
347 {
348  if (colNames_ == NULL)
349  throw NoTableColumnNamesException("DataTable::getColumnName(size_t).");
350  if (index >= nCol_)
351  throw IndexOutOfBoundsException("DataTable::getColumnName(size_t).", index, 0, nCol_ - 1);
352  return (*colNames_)[index];
353 }
354 
355 /******************************************************************************/
356 /* Work on columns */
357 /******************************************************************************/
358 
359 vector<string>& DataTable::getColumn(size_t index)
360 {
361  if (index >= nCol_)
362  throw IndexOutOfBoundsException("DataTable::getColumn(size_t).", index, 0, nCol_ - 1);
363  return data_[index];
364 }
365 
366 const vector<string>& DataTable::getColumn(size_t index) const
367 {
368  if (index >= nCol_)
369  throw IndexOutOfBoundsException("DataTable::getColumn(size_t).", index, 0, nCol_ - 1);
370  return data_[index];
371 }
372 
373 vector<string>& DataTable::getColumn(const string& colName)
374 {
375  if (colNames_ == NULL)
376  throw NoTableColumnNamesException("DataTable::getColumn(const string &).");
377  try
378  {
379  size_t colIndex = VectorTools::which(*colNames_, colName);
380  return data_[colIndex];
381  }
383  {
384  throw TableColumnNameNotFoundException("DataTable::getColumn(const string &).", colName);
385  }
386 }
387 
388 const vector<string>& DataTable::getColumn(const string& colName) const
389 {
390  if (colNames_ == NULL)
391  throw NoTableColumnNamesException("DataTable::getColumn(const string &).");
392  try
393  {
394  size_t colIndex = VectorTools::which(*colNames_, colName);
395  return data_[colIndex];
396  }
398  {
399  throw TableColumnNameNotFoundException("DataTable::getColumn(const string &).", colName);
400  }
401 }
402 
403 bool DataTable::hasColumn(const string& colName) const
404 {
405  if (colNames_ == NULL)
406  return false;
407  for (size_t i = 0; i < colNames_->size(); i++)
408  {
409  if ((*colNames_)[i] == colName)
410  return true;
411  }
412  return false;
413 }
414 
415 void DataTable::deleteColumn(size_t index)
416 {
417  if (index >= nCol_)
418  throw IndexOutOfBoundsException("DataTable::deleteColumn(size_t).", index, 0, nCol_ - 1);
419  data_.erase(data_.begin() + static_cast<ptrdiff_t>(index));
420  if (colNames_)
421  colNames_->erase(colNames_->begin() + static_cast<ptrdiff_t>(index));
422  nCol_--;
423 }
424 
425 void DataTable::deleteColumn(const string& colName)
426 {
427  if (!colNames_)
428  throw NoTableColumnNamesException("DataTable::deleteColumn(const string &).");
429  try
430  {
431  size_t colIndex = VectorTools::which(*colNames_, colName);
432  data_.erase(data_.begin() + static_cast<ptrdiff_t>(colIndex));
433  colNames_->erase(colNames_->begin() + static_cast<ptrdiff_t>(colIndex));
434  nCol_--;
435  }
437  {
438  throw TableColumnNameNotFoundException("DataTable::deleteColumn(const string &).", colName);
439  }
440 }
441 
442 void DataTable::addColumn(const vector<string>& newColumn)
443 {
444  if (colNames_)
445  throw TableColumnNamesException("DataTable::addColumn. Table has column names.");
446  if (newColumn.size() != nRow_)
447  throw DimensionException("DataTable::addColumn.", newColumn.size(), nRow_);
448  data_.push_back(newColumn);
449  nCol_++;
450 }
451 
452 void DataTable::addColumn(const string& colName, const vector<string>& newColumn)
453 {
454  if (!colNames_)
455  {
456  if (nCol_ == 0)
457  colNames_ = new vector<string>();
458  else
459  throw NoTableColumnNamesException("DataTable::addColumn. Table has column names.");
460  }
461  if (newColumn.size() != nRow_)
462  throw DimensionException("DataTable::addColumn.", newColumn.size(), nRow_);
463  if (nCol_ > 0 && find(colNames_->begin(), colNames_->end(), colName) != colNames_->end())
464  throw DuplicatedTableColumnNameException("DataTable::addColumn(const string &, const vector<string> &). Column names must be unique.");
465  colNames_->push_back(colName);
466  data_.push_back(newColumn);
467  nCol_++;
468 }
469 
470 /******************************************************************************/
471 /* Work on rows */
472 /******************************************************************************/
473 
474 vector<string> DataTable::getRow(size_t index) const
475 {
476  if (index >= nRow_)
477  throw IndexOutOfBoundsException("DataTable::getRow(size_t).", index, 0, nRow_ - 1);
478  vector<string> row;
479  for (size_t i = 0; i < nCol_; i++)
480  {
481  row.push_back(data_[i][index]);
482  }
483  return row;
484 }
485 
486 vector<string> DataTable::getRow(const string& rowName) const
487 {
488  if (!rowNames_)
489  throw NoTableRowNamesException("DataTable::getRow(const string &).");
490  try
491  {
492  size_t rowIndex = VectorTools::which(*rowNames_, rowName);
493  vector<string> row;
494  for (size_t i = 0; i < nCol_; i++)
495  {
496  row.push_back(data_[i][rowIndex]);
497  }
498  return row;
499  }
501  {
502  throw TableRowNameNotFoundException("DataTable::getRow(const string &).", rowName);
503  }
504 }
505 
506 bool DataTable::hasRow(const string& rowName) const
507 {
508  if (rowNames_ == NULL)
509  return false;
510  for (size_t i = 0; i < rowNames_->size(); i++)
511  {
512  if ((*rowNames_)[i] == rowName)
513  return true;
514  }
515  return false;
516 }
517 
518 void DataTable::deleteRow(size_t index)
519 {
520  for (size_t j = 0; j < nCol_; j++)
521  {
522  vector<string>* column = &data_[j];
523  if (index >= column->size())
524  throw IndexOutOfBoundsException("DataTable::deleteRow(size_t).", index, 0, column->size() - 1);
525  column->erase(column->begin() + static_cast<ptrdiff_t>(index));
526  }
527  if (rowNames_)
528  rowNames_->erase(rowNames_->begin() + static_cast<ptrdiff_t>(index));
529  nRow_--;
530 }
531 
532 void DataTable::deleteRow(const string& rowName)
533 {
534  if (!rowNames_)
535  throw NoTableRowNamesException("DataTable::deleteRow(const string &).");
536  try
537  {
538  size_t rowIndex = VectorTools::which(*rowNames_, rowName);
539  for (size_t j = 0; j < nCol_; j++)
540  {
541  vector<string>* column = &data_[j];
542  column->erase(column->begin() + static_cast<ptrdiff_t>(rowIndex));
543  }
544  rowNames_->erase(rowNames_->begin() + static_cast<ptrdiff_t>(rowIndex));
545  nRow_--;
546  }
548  {
549  throw TableRowNameNotFoundException("DataTable::deleteRow(const string &).", rowName);
550  }
551 }
552 
553 void DataTable::addRow(const vector<string>& newRow)
554 {
555  if (rowNames_)
556  throw TableRowNamesException("DataTable::addRow. Table has row names.");
557  if (newRow.size() != nCol_)
558  throw DimensionException("DataTable::addRow.", newRow.size(), nCol_);
559  for (size_t j = 0; j < nCol_; j++)
560  {
561  data_[j].push_back(newRow[j]);
562  }
563  nRow_++;
564 }
565 
566 void DataTable::setRow(size_t rowIndex, const vector<string>& newRow)
567 {
568  if (rowIndex >= nRow_)
569  throw DimensionException("DataTable::setRow.", rowIndex, nRow_);
570  if (newRow.size() != nCol_)
571  throw DimensionException("DataTable::setRow.", newRow.size(), nCol_);
572 
573  for (size_t j = 0; j < nCol_; j++)
574  {
575  data_[j][rowIndex] = newRow[j];
576  }
577 }
578 
579 void DataTable::addRow(const string& rowName, const vector<string>& newRow)
580 {
581  if (!rowNames_)
582  {
583  if (nRow_ == 0)
584  rowNames_ = new vector<string>();
585  else
586  throw NoTableRowNamesException("DataTable::addRow. Table has row names.");
587  }
588  if (newRow.size() != nCol_)
589  throw DimensionException("DataTable::addRow.", newRow.size(), nCol_);
590  if (nRow_ > 0 && find(rowNames_->begin(), rowNames_->end(), rowName) != rowNames_->end())
591  throw DuplicatedTableRowNameException("DataTable::addRow(const string &, const vector<string> &). Row names must be unique.");
592  rowNames_->push_back(rowName);
593  for (size_t j = 0; j < nCol_; j++)
594  {
595  data_[j].push_back(newRow[j]);
596  }
597  nRow_++;
598 }
599 
600 /******************************************************************************/
601 /* Read from a CSV file */
602 /******************************************************************************/
603 
604 DataTable* DataTable::read(istream& in, const string& sep, bool header, int rowNames)
605 {
606  string firstLine = FileTools::getNextLine(in);
607  StringTokenizer st1(firstLine, sep, false, true);
608  vector<string> row1(st1.getTokens().begin(), st1.getTokens().end());
609  string secondLine = FileTools::getNextLine(in);
610  StringTokenizer st2(secondLine, sep, false, true);
611  vector<string> row2(st2.getTokens().begin(), st2.getTokens().end());
612  size_t nCol = row1.size();
613  bool hasRowNames;
614  DataTable* dt;
615  if (row1.size() == row2.size())
616  {
617  dt = new DataTable(nCol);
618  if (header)
619  { // Use first line as header.
620  dt->setColumnNames(row1);
621  }
622  else
623  {
624  dt->addRow(row1);
625  }
626  dt->addRow(row2);
627  hasRowNames = false;
628  }
629  else if (row1.size() == row2.size() - 1)
630  {
631  dt = new DataTable(nCol);
632  dt->setColumnNames(row1);
633  string rowName = *row2.begin();
634  dt->addRow(rowName, vector<string>(row2.begin() + 1, row2.end()));
635  hasRowNames = true;
636  }
637  else
638  throw DimensionException("DataTable::read(...). Row 2 has not the correct number of columns.", row2.size(), nCol);
639 
640  // Now read each line:
641  string line = FileTools::getNextLine(in);
642  while (!TextTools::isEmpty(line))
643  {
644  StringTokenizer st(line, sep, false, true);
645  if (hasRowNames)
646  {
647  string rowName = *st.getTokens().begin();
648  vector<string> row(st.getTokens().begin() + 1, st.getTokens().end());
649  dt->addRow(rowName, row);
650  }
651  else
652  {
653  vector<string> row(st.getTokens().begin(), st.getTokens().end());
654  dt->addRow(row);
655  }
656  line = FileTools::getNextLine(in);
657  }
658 
659  // Row names:
660  if (rowNames > -1)
661  {
662  if (static_cast<size_t>(rowNames) >= nCol)
663  throw IndexOutOfBoundsException("DataTable::read(...). Invalid column specified for row names.", static_cast<size_t>(rowNames), 0, nCol - 1);
664  vector<string> col = dt->getColumn(static_cast<size_t>(rowNames));
665  dt->setRowNames(col);
666  dt->deleteColumn(static_cast<size_t>(rowNames));
667  }
668 
669  return dt;
670 }
671 
672 /******************************************************************************/
673 
674 void DataTable::write(const DataTable& data, ostream& out, const string& sep, bool alignHeaders)
675 {
676  size_t n = data.getNumberOfColumns();
677  if (n == 0)
678  return;
679  if (data.hasColumnNames())
680  { // Write header
681  vector<string> colNames = data.getColumnNames();
682  if (alignHeaders && data.hasRowNames())
683  out << sep;
684  out << colNames[0];
685  for (size_t i = 1; i < n; i++)
686  {
687  out << sep << colNames[i];
688  }
689  out << endl;
690  }
691  // Now write each row:
692  for (size_t i = 0; i < data.getNumberOfRows(); i++)
693  {
694  if (data.hasRowNames())
695  out << data.getRowName(i) << sep;
696  out << data(i, 0);
697  for (size_t j = 1; j < n; j++)
698  {
699  out << sep << data(i, j);
700  }
701  out << endl;
702  }
703 }
704 
705 void DataTable::write(const DataTable& data, bpp::OutputStream& out, const string& sep, bool alignHeaders)
706 {
707  size_t n = data.getNumberOfColumns();
708  if (n == 0)
709  return;
710  if (data.hasColumnNames())
711  { // Write header
712  vector<string> colNames = data.getColumnNames();
713  if (alignHeaders && data.hasRowNames())
714  out << sep;
715  out << colNames[0];
716  for (size_t i = 1; i < n; i++)
717  {
718  out << sep << colNames[i];
719  }
720  out.endLine();
721  }
722  // Now write each row:
723  for (size_t i = 0; i < data.getNumberOfRows(); i++)
724  {
725  if (data.hasRowNames())
726  out << data.getRowName(i) << sep;
727  out << data(i, 0);
728  for (size_t j = 1; j < n; j++)
729  {
730  out << sep << data(i, j);
731  }
732  out.endLine();
733  }
734 }
735 
736 /******************************************************************************/
This class corresponds to a 'dataset', i.e. a table with data by rows and variable by columns.
Definition: DataTable.h:67
bool hasRow(const std::string &rowName) const
Tell is a given row exists.
Definition: DataTable.cpp:506
std::vector< std::string > * rowNames_
Definition: DataTable.h:71
void deleteRow(size_t index)
Delete the given row.
Definition: DataTable.cpp:518
DataTable(size_t nRow, size_t nCol)
Build a new void DataTable object with nRow rows and nCol columns.
Definition: DataTable.cpp:53
void deleteColumn(size_t index)
Delete the given column.
Definition: DataTable.cpp:415
void setRow(const size_t rowIndex, const std::vector< std::string > &newRow)
Sets an existing with a given index.
Definition: DataTable.cpp:566
bool hasRowNames() const
Definition: DataTable.h:366
void addColumn(const std::vector< std::string > &newColumn)
Add a new column.
Definition: DataTable.cpp:442
std::string & operator()(size_t rowIndex, size_t colIndex)
Definition: DataTable.cpp:145
size_t nCol_
Definition: DataTable.h:69
void setRowName(size_t rowIndex, const std::string &rowName)
Set the row name of a row with a given index.
Definition: DataTable.cpp:293
std::vector< std::string > * colNames_
Definition: DataTable.h:72
std::vector< std::vector< std::string > > data_
Definition: DataTable.h:70
std::vector< std::string > getRowNames() const
Get the row names of this table.
Definition: DataTable.cpp:307
size_t getNumberOfColumns() const
Definition: DataTable.h:201
virtual ~DataTable()
Definition: DataTable.cpp:133
std::string getColumnName(size_t index) const
Get a given column name.
Definition: DataTable.cpp:346
bool hasColumnNames() const
Definition: DataTable.h:231
std::vector< std::string > getColumnNames() const
Get the column names of this table.
Definition: DataTable.cpp:339
std::vector< std::string > getRow(size_t index) const
Definition: DataTable.cpp:474
std::vector< std::string > & getColumn(size_t index)
Definition: DataTable.cpp:359
static DataTable * read(std::istream &in, const std::string &sep="\t", bool header=true, int rowNames=-1)
Read a table form a stream in CSV-like format.
Definition: DataTable.cpp:604
static void write(const DataTable &data, std::ostream &out, const std::string &sep="\t", bool alignHeaders=false)
Write a DataTable object to stream in CVS-like format.
Definition: DataTable.cpp:674
size_t nRow_
Definition: DataTable.h:69
DataTable & operator=(const DataTable &table)
Definition: DataTable.cpp:113
void addRow(const std::vector< std::string > &newRow)
Add a new row.
Definition: DataTable.cpp:553
std::string getRowName(size_t index) const
Get a given row name.
Definition: DataTable.cpp:314
size_t getNumberOfRows() const
Definition: DataTable.h:315
void setColumnNames(const std::vector< std::string > &colNames)
Set the column names of this table.
Definition: DataTable.cpp:325
bool hasColumn(const std::string &colName) const
Tell is a given column exists.
Definition: DataTable.cpp:403
void setRowNames(const std::vector< std::string > &rowNames)
Set the row names of this table.
Definition: DataTable.cpp:277
Exception thrown when a dimension problem occured.
Excpetion thrown when attempting to duplicate a column name.
Exception thrown when attempting to duplicate a row name.
Exception thrown when a given element was not found in the vector.
static std::string getNextLine(std::istream &in)
Get the next non-blanck line of a stream.
Definition: FileTools.cpp:145
Index out of bounds exception class.
Definition: Exceptions.h:170
Exception thrown when trying to retrieve a column by its name and no column names have been specified...
Exception thrown when trying to retrieve a row by its name and no row names have been specified.
OutputStream interface.
Definition: OutputStream.h:67
virtual OutputStream & endLine()=0
A tokenizer for strings.
const std::deque< std::string > & getTokens() const
Retrieve all tokens.
Exception thrown when a given column name is not found is a DataTable object.
General exception class dealing with column names.
Exception thrown when a given name is not found is a DataTable object.
Exception thrown when a given row name is not found is a DataTable object.
General exception class dealing with row names.
static bool isUnique(const std::vector< T > &v)
Tell if the std::vector as unique elements.
Definition: VectorTools.h:508
static size_t which(const std::vector< T > &v, const T &which)
Send the position of the first occurence of 'which'.
Definition: VectorTools.h:439
static bool contains(const std::vector< T > &vec, T el)
Definition: VectorTools.h:1803
bool isEmpty(const std::string &s)
Tell if a string is empty. A string is considered to be 'empty' if it is only made of white spaces.
Definition: TextTools.cpp:58