|
bpp-core
2.1.0
|
00001 // 00002 // File: DataTable.cpp 00003 // Created by: Julien Dutheil 00004 // Created on: Aug 2005 00005 // 00006 00007 /* 00008 Copyright or © or Copr. CNRS, (November 17, 2004) 00009 00010 This software is a computer program whose purpose is to provide classes 00011 for numerical calculus. 00012 00013 This software is governed by the CeCILL license under French law and 00014 abiding by the rules of distribution of free software. You can use, 00015 modify and/ or redistribute the software under the terms of the CeCILL 00016 license as circulated by CEA, CNRS and INRIA at the following URL 00017 "http://www.cecill.info". 00018 00019 As a counterpart to the access to the source code and rights to copy, 00020 modify and redistribute granted by the license, users are provided only 00021 with a limited warranty and the software's author, the holder of the 00022 economic rights, and the successive licensors have only limited 00023 liability. 00024 00025 In this respect, the user's attention is drawn to the risks associated 00026 with loading, using, modifying and/or developing or reproducing the 00027 software by the user in light of its specific status of free software, 00028 that may mean that it is complicated to manipulate, and that also 00029 therefore means that it is reserved for developers and experienced 00030 professionals having in-depth computer knowledge. Users are therefore 00031 encouraged to load and test the software's suitability as regards their 00032 requirements in conditions enabling the security of their systems and/or 00033 data to be ensured and, more generally, to use and operate it in the 00034 same conditions as regards security. 00035 00036 The fact that you are presently reading this means that you have had 00037 knowledge of the CeCILL license and that you accept its terms. 00038 */ 00039 00040 #include "DataTable.h" 00041 #include "VectorTools.h" 00042 #include "../Io/FileTools.h" 00043 #include "../Text/TextTools.h" 00044 #include "../Text/StringTokenizer.h" 00045 00046 using namespace bpp; 00047 using namespace std; 00048 00049 /******************************************************************************/ 00050 00051 DataTable::DataTable(size_t nRow, size_t nCol) : 00052 nRow_(nRow), nCol_(nCol), data_(nCol), rowNames_(0), colNames_(0) 00053 { 00054 for(size_t i = 0; i < nCol; i++) 00055 data_[i].resize(nRow); 00056 } 00057 00058 DataTable::DataTable(size_t nCol) : 00059 nRow_(0), nCol_(nCol), data_(nCol), rowNames_(0), colNames_(0) 00060 { 00061 } 00062 00063 DataTable::DataTable(const std::vector<std::string>& colNames) throw (DuplicatedTableColumnNameException) : 00064 nRow_(0), nCol_(colNames.size()), data_(colNames.size()), rowNames_(0), colNames_(0) 00065 00066 { 00067 setColumnNames(colNames); //May throw an exception. 00068 } 00069 00070 DataTable::DataTable(const DataTable& table) : 00071 nRow_(table.nRow_), nCol_(table.nCol_), data_(table.data_), rowNames_(0), colNames_(0) 00072 { 00073 if(table.rowNames_) rowNames_ = new vector<string>(*table.rowNames_); 00074 if(table.colNames_) colNames_ = new vector<string>(*table.colNames_); 00075 } 00076 00077 DataTable& DataTable::operator=(const DataTable & table) 00078 { 00079 nRow_ = table.nRow_; 00080 nCol_ = table.nCol_; 00081 data_ = table.data_; 00082 if(rowNames_) delete rowNames_; 00083 if(colNames_) delete colNames_; 00084 rowNames_ = 0; 00085 colNames_ = 0; 00086 if(table.rowNames_) rowNames_ = new vector<string>(*table.rowNames_); 00087 if(table.colNames_) colNames_ = new vector<string>(*table.colNames_); 00088 return *this; 00089 } 00090 00091 /******************************************************************************/ 00092 00093 DataTable::~DataTable() 00094 { 00095 if(rowNames_ != NULL) delete rowNames_; 00096 if(colNames_ != NULL) delete colNames_; 00097 } 00098 00099 /******************************************************************************/ 00100 /* Cell access */ 00101 /******************************************************************************/ 00102 00103 string & DataTable::operator()(size_t rowIndex, size_t colIndex) throw (IndexOutOfBoundsException) 00104 { 00105 if(colIndex >= nCol_) throw IndexOutOfBoundsException("DataTable::operator(size_t, size_t).", colIndex, 0, nCol_ - 1); 00106 if(rowIndex >= data_[colIndex].size()) throw IndexOutOfBoundsException("DataTable::operator(size_t, size_t).", rowIndex, 0, data_[colIndex].size() - 1); 00107 return data_[colIndex][rowIndex]; 00108 } 00109 00110 const string & DataTable::operator()(size_t rowIndex, size_t colIndex) const throw (IndexOutOfBoundsException) 00111 { 00112 if(colIndex >= nCol_) throw IndexOutOfBoundsException("DataTable::operator(size_t, size_t).", colIndex, 0, nCol_ - 1); 00113 if(rowIndex >= data_[colIndex].size()) throw IndexOutOfBoundsException("DataTable::operator(size_t, size_t).", rowIndex, 0, data_[colIndex].size() - 1); 00114 return data_[colIndex][rowIndex]; 00115 } 00116 00117 /******************************************************************************/ 00118 00119 string & DataTable::operator()(const string & rowName, const string & colName) 00120 throw (NoTableRowNamesException, NoTableColumnNamesException, TableNameNotFoundException) 00121 { 00122 if(rowNames_ == NULL) throw NoTableRowNamesException("DataTable::operator(const string &, const string &)."); 00123 if(colNames_ == NULL) throw NoTableColumnNamesException("DataTable::operator(const string &, const string &)."); 00124 try 00125 { 00126 size_t rowIndex = VectorTools::which(*rowNames_, rowName); 00127 size_t colIndex = VectorTools::which(*colNames_, colName); 00128 return (*this)(rowIndex, colIndex); 00129 } 00130 catch(ElementNotFoundException<string> & ex) 00131 { 00132 throw TableNameNotFoundException("DataTable::operator(const string &, const string &).", *ex.getElement()); 00133 } 00134 } 00135 00136 const string & DataTable::operator()(const string & rowName, const string & colName) const 00137 throw (NoTableRowNamesException, NoTableColumnNamesException, TableNameNotFoundException) 00138 { 00139 if(rowNames_ == NULL) throw NoTableRowNamesException("DataTable::operator(const string &, const string &)."); 00140 if(colNames_ == NULL) throw NoTableColumnNamesException("DataTable::operator(const string &, const string &)."); 00141 try 00142 { 00143 size_t rowIndex = VectorTools::which(*rowNames_, rowName); 00144 size_t colIndex = VectorTools::which(*colNames_, colName); 00145 return (*this)(rowIndex, colIndex); 00146 } 00147 catch(ElementNotFoundException<string> & ex) 00148 { 00149 throw TableNameNotFoundException("DataTable::operator(const string &, const string &).", *ex.getElement()); 00150 } 00151 } 00152 00153 /******************************************************************************/ 00154 00155 string & DataTable::operator()(const string & rowName, size_t colIndex) 00156 throw (NoTableRowNamesException, TableNameNotFoundException, IndexOutOfBoundsException) 00157 { 00158 if(rowNames_ == NULL) throw NoTableRowNamesException("DataTable::operator(const string &, size_t)."); 00159 if(colIndex >= nCol_) throw IndexOutOfBoundsException("DataTable::operator(const string &, size_t).", colIndex, 0, nCol_ - 1); 00160 try 00161 { 00162 size_t rowIndex = VectorTools::which(*rowNames_, rowName); 00163 return (*this)(rowIndex, colIndex); 00164 } 00165 catch(ElementNotFoundException<string> & ex) 00166 { 00167 throw TableNameNotFoundException("DataTable::operator(const string &, size_t).", *ex.getElement()); 00168 } 00169 } 00170 00171 const string & DataTable::operator()(const string & rowName, size_t colIndex) const 00172 throw (NoTableRowNamesException, TableNameNotFoundException, IndexOutOfBoundsException) 00173 { 00174 if(rowNames_ == NULL) throw NoTableRowNamesException("DataTable::operator(const string &, size_t)."); 00175 if(colIndex >= nCol_) throw IndexOutOfBoundsException("DataTable::operator(const string &, size_t).", colIndex, 0, nCol_ - 1); 00176 try 00177 { 00178 size_t rowIndex = VectorTools::which(*rowNames_, rowName); 00179 return (*this)(rowIndex, colIndex); 00180 } 00181 catch(ElementNotFoundException<string> & ex) 00182 { 00183 throw TableNameNotFoundException("DataTable::operator(const string &, size_t).", *ex.getElement()); 00184 } 00185 } 00186 00187 /******************************************************************************/ 00188 00189 string & DataTable::operator()(size_t rowIndex, const string & colName) 00190 throw (IndexOutOfBoundsException, NoTableColumnNamesException, TableNameNotFoundException) 00191 { 00192 if(colNames_ == NULL) throw NoTableColumnNamesException("DataTable::operator(size_t, const string &)."); 00193 try 00194 { 00195 size_t colIndex = VectorTools::which(*colNames_, colName); 00196 if(rowIndex >= data_[colIndex].size()) throw IndexOutOfBoundsException("DataTable::operator(size_t, const string &).", rowIndex, 0, data_[colIndex].size() - 1); 00197 return (*this)(rowIndex, colIndex); 00198 } 00199 catch(ElementNotFoundException<string> & ex) 00200 { 00201 throw TableNameNotFoundException("DataTable::operator(const string &, const string &).", *ex.getElement()); 00202 } 00203 } 00204 00205 const string & DataTable::operator()(size_t rowIndex, const string & colName) const 00206 throw (IndexOutOfBoundsException, NoTableColumnNamesException, TableNameNotFoundException) 00207 { 00208 if(colNames_ == NULL) throw NoTableColumnNamesException("DataTable::operator(size_t, const string &)."); 00209 try 00210 { 00211 size_t colIndex = VectorTools::which(*colNames_, colName); 00212 if(rowIndex >= data_[colIndex].size()) throw IndexOutOfBoundsException("DataTable::operator(size_t, const string &).", rowIndex, 0, data_[colIndex].size() - 1); 00213 return (*this)(rowIndex, colIndex); 00214 } 00215 catch(ElementNotFoundException<string> & ex) 00216 { 00217 throw TableNameNotFoundException("DataTable::operator(const string &, const string &).", *ex.getElement()); 00218 } 00219 } 00220 00221 /******************************************************************************/ 00222 /* Work with names */ 00223 /******************************************************************************/ 00224 00225 void DataTable::setRowNames(const vector<string> & rowNames) 00226 throw (DimensionException, DuplicatedTableRowNameException) 00227 { 00228 if (!VectorTools::isUnique(rowNames)) 00229 { 00230 throw DuplicatedTableRowNameException("DataTable::setRowNames(...). Row names must be unique."); 00231 } 00232 if (rowNames.size() != nRow_) throw DimensionException("DataTable::setRowNames.", rowNames.size(), nRow_); 00233 else 00234 { 00235 if(rowNames_ != NULL) delete rowNames_; 00236 rowNames_ = new vector<string>(rowNames.begin(), rowNames.end()); 00237 } 00238 } 00239 00240 vector<string> DataTable::getRowNames() const throw (NoTableRowNamesException) 00241 { 00242 if(rowNames_ == NULL) throw NoTableRowNamesException("DataTable::getRowNames()."); 00243 return * rowNames_; 00244 } 00245 00246 string DataTable::getRowName(size_t index) const throw (NoTableRowNamesException, IndexOutOfBoundsException) 00247 { 00248 if(rowNames_ == NULL) throw NoTableRowNamesException("DataTable::getRowName(size_t)."); 00249 if(index >= nRow_) throw IndexOutOfBoundsException("DataTable::getRowName(size_t).", index, 0, nRow_ - 1); 00250 return (* rowNames_)[index]; 00251 } 00252 00253 /******************************************************************************/ 00254 00255 void DataTable::setColumnNames(const vector<string> & colNames) 00256 throw (DimensionException, DuplicatedTableColumnNameException) 00257 { 00258 if(!VectorTools::isUnique(colNames)) throw DuplicatedTableColumnNameException("DataTable::setColumnNames(...). Column names must be unique."); 00259 if(colNames.size() != nCol_) throw DimensionException("DataTable::setColumnNames.", colNames.size(), nCol_); 00260 else 00261 { 00262 if(colNames_ != NULL) delete colNames_; 00263 colNames_ = new vector<string>(colNames.begin(), colNames.end()); 00264 } 00265 } 00266 00267 vector<string> DataTable::getColumnNames() const throw (NoTableColumnNamesException) 00268 { 00269 if(colNames_ == NULL) throw NoTableColumnNamesException("DataTable::getColumnNames()."); 00270 return *colNames_; 00271 } 00272 00273 string DataTable::getColumnName(size_t index) const throw (NoTableColumnNamesException, IndexOutOfBoundsException) 00274 { 00275 if(colNames_ == NULL) throw NoTableColumnNamesException("DataTable::getColumnName(size_t)."); 00276 if(index >= nCol_) throw IndexOutOfBoundsException("DataTable::getColumnName(size_t).", index, 0, nCol_ - 1); 00277 return (* colNames_)[index]; 00278 } 00279 00280 /******************************************************************************/ 00281 /* Work on columns */ 00282 /******************************************************************************/ 00283 00284 vector<string> & DataTable::getColumn(size_t index) 00285 throw (IndexOutOfBoundsException) 00286 { 00287 if(index >= nCol_) throw IndexOutOfBoundsException("DataTable::getColumn(size_t).", index, 0, nCol_ - 1); 00288 return data_[index]; 00289 } 00290 00291 const vector<string> & DataTable::getColumn(size_t index) const 00292 throw (IndexOutOfBoundsException) 00293 { 00294 if(index >= nCol_) throw IndexOutOfBoundsException("DataTable::getColumn(size_t).", index, 0, nCol_ - 1); 00295 return data_[index]; 00296 } 00297 00298 vector<string> & DataTable::getColumn(const string & colName) 00299 throw (NoTableColumnNamesException, TableColumnNameNotFoundException) 00300 { 00301 if(colNames_ == NULL) throw NoTableColumnNamesException("DataTable::getColumn(const string &)."); 00302 try 00303 { 00304 size_t colIndex = VectorTools::which(*colNames_, colName); 00305 return data_[colIndex]; 00306 } 00307 catch(ElementNotFoundException<string> & ex) 00308 { 00309 throw TableColumnNameNotFoundException("DataTable::getColumn(const string &).", colName); 00310 } 00311 } 00312 00313 const vector<string> & DataTable::getColumn(const string & colName) const 00314 throw (NoTableColumnNamesException, TableColumnNameNotFoundException) 00315 { 00316 if(colNames_ == NULL) throw NoTableColumnNamesException("DataTable::getColumn(const string &)."); 00317 try 00318 { 00319 size_t colIndex = VectorTools::which(*colNames_, colName); 00320 return data_[colIndex]; 00321 } 00322 catch(ElementNotFoundException<string> & ex) 00323 { 00324 throw TableColumnNameNotFoundException("DataTable::getColumn(const string &).", colName); 00325 } 00326 } 00327 00328 bool DataTable::hasColumn(const string & colName) const 00329 { 00330 if(colNames_ == NULL) return false; 00331 for(size_t i = 0; i < colNames_->size(); i++) 00332 if((* colNames_)[i] == colName) return true; 00333 return false; 00334 } 00335 00336 void DataTable::deleteColumn(size_t index) 00337 throw (IndexOutOfBoundsException) 00338 { 00339 if(index >= nCol_) throw IndexOutOfBoundsException("DataTable::deleteColumn(size_t).", index, 0, nCol_ - 1); 00340 data_.erase(data_.begin() + index); 00341 if(colNames_ != NULL) colNames_->erase(colNames_->begin()+index); 00342 nCol_--; 00343 } 00344 00345 void DataTable::deleteColumn(const string & colName) 00346 throw (NoTableColumnNamesException, TableColumnNameNotFoundException) 00347 { 00348 if(colNames_ == NULL) throw NoTableColumnNamesException("DataTable::deleteColumn(const string &)."); 00349 try 00350 { 00351 size_t colIndex = VectorTools::which(*colNames_, colName); 00352 data_.erase(data_.begin() + colIndex); 00353 colNames_->erase(colNames_->begin() + colIndex); 00354 nCol_--; 00355 } 00356 catch(ElementNotFoundException<string> & ex) 00357 { 00358 throw TableColumnNameNotFoundException("DataTable::deleteColumn(const string &).", colName); 00359 } 00360 } 00361 00362 void DataTable::addColumn(const vector<string>& newColumn) 00363 throw (DimensionException, TableColumnNamesException) 00364 { 00365 if (colNames_) 00366 throw TableColumnNamesException("DataTable::addColumn. Table has column names."); 00367 if (newColumn.size() != nRow_) 00368 throw DimensionException("DataTable::addColumn.", newColumn.size(), nRow_); 00369 data_.push_back(newColumn); 00370 nCol_++; 00371 } 00372 00373 void DataTable::addColumn(const string& colName, const vector<string>& newColumn) 00374 throw (DimensionException, NoTableColumnNamesException, DuplicatedTableColumnNameException) 00375 { 00376 if(!colNames_) 00377 { 00378 if (nCol_ == 0) colNames_ = new vector<string>(); 00379 else throw NoTableColumnNamesException("DataTable::addColumn. Table has column names."); 00380 } 00381 if (newColumn.size() != nRow_) 00382 throw DimensionException("DataTable::addColumn.", newColumn.size(), nRow_); 00383 if (nCol_ > 0 && find(colNames_->begin(), colNames_->end(), colName) != colNames_->end()) 00384 throw DuplicatedTableColumnNameException("DataTable::addColumn(const string &, const vector<string> &). Column names must be unique."); 00385 colNames_->push_back(colName); 00386 data_.push_back(newColumn); 00387 nCol_++; 00388 } 00389 00390 /******************************************************************************/ 00391 /* Work on rows */ 00392 /******************************************************************************/ 00393 00394 vector<string> DataTable::getRow(size_t index) const 00395 throw (IndexOutOfBoundsException) 00396 { 00397 if(index >= nRow_) throw IndexOutOfBoundsException("DataTable::getRow(size_t).", index, 0, nRow_ - 1); 00398 vector<string> row; 00399 for (size_t i = 0 ; i < nCol_ ; i++) 00400 row.push_back(data_[i][index]); 00401 return row; 00402 } 00403 00404 vector<string> DataTable::getRow(const string& rowName) const 00405 throw (NoTableRowNamesException, TableRowNameNotFoundException) 00406 { 00407 if (!rowNames_) throw NoTableRowNamesException("DataTable::getRow(const string &)."); 00408 try 00409 { 00410 size_t rowIndex = VectorTools::which(*rowNames_, rowName); 00411 vector<string> row; 00412 for (size_t i = 0 ; i < nCol_ ; i++) 00413 row.push_back(data_[i][rowIndex]); 00414 return row; 00415 } 00416 catch(ElementNotFoundException<string> & ex) 00417 { 00418 throw TableRowNameNotFoundException("DataTable::getRow(const string &).", rowName); 00419 } 00420 } 00421 00422 bool DataTable::hasRow(const string & rowName) const 00423 { 00424 if(rowNames_ == NULL) return false; 00425 for(size_t i = 0; i < rowNames_->size(); i++) 00426 { 00427 if((* rowNames_)[i] == rowName) return true; 00428 } 00429 return false; 00430 } 00431 00432 void DataTable::deleteRow(size_t index) 00433 throw (IndexOutOfBoundsException) 00434 { 00435 for(size_t j = 0; j < nCol_; j++) 00436 { 00437 vector<string> * column = & data_[j]; 00438 if(index >= column->size()) throw IndexOutOfBoundsException("DataTable::deleteRow(size_t).", index, 0, column->size() - 1); 00439 column->erase(column->begin()+index); 00440 } 00441 if(rowNames_ != NULL) rowNames_->erase(rowNames_->begin()+index); 00442 nRow_--; 00443 } 00444 00445 void DataTable::deleteRow(const string& rowName) 00446 throw (NoTableRowNamesException, TableRowNameNotFoundException) 00447 { 00448 if(rowNames_ == NULL) throw NoTableRowNamesException("DataTable::deleteRow(const string &)."); 00449 try 00450 { 00451 size_t rowIndex = VectorTools::which(*rowNames_, rowName); 00452 for(size_t j = 0; j < nCol_; j++) 00453 { 00454 vector<string> * column = & data_[j]; 00455 column->erase(column->begin()+rowIndex); 00456 } 00457 rowNames_->erase(rowNames_->begin()+rowIndex); 00458 nRow_--; 00459 } 00460 catch(ElementNotFoundException<string> & ex) 00461 { 00462 throw TableRowNameNotFoundException("DataTable::deleteRow(const string &).", rowName); 00463 } 00464 } 00465 00466 void DataTable::addRow(const vector<string>& newRow) 00467 throw (DimensionException, TableRowNamesException) 00468 { 00469 if (rowNames_) throw TableRowNamesException("DataTable::addRow. Table has row names."); 00470 if (newRow.size() != nCol_) throw DimensionException("DataTable::addRow.", newRow.size(), nCol_); 00471 for (size_t j = 0; j < nCol_; j++) 00472 data_[j].push_back(newRow[j]); 00473 nRow_++; 00474 } 00475 00476 void DataTable::addRow(const string& rowName, const vector<string>& newRow) 00477 throw (DimensionException, NoTableRowNamesException, DuplicatedTableRowNameException) 00478 { 00479 if (!rowNames_) 00480 { 00481 if (nRow_ == 0) rowNames_ = new vector<string>(); 00482 else throw NoTableRowNamesException("DataTable::addRow. Table has row names."); 00483 } 00484 if (newRow.size() != nCol_) throw DimensionException("DataTable::addRow.", newRow.size(), nCol_); 00485 if (nRow_ > 0 && find(rowNames_->begin(), rowNames_->end(), rowName) != rowNames_->end()) 00486 throw DuplicatedTableRowNameException("DataTable::addRow(const string &, const vector<string> &). Row names must be unique."); 00487 rowNames_->push_back(rowName); 00488 for (size_t j = 0; j < nCol_; j++) 00489 data_[j].push_back(newRow[j]); 00490 nRow_++; 00491 } 00492 00493 /******************************************************************************/ 00494 /* Read from a CSV file */ 00495 /******************************************************************************/ 00496 00497 DataTable* DataTable::read(istream& in, const string& sep, bool header, int rowNames) 00498 throw (DimensionException, IndexOutOfBoundsException, DuplicatedTableRowNameException) 00499 { 00500 string firstLine = FileTools::getNextLine(in); 00501 StringTokenizer st1(firstLine, sep, false, true); 00502 vector<string> row1(st1.getTokens().begin(), st1.getTokens().end()); 00503 string secondLine = FileTools::getNextLine(in); 00504 StringTokenizer st2(secondLine, sep, false, true); 00505 vector<string> row2(st2.getTokens().begin(), st2.getTokens().end()); 00506 size_t nCol = row1.size(); 00507 bool hasRowNames; 00508 DataTable * dt; 00509 if(row1.size() == row2.size()) 00510 { 00511 dt = new DataTable(nCol); 00512 if(header) 00513 { //Use first line as header. 00514 dt->setColumnNames(row1); 00515 } 00516 else 00517 { 00518 dt->addRow(row1); 00519 } 00520 dt->addRow(row2); 00521 hasRowNames = false; 00522 } 00523 else if(row1.size() == row2.size() - 1) 00524 { 00525 dt = new DataTable(nCol); 00526 dt->setColumnNames(row1); 00527 string rowName = *row2.begin(); 00528 dt->addRow(rowName, vector<string>(row2.begin()+1, row2.end())); 00529 hasRowNames = true; 00530 } 00531 else throw DimensionException("DataTable::read(...). Row 2 has not the correct number of columns.", row2.size(), nCol); 00532 00533 // Now read each line: 00534 string line = FileTools::getNextLine(in); 00535 while(!TextTools::isEmpty(line)) 00536 { 00537 StringTokenizer st(line, sep, false, true); 00538 if(hasRowNames) 00539 { 00540 string rowName = *st.getTokens().begin(); 00541 vector<string> row(st.getTokens().begin()+1, st.getTokens().end()); 00542 dt->addRow(rowName, row); 00543 } 00544 else 00545 { 00546 vector<string> row(st.getTokens().begin(), st.getTokens().end()); 00547 dt->addRow(row); 00548 } 00549 line = FileTools::getNextLine(in); 00550 } 00551 00552 // Row names: 00553 if(rowNames > -1) 00554 { 00555 if((size_t)rowNames >= nCol) throw IndexOutOfBoundsException("DataTable::read(...). Invalid column specified for row names.", rowNames, 0, nCol-1); 00556 vector<string> col = dt->getColumn((size_t)rowNames); 00557 dt->setRowNames(col); 00558 dt->deleteColumn(rowNames); 00559 } 00560 00561 return(dt); 00562 } 00563 00564 /******************************************************************************/ 00565 00566 void DataTable::write(const DataTable& data, ostream& out, const string& sep, bool alignHeaders) 00567 { 00568 size_t n = data.getNumberOfColumns(); 00569 if(n == 0) return; 00570 if(data.hasColumnNames()) 00571 { //Write header 00572 vector<string> colNames = data.getColumnNames(); 00573 if (alignHeaders && data.hasRowNames()) out << sep; 00574 out << colNames[0]; 00575 for(size_t i = 1; i < n; i++) { 00576 out << sep << colNames[i]; 00577 } 00578 out << endl; 00579 } 00580 //Now write each row: 00581 for(size_t i = 0; i < data.getNumberOfRows(); i++) 00582 { 00583 if(data.hasRowNames()) out << data.getRowName(i) << sep; 00584 out << data(i, 0); 00585 for(size_t j = 1; j < n; j++) 00586 { 00587 out << sep << data(i, j); 00588 } 00589 out << endl; 00590 } 00591 } 00592 00593 /******************************************************************************/ 00594