5 #ifndef BPP_NUMERIC_TABLE_H 6 #define BPP_NUMERIC_TABLE_H 9 #include "../Clonable.h" 35 std::vector< std::vector<T>>
data_;
47 Table(
size_t nRow,
size_t nCol) :
54 for (
size_t i = 0; i < nCol; ++i)
56 data_[i].resize(nRow);
67 Table(
const std::vector<std::string>& colNames) :
69 nCol_(colNames.size()),
70 data_(colNames.size()),
82 rowNames_(table.rowNames_),
83 colNames_(table.colNames_)
86 Table(
const std::vector<std::vector<T>>& vt) :
87 nRow_(vt.size() == 0 ? 0 : vt[0].size()),
114 nRow_ = vt[0].size();
132 const std::vector< std::vector<T>>&
getData()
const 146 if (colIndex >= nCol_)
148 if (rowIndex >= data_[colIndex].size())
150 return data_[colIndex][rowIndex];
161 if (colIndex >= nCol_)
163 if (rowIndex >= data_[colIndex].size())
165 return data_[colIndex][rowIndex];
176 T&
operator()(
const std::string& rowName,
const std::string& colName)
178 if (rowNames_.size() == 0)
180 if (colNames_.size() == 0)
186 return (*
this)(rowIndex, colIndex);
203 const T&
operator()(
const std::string& rowName,
const std::string& colName)
const 205 if (rowNames_.size() == 0)
207 if (colNames_.size() == 0)
213 return (*
this)(rowIndex, colIndex);
232 if (rowNames_.size() == 0)
234 if (colIndex >= nCol_)
239 return (*
this)(rowIndex, colIndex);
256 const T&
operator()(
const std::string& rowName,
size_t colIndex)
const 258 if (rowNames_.size() == 0)
260 if (colIndex >= nCol_)
265 return (*
this)(rowIndex, colIndex);
284 if (colNames_.size() == 0)
289 if (rowIndex >= data_[colIndex].size())
291 return (*
this)(rowIndex, colIndex);
308 const T&
operator()(
size_t rowIndex,
const std::string& colName)
const 310 if (colNames_.size() == 0)
315 if (rowIndex >= data_[colIndex].size())
317 return (*
this)(rowIndex, colIndex);
347 if (colNames.size() !=
nCol_)
351 colNames_ = colNames;
362 if (colNames_.size() == 0)
369 if (colNames_.size() == 0)
384 if (colNames_.size() == 0)
388 return colNames_[index];
430 if (colNames_.size() == 0)
435 return data_[colIndex];
449 const std::vector<T>&
getColumn(
const std::string& colName)
const 451 if (colNames_.size() == 0)
456 return data_[colIndex];
473 if (colNames_.size() == 0)
475 for (
size_t i = 0; i < colNames_.size(); i++)
477 if ((colNames_)[i] == colName)
494 data_.erase(data_.begin() + (long)index);
495 if (colNames_.size() != 0)
496 colNames_.erase(colNames_.begin() + (long)(index));
511 if (index + len >= nCol_)
514 data_.erase(data_.begin() + (long)index, data_.begin() + (long)(index + len));
515 if (colNames_.size() != 0)
516 colNames_.erase(colNames_.begin() + (long)(index), colNames_.begin() + (long)(index + len));
530 if ((colNames_.size() == 0))
535 data_.erase(data_.begin() + (size_t)(colIndex));
536 colNames_.erase(colNames_.begin() + (size_t)(colIndex));
554 void addColumn(
const std::vector<T>& newColumn,
int pos = -1)
556 if (pos > (
int)nCol_)
561 if (colNames_.size())
563 if (newColumn.size() !=
nRow_)
566 data_.insert(data_.begin() + pos, newColumn);
580 void addColumn(
const std::string& colName,
const std::vector<T>& newColumn,
int pos = -1)
582 if (pos > (
int)nCol_)
587 if ((colNames_.size() == 0) && (nCol_ != 0))
590 if (newColumn.size() !=
nRow_)
592 if (nCol_ > 0 && find(colNames_.begin(), colNames_.end(), colName) != colNames_.end())
595 colNames_.insert(colNames_.begin() + pos, colName);
596 data_.insert(data_.begin() + pos, newColumn);
609 void addColumn(std::string& st,
const std::string& sep =
"\t",
int pos = -1,
int rowCol = -1)
611 if (pos > (
int)nCol_)
619 if (row.size() != nRow_ + (rowCol >= 0) ? 1 : 0)
622 std::vector<T> newColumn;
624 for (
size_t i = 0; i < row.size(); i++)
626 if ((
int)i == rowCol)
628 std::string colName = row[i];
629 if (find(colNames_.begin(), colNames_.end(), colName) != colNames_.end())
632 colNames_.insert(colNames_.begin() + (long)pos, colName);
636 std::stringstream ss(row[i]);
639 newColumn.push_back(t);
642 data_.insert(data_.begin() + pos, newColumn);
656 void setColumn(
const std::vector<T>& newColumn,
size_t pos)
661 if (newColumn.size() !=
nRow_)
664 data_[pos] = newColumn;
677 void setColumn(
const std::string& colName,
const std::vector<T>& newColumn,
size_t pos)
682 if (colNames_.size() == 0)
685 if (newColumn.size() !=
nRow_)
688 if (find(colNames_.begin(), colNames_.end(), colName) != colNames_.end() &&
689 find(colNames_.begin(), colNames_.end(), colName) != colNames_.begin() + pos)
692 colNames_[pos] = colName;
693 data_[pos] = newColumn;
722 if (rowNames.size() !=
nRow_)
726 rowNames_ = rowNames;
739 if (rowNames_.size() == 0)
746 if (rowNames_.size() == 0)
758 bool hasRow(
const std::string& rowName)
const 760 if (rowNames_.size() == 0)
762 for (
size_t i = 0; i < rowNames_.size(); i++)
764 if ((rowNames_)[i] == rowName)
781 if (rowNames_.size() == 0)
785 return (rowNames_)[index];
799 std::vector<T>
getRow(
size_t index)
const 804 for (
size_t i = 0; i <
nCol_; i++)
806 row.push_back(data_[i][index]);
818 std::vector<T>
getRow(
const std::string& rowName)
const 820 if ((rowNames_.size() == 0))
826 for (
size_t i = 0; i <
nCol_; i++)
828 row.push_back(data_[i][rowIndex]);
847 for (
size_t j = 0; j <
nCol_; j++)
849 std::vector<T>* column = &data_[j];
850 if (index >= column->size())
852 column->erase(column->begin() + index);
854 if (rowNames_.size() != 0)
855 rowNames_.erase(rowNames_.begin() + index);
868 for (
size_t j = 0; j <
nCol_; j++)
870 std::vector<T>* column = &data_[j];
871 if (index >= column->size())
873 column->erase(column->begin() + (long)index, column->begin() + long(index + len));
875 if (rowNames_.size() != 0)
876 rowNames_.erase(rowNames_.begin() + long(index), rowNames_.begin() + long(index + len));
890 if ((rowNames_.size() == 0))
895 for (
size_t j = 0; j <
nCol_; j++)
897 std::vector<T>* column = &data_[j];
898 column->erase(column->begin() + rowIndex);
900 rowNames_.erase(rowNames_.begin() + rowIndex);
916 void addRow(
const std::vector<T>& newRow,
int pos = -1)
918 if (pos > (
int)nRow_)
924 if (rowNames_.size() != 0)
926 if (newRow.size() !=
nCol_)
928 for (
size_t j = 0; j <
nCol_; j++)
930 data_[j].insert(data_[j].begin() + (
size_t)pos, newRow[j]);
942 void addRow(
const std::string& rowName,
const std::vector<T>& newRow,
int pos = -1)
944 if (pos > (
int)nRow_)
949 if ((rowNames_.size() == 0) && (nRow_ != 0))
952 if (newRow.size() !=
nCol_)
954 if (nRow_ > 0 && find(rowNames_.begin(), rowNames_.end(), rowName) != rowNames_.end())
956 rowNames_.insert(rowNames_.begin() + (size_t)pos, rowName);
957 for (
size_t j = 0; j <
nCol_; j++)
959 data_[j].insert(data_[j].begin() + (
size_t)pos, newRow[j]);
973 void addRow(std::string& st,
const std::string& sep =
"\t",
int pos = -1,
int rowCol = -1)
975 if (pos > (
int)nRow_)
983 if (row.size() != nCol_ + (rowCol >= 0) ? 1 : 0)
988 for (
size_t i = 0; i < row.size(); i++)
990 if ((
int)i == rowCol)
992 std::string rowName = row[i];
993 if (find(rowNames_.begin(), rowNames_.end(), rowName) != rowNames_.end())
996 rowNames_.insert(rowNames_.begin() + (long)pos, rowName);
1000 std::stringstream ss(row[i]);
1003 data_[id].insert(data_[
id].begin() + (
long)pos, t);
1031 static std::unique_ptr<Table<T>>
read(std::istream& in,
bool byRow,
const std::string& sep =
"\t",
bool header =
true,
int names = -1)
1036 size_t nCol = row1.size();
1037 std::unique_ptr< Table<T>> dt;
1044 dt = std::make_unique<Table<T>>(0, nCol);
1045 dt->setColumnNames(row1);
1049 dt = std::make_unique<Table<T>>(nCol, 0);
1050 dt->setRowNames(row1);
1057 dt = std::make_unique<Table<T>>(0, nCol - (names >= 0 ? 1 : 0));
1058 dt->addRow(firstLine, sep, names);
1062 dt = std::make_unique<Table<T>>(nCol - (names >= 0 ? 1 : 0), 0);
1063 dt->addColumn(firstLine, sep, names);
1073 dt->addRow(line, sep, names);
1075 dt->addColumn(line, sep, names);
1092 static void write(
const Table& data, std::ostream& out,
bool byRow,
const std::string& sep =
"\t",
bool alignHeaders =
false)
1105 if (alignHeaders && frontNames)
1108 for (
size_t i = 1; i < n; ++i)
1110 out << sep << names[i];
1117 for (
size_t i = 0; i < m; ++i)
1124 out << (byRow ? data(i, 0) : data(0, i));
1125 for (
size_t j = 1; j < n; ++j)
1127 out << sep << (byRow ? data(i, j) : data(j, i));
1146 if (alignHeaders && frontNames)
1149 for (
size_t i = 1; i < n; ++i)
1151 out << sep << names[i];
1158 for (
size_t i = 0; i < m; ++i)
1163 out << (byRow ? data(i, 0) : data(0, i));
1164 for (
size_t j = 1; j < n; ++j)
1166 out << sep << (byRow ? data(i, j) : data(j, i));
1173 #endif // BPP_NUMERIC_TABLE_H size_t getNumberOfColumns() const
Table(const std::vector< std::string > &colNames)
Build a new void Table object with named columns.
void deleteRows(size_t index, size_t len)
Delete the given rows.
void addRow(std::string &st, const std::string &sep="\, int pos=-1, int rowCol=-1)
Add a new row.
size_t getNumberOfRows() const
std::vector< T > getRow(const std::string &rowName) const
void addRow(const std::vector< T > &newRow, int pos=-1)
Add a new row.
const T & operator()(size_t rowIndex, size_t colIndex) const
const std::vector< std::string > & getRowNames() const
std::string getRowName(size_t index) const
Get a given row name.
void deleteRow(size_t index)
Delete the given row.
T & operator()(size_t rowIndex, const std::string &colName)
T & operator()(const std::string &rowName, const std::string &colName)
std::vector< T > & getColumn(size_t index)
Table & operator=(const std::vector< std::vector< T >> &vt)
Number exception: integers.
const T & operator()(size_t rowIndex, const std::string &colName) const
void setColumn(const std::vector< T > &newColumn, size_t pos)
Set a new column.
T & operator()(size_t rowIndex, size_t colIndex)
const T * getElement() const
Exception thrown when a given column name is not found is a DataTable object.
static void write(const Table &data, std::ostream &out, bool byRow, const std::string &sep="\, bool alignHeaders=false)
Write a Table object to stream in CSV-like format.
Exception thrown when attempting to duplicate a row name.
const T & operator()(const std::string &rowName, size_t colIndex) const
Exception thrown when trying to retrieve a row by its name and no row names have been specified...
void addColumn(const std::vector< T > &newColumn, int pos=-1)
Add a new column.
Exception thrown when a given element was not found in the vector.
const T & operator()(const std::string &rowName, const std::string &colName) const
Table * clone() const
Create a copy of this object and send a pointer to it.
const std::vector< T > & getColumn(size_t index) const
static void write(const Table &data, bpp::OutputStream &out, bool byRow, const std::string &sep="\, bool alignHeaders=false)
void deleteColumn(const std::string &colName)
Delete the given column.
void deleteColumn(size_t index)
Delete the given column.
void setColumn(const std::string &colName, const std::vector< T > &newColumn, size_t pos)
Set a new column.
std::vector< T > getRow(size_t index) const
bool hasColumn(const std::string &colName) const
Tell is a given column exists.
void addColumn(const std::string &colName, const std::vector< T > &newColumn, int pos=-1)
Add a new column.
Exception thrown when a given row name is not found is a DataTable object.
const std::vector< std::vector< T > > & getData() const
Table(const std::vector< std::vector< T >> &vt)
std::vector< std::vector< T > > data_
void deleteColumns(size_t index, size_t len)
Delete the given columns.
std::vector< T > & getColumn(const std::string &colName)
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.
const std::deque< std::string > & getTokens() const
Retrieve all tokens.
std::vector< std::string > colNames_
const std::vector< T > & getColumn(const std::string &colName) const
virtual OutputStream & endLine()=0
void setRowNames(const std::vector< std::string > &rowNames)
Set the row names of this table.
void addRow(const std::string &rowName, const std::vector< T > &newRow, int pos=-1)
Add a new row at a given position.
Table(size_t nRow, size_t nCol)
Build a new void Table object with nRow rows and nCol columns.
std::vector< std::string > & getColumnNames()
The Clonable interface (allow an object to be cloned).
std::vector< std::string > getRowNames()
Get the row names of this table.
const std::vector< std::string > & getColumnNames() const
Get the column names of this table.
T & operator()(const std::string &rowName, size_t colIndex)
std::string getColumnName(size_t index) const
Get a given column name.
This class corresponds to a 'dataset', i.e. a table with data by rows and variable by columns...
Index out of bounds exception class.
Exception thrown when a given name is not found is a DataTable object.
void addColumn(std::string &st, const std::string &sep="\, int pos=-1, int rowCol=-1)
Add a new column.
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...
void setColumnNames(const std::vector< std::string > &colNames)
Set the column names of this table.
bool hasColumnNames() const
Table & operator=(const Table &table)
Table(const Table &table)
static std::unique_ptr< Table< T > > read(std::istream &in, bool byRow, const std::string &sep="\, bool header=true, int names=-1)
Read a table form a stream in CSV-like.
Exception thrown when a dimension problem occured.
General exception class dealing with column names.
void deleteRow(const std::string &rowName)
Delete the given row.
General exception class dealing with row names.
std::vector< std::string > rowNames_