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