00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include <RcppFrame.h>
00024
00025 ColDatum::ColDatum() : level(0) { };
00026
00027 ColDatum::ColDatum(const ColDatum& datum) {
00028
00029 s = datum.s;
00030 x = datum.x;
00031 i = datum.i;
00032 type = datum.type;
00033 level = datum.level;
00034 numLevels = datum.numLevels;
00035 d = datum.d;
00036 if (type == COLTYPE_FACTOR) {
00037 levelNames = new std::string[numLevels];
00038 for (int i = 0; i < numLevels; i++)
00039 levelNames[i] = datum.levelNames[i];
00040 }
00041 }
00042
00043 ColDatum::~ColDatum() {
00044 if (type == COLTYPE_FACTOR) {
00045
00046
00047
00048
00049
00050 delete [] levelNames;
00051 }
00052 }
00053
00054 void ColDatum::setDoubleValue(double val) {
00055 x = val;
00056 type = COLTYPE_DOUBLE;
00057 }
00058
00059 void ColDatum::setIntValue(int val) {
00060 i = val;
00061 type = COLTYPE_INT;
00062 }
00063
00064 void ColDatum::setLogicalValue(int val) {
00065 if (val != 0 && val != 1)
00066 throw std::range_error("ColDatum::setLogicalValue: logical values must be 0/1.");
00067 i = val;
00068 type = COLTYPE_LOGICAL;
00069 }
00070
00071 void ColDatum::setStringValue(std::string val) {
00072 s = val;
00073 type = COLTYPE_STRING;
00074 }
00075
00076 void ColDatum::setDateValue(RcppDate date) {
00077 d = date;
00078 type = COLTYPE_DATE;
00079 }
00080
00081 void ColDatum::setDatetimeValue(RcppDatetime datetime) {
00082 x = datetime.m_d;
00083 type = COLTYPE_DATETIME;
00084 }
00085
00086 void ColDatum::setFactorValue(std::string *names, int numNames, int factorLevel) {
00087 if (factorLevel < 1 || factorLevel > numNames)
00088 throw std::range_error("ColDatum::setFactorValue: factor level out of range");
00089 level = factorLevel;
00090 numLevels = numNames;
00091 levelNames = new std::string[numLevels];
00092 for (int i = 0; i < numLevels; i++)
00093 levelNames[i] = names[i];
00094 type = COLTYPE_FACTOR;
00095 }
00096
00097 double ColDatum::getDoubleValue() {
00098 if (type != COLTYPE_DOUBLE)
00099 throw std::range_error("ColDatum::getDoubleValue: wrong data type in getDoubleValue");
00100 return x;
00101 }
00102
00103 int ColDatum::getIntValue() {
00104 if (type != COLTYPE_INT)
00105 throw std::range_error("ColDatum::getIntValue: wrong data type in getIntValue");
00106 return i;
00107 }
00108
00109 int ColDatum::getLogicalValue() {
00110 if (type != COLTYPE_LOGICAL)
00111 throw std::range_error("ColDatum::getLogicalValue: wrong data type in getLogicalValue");
00112 return i;
00113 }
00114
00115 std::string ColDatum::getStringValue() {
00116 if (type != COLTYPE_STRING)
00117 throw std::range_error("ColDatum::getStringValue: wrong data type in getStringValue");
00118 return s;
00119 }
00120
00121 RcppDate ColDatum::getDateValue() {
00122 if (type != COLTYPE_DATE)
00123 throw std::range_error("ColDatum::getDateValue: wrong data type in getDateValue");
00124 return d;
00125 }
00126
00127 double ColDatum::getDateRCode() {
00128 return (double)(d.getJDN() - RcppDate::Jan1970Offset);
00129 }
00130
00131 RcppDatetime ColDatum::getDatetimeValue() {
00132 if (type != COLTYPE_DATETIME)
00133 throw std::range_error("ColDatum::getDatetimeValue: wrong data type in getDatetimeValue");
00134 return RcppDatetime(x);
00135 }
00136
00137 void ColDatum::checkFactorType() {
00138 if (type != COLTYPE_FACTOR)
00139 throw std::range_error("ColDatun::checkFactorType: wrong data type in getFactor...");
00140 }
00141
00142 int ColDatum::getFactorNumLevels() {
00143 checkFactorType();
00144 return numLevels;
00145 }
00146
00147 int ColDatum::getFactorLevel() {
00148 checkFactorType();
00149 return level;
00150 }
00151
00152 std::string *ColDatum::getFactorLevelNames() {
00153 checkFactorType();
00154 return levelNames;
00155 }
00156
00157 std::string ColDatum::getFactorLevelName() {
00158 checkFactorType();
00159 return levelNames[level-1];
00160 }
00161
00162 RcppFrame::RcppFrame(std::vector<std::string> colNames) : colNames(colNames) {
00163 if (colNames.size() == 0)
00164 throw std::range_error("RcppFrame::RcppFrame: zero length colNames");
00165 }
00166
00167 RcppFrame::RcppFrame(SEXP df) {
00168 if (!Rf_isNewList(df))
00169 throw std::range_error("RcppFrame::RcppFrame: invalid data frame.");
00170 int ncol = Rf_length(df);
00171 SEXP names = Rf_getAttrib(df, R_NamesSymbol);
00172 colNames.resize(ncol);
00173 SEXP colData = VECTOR_ELT(df,0);
00174 int nrow = Rf_length(colData);
00175 if (nrow == 0)
00176 throw std::range_error("RcppFrame::RcppFrame: zero lenth column.");
00177
00178
00179 table.resize(nrow);
00180 for (int r = 0; r < nrow; r++)
00181 table[r].resize(ncol);
00182
00183 for (int i=0; i < ncol; i++) {
00184 colNames[i] = std::string(CHAR(STRING_ELT(names,i)));
00185 SEXP colData = VECTOR_ELT(df,i);
00186 if (!Rf_isVector(colData) || Rf_length(colData) != nrow)
00187 throw std::range_error("RcppFrame::RcppFrame: invalid column.");
00188
00189
00190
00191
00192 bool isDateClass = false;
00193 SEXP classname = Rf_getAttrib(colData, R_ClassSymbol);
00194 if (classname != R_NilValue)
00195 isDateClass = (strcmp(CHAR(STRING_ELT(classname,0)),"Date") == 0);
00196
00197 if (Rf_isReal(colData)) {
00198 if (isDateClass) {
00199 for (int j=0; j < nrow; j++)
00200 table[j][i].setDateValue(RcppDate((int)REAL(colData)[j]));
00201 }
00202 else
00203 for (int j=0; j < nrow; j++)
00204 table[j][i].setDoubleValue(REAL(colData)[j]);
00205 }
00206 else if (Rf_isInteger(colData)) {
00207 if (isDateClass) {
00208 for (int j=0; j < nrow; j++)
00209 table[j][i].setDateValue(RcppDate(INTEGER(colData)[j]));
00210 }
00211 else
00212 for (int j=0; j < nrow; j++)
00213 table[j][i].setIntValue(INTEGER(colData)[j]);
00214 }
00215 else if (Rf_isString(colData)) {
00216 for (int j=0; j < nrow; j++)
00217 table[j][i].setStringValue(std::string(CHAR(STRING_ELT(colData,j))));
00218 }
00219 else if (Rf_isFactor(colData)) {
00220 SEXP names = Rf_getAttrib(colData, R_LevelsSymbol);
00221 int numLevels = Rf_length(names);
00222 std::string *levelNames = new std::string[numLevels];
00223 for (int k=0; k < numLevels; k++)
00224 levelNames[k] = std::string(CHAR(STRING_ELT(names,k)));
00225 for (int j=0; j < nrow; j++)
00226 table[j][i].setFactorValue(levelNames, numLevels,
00227 INTEGER(colData)[j]);
00228 delete [] levelNames;
00229 }
00230 else if (Rf_isLogical(colData)) {
00231 for (int j=0; j < nrow; j++) {
00232 table[j][i].setLogicalValue(INTEGER(colData)[j]);
00233 }
00234 }
00235 else
00236 throw std::range_error("RcppFrame::RcppFrame: unsupported data frame column type.");
00237 }
00238 }
00239
00240 std::vector<std::string>& RcppFrame::getColNames() {
00241 return colNames;
00242 }
00243
00244 std::vector<std::vector<ColDatum> >& RcppFrame::getTableData() {
00245 return table;
00246 }
00247
00248 void RcppFrame::addRow(std::vector<ColDatum> rowData) {
00249 if (rowData.size() != colNames.size())
00250 throw std::range_error("RcppFrame::addRow: incorrect row length.");
00251 if (table.size() > 0) {
00252
00253
00254
00255 for (int i = 0; i < (int)colNames.size(); i++) {
00256 if (rowData[i].getType() != table[0][i].getType()) {
00257 std::ostringstream oss;
00258 oss << "RcppFrame::addRow: incorrect data type at posn "
00259 << i;
00260 throw std::range_error(oss.str());
00261 }
00262 }
00263 }
00264 table.push_back(rowData);
00265 }
00266
00267 int RcppFrame::rows() {
00268 return table.size();
00269 }
00270
00271 int RcppFrame::cols() {
00272 return table[0].size();
00273 }
00274
00275