[Rcpp-commits] r171 - pkg/src
noreply at r-forge.r-project.org
noreply at r-forge.r-project.org
Wed Nov 11 01:39:54 CET 2009
Author: edd
Date: 2009-11-11 01:39:54 +0100 (Wed, 11 Nov 2009)
New Revision: 171
Added:
pkg/src/RcppFrame.cpp
pkg/src/RcppFrame.h
Modified:
pkg/src/Rcpp.cpp
pkg/src/Rcpp.h
Log:
moved ColDatum and RcppFrame into RcppFrame files
Modified: pkg/src/Rcpp.cpp
===================================================================
--- pkg/src/Rcpp.cpp 2009-11-10 13:44:27 UTC (rev 170)
+++ pkg/src/Rcpp.cpp 2009-11-11 00:39:54 UTC (rev 171)
@@ -21,79 +21,6 @@
#include <Rcpp.h>
-RcppFrame::RcppFrame(SEXP df) {
- if (!Rf_isNewList(df))
- throw std::range_error("RcppFrame::RcppFrame: invalid data frame.");
- int ncol = Rf_length(df);
- SEXP names = Rf_getAttrib(df, R_NamesSymbol);
- colNames.resize(ncol);
- SEXP colData = VECTOR_ELT(df,0); // First column of data.
- int nrow = Rf_length(colData);
- if (nrow == 0)
- throw std::range_error("RcppFrame::RcppFrame: zero lenth column.");
-
- // Allocate storage for table.
- table.resize(nrow);
- for (int r = 0; r < nrow; r++)
- table[r].resize(ncol);
-
- for (int i=0; i < ncol; i++) {
- colNames[i] = std::string(CHAR(STRING_ELT(names,i)));
- SEXP colData = VECTOR_ELT(df,i);
- if (!Rf_isVector(colData) || Rf_length(colData) != nrow)
- throw std::range_error("RcppFrame::RcppFrame: invalid column.");
-
- // Check for Date class. Currently R stores the date ordinal in a
- // real value. We check for Date under both Real and Integer values
- // as insurance against future changes.
- bool isDateClass = false;
- SEXP classname = Rf_getAttrib(colData, R_ClassSymbol);
- if (classname != R_NilValue)
- isDateClass = (strcmp(CHAR(STRING_ELT(classname,0)),"Date") == 0);
-
- if (Rf_isReal(colData)) {
- if (isDateClass) {
- for (int j=0; j < nrow; j++) // Column of Date's
- table[j][i].setDateValue(RcppDate((int)REAL(colData)[j]));
- }
- else // Column of REAL's
- for (int j=0; j < nrow; j++)
- table[j][i].setDoubleValue(REAL(colData)[j]);
- }
- else if (Rf_isInteger(colData)) {
- if (isDateClass) {
- for (int j=0; j < nrow; j++) // Column of Date's
- table[j][i].setDateValue(RcppDate(INTEGER(colData)[j]));
- }
- else
- for (int j=0; j < nrow; j++)
- table[j][i].setIntValue(INTEGER(colData)[j]);
- }
- else if (Rf_isString(colData)) { // Non-factor string column
- for (int j=0; j < nrow; j++)
- table[j][i].setStringValue(std::string(CHAR(STRING_ELT(colData,j))));
- }
- else if (Rf_isFactor(colData)) { // Factor column.
- SEXP names = Rf_getAttrib(colData, R_LevelsSymbol);
- int numLevels = Rf_length(names);
- std::string *levelNames = new std::string[numLevels];
- for (int k=0; k < numLevels; k++)
- levelNames[k] = std::string(CHAR(STRING_ELT(names,k)));
- for (int j=0; j < nrow; j++)
- table[j][i].setFactorValue(levelNames, numLevels,
- INTEGER(colData)[j]);
- delete [] levelNames;
- }
- else if (Rf_isLogical(colData)) {
- for (int j=0; j < nrow; j++) {
- table[j][i].setLogicalValue(INTEGER(colData)[j]);
- }
- }
- else
- throw std::range_error("RcppFrame::RcppFrame: unsupported data frame column type.");
- }
-}
-
RcppDateVector::RcppDateVector(SEXP vec) {
int i;
if (!Rf_isNumeric(vec) || Rf_isMatrix(vec) || Rf_isLogical(vec))
Modified: pkg/src/Rcpp.h
===================================================================
--- pkg/src/Rcpp.h 2009-11-10 13:44:27 UTC (rev 170)
+++ pkg/src/Rcpp.h 2009-11-11 00:39:54 UTC (rev 171)
@@ -25,162 +25,10 @@
#include <RcppCommon.h>
#include <RcppDate.h>
#include <RcppDatetime.h>
+#include <RcppFrame.h>
#include <RcppList.h>
#include <RcppParams.h>
-// Supported data frame column types.
-enum ColType { COLTYPE_DOUBLE, COLTYPE_INT, COLTYPE_STRING,
- COLTYPE_FACTOR, COLTYPE_LOGICAL,
- COLTYPE_DATE, COLTYPE_DATETIME };
-
-class ColDatum {
-public:
- ColDatum() {
- level = 0;
- }
- ~ColDatum() {
- if (type == COLTYPE_FACTOR) {
- // For this to work we need a deep copy when type == COLTYPE_FACTOR.
- // See the copy constructor below. It is wasteful to have
- // evey factor cell own a separate copy of levelNames, but we leave
- // the task of factoring it out (using reference counts) for
- // later.
- delete [] levelNames;
- }
- }
- ColDatum(const ColDatum& datum) {
-
- // Need deep copy so contruction/destruction is synchronized.
- s = datum.s;
- x = datum.x;
- i = datum.i;
- type = datum.type;
- level = datum.level;
- numLevels = datum.numLevels;
- d = datum.d;
- if (type == COLTYPE_FACTOR) {
- levelNames = new std::string[numLevels];
- for (int i = 0; i < numLevels; i++)
- levelNames[i] = datum.levelNames[i];
- }
- }
-
- ColType getType() const { return type; }
-
- void setDoubleValue(double val) { x = val; type = COLTYPE_DOUBLE; }
- void setIntValue(int val) { i = val; type = COLTYPE_INT; }
- void setLogicalValue(int val) {
- if (val != 0 && val != 1)
- throw std::range_error("ColDatum::setLogicalValue: logical values must be 0/1.");
- i = val; type = COLTYPE_LOGICAL;
- }
- void setStringValue(std::string val) { s = val; type = COLTYPE_STRING; }
- void setDateValue(RcppDate date) {
- d = date;
- type = COLTYPE_DATE;
- }
- void setDatetimeValue(RcppDatetime datetime) {
- x = datetime.m_d;
- type = COLTYPE_DATETIME;
- }
- void setFactorValue(std::string *names, int numNames, int factorLevel) {
- if (factorLevel < 1 || factorLevel > numNames)
- throw std::range_error("ColDatum::setFactorValue: factor level out of range");
- level = factorLevel;
- numLevels = numNames;
- levelNames = new std::string[numLevels];
- for (int i = 0; i < numLevels; i++)
- levelNames[i] = names[i];
- type = COLTYPE_FACTOR;
- }
-
- double getDoubleValue() {
- if (type != COLTYPE_DOUBLE)
- throw std::range_error("ColDatum::getDoubleValue: wrong data type in getDoubleValue");
- return x;
- }
- int getIntValue() {
- if (type != COLTYPE_INT)
- throw std::range_error("ColDatum::getIntValue: wrong data type in getIntValue");
- return i;
- }
- int getLogicalValue() {
- if (type != COLTYPE_LOGICAL)
- throw std::range_error("ColDatum::getLogicalValue: wrong data type in getLogicalValue");
- return i;
- }
- std::string getStringValue() {
- if (type != COLTYPE_STRING)
- throw std::range_error("ColDatum::getStringValue: wrong data type in getStringValue");
- return s;
- }
- RcppDate getDateValue() {
- if (type != COLTYPE_DATE)
- throw std::range_error("ColDatum::getDateValue: wrong data type in getDateValue");
- return d;
- }
- double getDateRCode() {
- return (double)(d.getJDN() - RcppDate::Jan1970Offset);
- }
- RcppDatetime getDatetimeValue() {
- if (type != COLTYPE_DATETIME)
- throw std::range_error("ColDatum::getDatetimeValue: wrong data type in getDatetimeValue");
- return RcppDatetime(x);
- }
-
- void checkFactorType() {
- if (type != COLTYPE_FACTOR)
- throw std::range_error("ColDatun::checkFactorType: wrong data type in getFactor...");
- }
- int getFactorNumLevels() { checkFactorType(); return numLevels; }
- int getFactorLevel() { checkFactorType(); return level; }
- std::string *getFactorLevelNames() { checkFactorType(); return levelNames; }
- std::string getFactorLevelName() { checkFactorType(); return levelNames[level-1];}
-
-private:
- ColType type;
- std::string s;
- double x; // used for double and datetime
- int i; // used for int and logical
- int level; // factor level
- int numLevels; // number of levels for this factor
- std::string *levelNames; // level name = levelNames[level-1]
- RcppDate d;
-};
-
-class RcppFrame {
- std::vector<std::string> colNames;
- std::vector<std::vector<ColDatum> > table; // table[row][col]
-public:
- RcppFrame(SEXP df); // Construct from R data frame.
- RcppFrame(std::vector<std::string> colNames) : colNames(colNames) {
- if (colNames.size() == 0)
- throw std::range_error("RcppFrame::RcppFrame: zero length colNames");
- }
- std::vector<std::string>& getColNames() { return colNames; }
- std::vector<std::vector<ColDatum> >& getTableData() { return table; }
- void addRow(std::vector<ColDatum> rowData) {
- if (rowData.size() != colNames.size())
- throw std::range_error("RcppFrame::addRow: incorrect row length.");
- if (table.size() > 0) {
-
- // First row added determines column types. Check for consistency
- // for rows after the first...
- for (int i = 0; i < (int)colNames.size(); i++) {
- if (rowData[i].getType() != table[0][i].getType()) {
- std::ostringstream oss;
- oss << "RcppFrame::addRow: incorrect data type at posn "
- << i;
- throw std::range_error(oss.str());
- }
- }
- }
- table.push_back(rowData);
- }
- int rows() { return table.size(); }
- int cols() { return table[0].size(); }
-};
-
class RcppNumList {
public:
RcppNumList(SEXP theList) {
Added: pkg/src/RcppFrame.cpp
===================================================================
--- pkg/src/RcppFrame.cpp (rev 0)
+++ pkg/src/RcppFrame.cpp 2009-11-11 00:39:54 UTC (rev 171)
@@ -0,0 +1,274 @@
+// -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; tab-width: 8 -*-
+//
+// RcppFrame.cpp: Rcpp R/C++ interface class library -- data.framee support
+//
+// Copyright (C) 2005 - 2006 Dominick Samperi
+// Copyright (C) 2008 - 2009 Dirk Eddelbuettel
+//
+// This library is free software; you can redistribute it and/or modify it
+// under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation; either version 2.1 of the License, or (at
+// your option) any later version.
+//
+// This library is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+// License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this library; if not, write to the Free Software Foundation,
+// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+#include <RcppFrame.h>
+
+ColDatum::ColDatum() : level(0) { };
+
+ColDatum::ColDatum(const ColDatum& datum) {
+ // Need deep copy so contruction/destruction is synchronized.
+ s = datum.s;
+ x = datum.x;
+ i = datum.i;
+ type = datum.type;
+ level = datum.level;
+ numLevels = datum.numLevels;
+ d = datum.d;
+ if (type == COLTYPE_FACTOR) {
+ levelNames = new std::string[numLevels];
+ for (int i = 0; i < numLevels; i++)
+ levelNames[i] = datum.levelNames[i];
+ }
+}
+
+ColDatum::~ColDatum() {
+ if (type == COLTYPE_FACTOR) {
+ // For this to work we need a deep copy when type == COLTYPE_FACTOR.
+ // See the copy constructor below. It is wasteful to have
+ // evey factor cell own a separate copy of levelNames, but we leave
+ // the task of factoring it out (using reference counts) for
+ // later.
+ delete [] levelNames;
+ }
+}
+
+void ColDatum::setDoubleValue(double val) {
+ x = val;
+ type = COLTYPE_DOUBLE;
+}
+
+void ColDatum::setIntValue(int val) {
+ i = val;
+ type = COLTYPE_INT;
+}
+
+void ColDatum::setLogicalValue(int val) {
+ if (val != 0 && val != 1)
+ throw std::range_error("ColDatum::setLogicalValue: logical values must be 0/1.");
+ i = val;
+ type = COLTYPE_LOGICAL;
+}
+
+void ColDatum::setStringValue(std::string val) {
+ s = val;
+ type = COLTYPE_STRING;
+}
+
+void ColDatum::setDateValue(RcppDate date) {
+ d = date;
+ type = COLTYPE_DATE;
+}
+
+void ColDatum::setDatetimeValue(RcppDatetime datetime) {
+ x = datetime.m_d;
+ type = COLTYPE_DATETIME;
+}
+
+void ColDatum::setFactorValue(std::string *names, int numNames, int factorLevel) {
+ if (factorLevel < 1 || factorLevel > numNames)
+ throw std::range_error("ColDatum::setFactorValue: factor level out of range");
+ level = factorLevel;
+ numLevels = numNames;
+ levelNames = new std::string[numLevels];
+ for (int i = 0; i < numLevels; i++)
+ levelNames[i] = names[i];
+ type = COLTYPE_FACTOR;
+}
+
+double ColDatum::getDoubleValue() {
+ if (type != COLTYPE_DOUBLE)
+ throw std::range_error("ColDatum::getDoubleValue: wrong data type in getDoubleValue");
+ return x;
+}
+
+int ColDatum::getIntValue() {
+ if (type != COLTYPE_INT)
+ throw std::range_error("ColDatum::getIntValue: wrong data type in getIntValue");
+ return i;
+}
+
+int ColDatum::getLogicalValue() {
+ if (type != COLTYPE_LOGICAL)
+ throw std::range_error("ColDatum::getLogicalValue: wrong data type in getLogicalValue");
+ return i;
+}
+
+std::string ColDatum::getStringValue() {
+ if (type != COLTYPE_STRING)
+ throw std::range_error("ColDatum::getStringValue: wrong data type in getStringValue");
+ return s;
+}
+
+RcppDate ColDatum::getDateValue() {
+ if (type != COLTYPE_DATE)
+ throw std::range_error("ColDatum::getDateValue: wrong data type in getDateValue");
+ return d;
+}
+
+double ColDatum::getDateRCode() {
+ return (double)(d.getJDN() - RcppDate::Jan1970Offset);
+}
+
+RcppDatetime ColDatum::getDatetimeValue() {
+ if (type != COLTYPE_DATETIME)
+ throw std::range_error("ColDatum::getDatetimeValue: wrong data type in getDatetimeValue");
+ return RcppDatetime(x);
+}
+
+void ColDatum::checkFactorType() {
+ if (type != COLTYPE_FACTOR)
+ throw std::range_error("ColDatun::checkFactorType: wrong data type in getFactor...");
+}
+
+int ColDatum::getFactorNumLevels() {
+ checkFactorType();
+ return numLevels;
+}
+
+int ColDatum::getFactorLevel() {
+ checkFactorType();
+ return level;
+}
+
+std::string *ColDatum::getFactorLevelNames() {
+ checkFactorType();
+ return levelNames;
+}
+
+std::string ColDatum::getFactorLevelName() {
+ checkFactorType();
+ return levelNames[level-1];
+}
+
+RcppFrame::RcppFrame(std::vector<std::string> colNames) : colNames(colNames) {
+ if (colNames.size() == 0)
+ throw std::range_error("RcppFrame::RcppFrame: zero length colNames");
+}
+
+RcppFrame::RcppFrame(SEXP df) {
+ if (!Rf_isNewList(df))
+ throw std::range_error("RcppFrame::RcppFrame: invalid data frame.");
+ int ncol = Rf_length(df);
+ SEXP names = Rf_getAttrib(df, R_NamesSymbol);
+ colNames.resize(ncol);
+ SEXP colData = VECTOR_ELT(df,0); // First column of data.
+ int nrow = Rf_length(colData);
+ if (nrow == 0)
+ throw std::range_error("RcppFrame::RcppFrame: zero lenth column.");
+
+ // Allocate storage for table.
+ table.resize(nrow);
+ for (int r = 0; r < nrow; r++)
+ table[r].resize(ncol);
+
+ for (int i=0; i < ncol; i++) {
+ colNames[i] = std::string(CHAR(STRING_ELT(names,i)));
+ SEXP colData = VECTOR_ELT(df,i);
+ if (!Rf_isVector(colData) || Rf_length(colData) != nrow)
+ throw std::range_error("RcppFrame::RcppFrame: invalid column.");
+
+ // Check for Date class. Currently R stores the date ordinal in a
+ // real value. We check for Date under both Real and Integer values
+ // as insurance against future changes.
+ bool isDateClass = false;
+ SEXP classname = Rf_getAttrib(colData, R_ClassSymbol);
+ if (classname != R_NilValue)
+ isDateClass = (strcmp(CHAR(STRING_ELT(classname,0)),"Date") == 0);
+
+ if (Rf_isReal(colData)) {
+ if (isDateClass) {
+ for (int j=0; j < nrow; j++) // Column of Date's
+ table[j][i].setDateValue(RcppDate((int)REAL(colData)[j]));
+ }
+ else // Column of REAL's
+ for (int j=0; j < nrow; j++)
+ table[j][i].setDoubleValue(REAL(colData)[j]);
+ }
+ else if (Rf_isInteger(colData)) {
+ if (isDateClass) {
+ for (int j=0; j < nrow; j++) // Column of Date's
+ table[j][i].setDateValue(RcppDate(INTEGER(colData)[j]));
+ }
+ else
+ for (int j=0; j < nrow; j++)
+ table[j][i].setIntValue(INTEGER(colData)[j]);
+ }
+ else if (Rf_isString(colData)) { // Non-factor string column
+ for (int j=0; j < nrow; j++)
+ table[j][i].setStringValue(std::string(CHAR(STRING_ELT(colData,j))));
+ }
+ else if (Rf_isFactor(colData)) { // Factor column.
+ SEXP names = Rf_getAttrib(colData, R_LevelsSymbol);
+ int numLevels = Rf_length(names);
+ std::string *levelNames = new std::string[numLevels];
+ for (int k=0; k < numLevels; k++)
+ levelNames[k] = std::string(CHAR(STRING_ELT(names,k)));
+ for (int j=0; j < nrow; j++)
+ table[j][i].setFactorValue(levelNames, numLevels,
+ INTEGER(colData)[j]);
+ delete [] levelNames;
+ }
+ else if (Rf_isLogical(colData)) {
+ for (int j=0; j < nrow; j++) {
+ table[j][i].setLogicalValue(INTEGER(colData)[j]);
+ }
+ }
+ else
+ throw std::range_error("RcppFrame::RcppFrame: unsupported data frame column type.");
+ }
+}
+
+std::vector<std::string>& RcppFrame::getColNames() {
+ return colNames;
+}
+
+std::vector<std::vector<ColDatum> >& RcppFrame::getTableData() {
+ return table;
+}
+
+void RcppFrame::addRow(std::vector<ColDatum> rowData) {
+ if (rowData.size() != colNames.size())
+ throw std::range_error("RcppFrame::addRow: incorrect row length.");
+ if (table.size() > 0) {
+
+ // First row added determines column types. Check for consistency
+ // for rows after the first...
+ for (int i = 0; i < (int)colNames.size(); i++) {
+ if (rowData[i].getType() != table[0][i].getType()) {
+ std::ostringstream oss;
+ oss << "RcppFrame::addRow: incorrect data type at posn "
+ << i;
+ throw std::range_error(oss.str());
+ }
+ }
+ }
+ table.push_back(rowData);
+}
+
+int RcppFrame::rows() {
+ return table.size();
+}
+
+int RcppFrame::cols() {
+ return table[0].size();
+}
+
+
Added: pkg/src/RcppFrame.h
===================================================================
--- pkg/src/RcppFrame.h (rev 0)
+++ pkg/src/RcppFrame.h 2009-11-11 00:39:54 UTC (rev 171)
@@ -0,0 +1,91 @@
+// -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; tab-width: 8 -*-
+//
+// RcppFrame.h: Rcpp R/C++ interface class library -- data.framee support
+//
+// Copyright (C) 2005 - 2006 Dominick Samperi
+// Copyright (C) 2008 - 2009 Dirk Eddelbuettel
+//
+// This library is free software; you can redistribute it and/or modify it
+// under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation; either version 2.1 of the License, or (at
+// your option) any later version.
+//
+// This library is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+// License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this library; if not, write to the Free Software Foundation,
+// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+#ifndef RcppFrame_h
+#define RcppFrame_h
+
+#include <RcppCommon.h>
+#include <RcppDate.h>
+#include <RcppDatetime.h>
+
+enum ColType { // Supported data frame column types.
+ COLTYPE_DOUBLE, COLTYPE_INT, COLTYPE_STRING,
+ COLTYPE_FACTOR, COLTYPE_LOGICAL,
+ COLTYPE_DATE, COLTYPE_DATETIME
+};
+class ColDatum; // forward declaration, see below
+
+class RcppFrame {
+ std::vector<std::string> colNames;
+ std::vector<std::vector<ColDatum> > table; // table[row][col]
+
+public:
+ RcppFrame(SEXP df); // Construct from R data frame.
+ RcppFrame(std::vector<std::string> colNames);
+ std::vector<std::string>& getColNames();
+ std::vector<std::vector<ColDatum> >& getTableData();
+ void addRow(std::vector<ColDatum> rowData);
+ int rows();
+ int cols();
+};
+
+
+class ColDatum {
+public:
+ ColDatum();
+ ColDatum(const ColDatum& datum);
+ ~ColDatum();
+
+ ColType getType() const { return type; }
+ void setDoubleValue(double val);
+ void setIntValue(int val);
+ void setLogicalValue(int val);
+ void setStringValue(std::string val);
+ void setDateValue(RcppDate date);
+ void setDatetimeValue(RcppDatetime datetime);
+ void setFactorValue(std::string *names, int numNames, int factorLevel);
+
+ double getDoubleValue();
+ int getIntValue();
+ int getLogicalValue();
+ std::string getStringValue();
+ RcppDate getDateValue();
+ double getDateRCode();
+ RcppDatetime getDatetimeValue();
+ void checkFactorType();
+ int getFactorNumLevels();
+ int getFactorLevel();
+ std::string *getFactorLevelNames();
+ std::string getFactorLevelName();
+
+private:
+ ColType type;
+ std::string s;
+ double x; // used for double and datetime
+ int i; // used for int and logical
+ int level; // factor level
+ int numLevels; // number of levels for this factor
+ std::string *levelNames; // level name = levelNames[level-1]
+ RcppDate d;
+};
+
+
+#endif
More information about the Rcpp-commits
mailing list