Rcpp Version 0.12.12
DataFrame.h
Go to the documentation of this file.
1 // -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; indent-tabs-mode: nil; -*-
2 //
3 // DataFrame.h: Rcpp R/C++ interface class library -- data frames
4 //
5 // Copyright (C) 2010 - 2015 Dirk Eddelbuettel and Romain Francois
6 //
7 // This file is part of Rcpp.
8 //
9 // Rcpp is free software: you can redistribute it and/or modify it
10 // under the terms of the GNU General Public License as published by
11 // the Free Software Foundation, either version 2 of the License, or
12 // (at your option) any later version.
13 //
14 // Rcpp is distributed in the hope that it will be useful, but
15 // WITHOUT ANY WARRANTY; without even the implied warranty of
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 // GNU General Public License for more details.
18 //
19 // You should have received a copy of the GNU General Public License
20 // along with Rcpp. If not, see <http://www.gnu.org/licenses/>.
21 
22 #ifndef Rcpp__DataFrame_h
23 #define Rcpp__DataFrame_h
24 
25 namespace Rcpp{
26 
27  namespace internal{
28  inline SEXP empty_data_frame(){
29  Shield<SEXP> df( Rf_allocVector(VECSXP, 0) );
30  Rf_setAttrib(df, R_NamesSymbol, Rf_allocVector(STRSXP, 0));
31  Rf_setAttrib(df, R_RowNamesSymbol, Rf_allocVector(INTSXP, 0));
32  Rf_setAttrib(df, R_ClassSymbol, Rf_mkString("data.frame"));
33  return df;
34  }
35  }
36 
37  template <template <class> class StoragePolicy>
38  class DataFrame_Impl : public Vector<VECSXP, StoragePolicy> {
39  public:
41 
42  DataFrame_Impl() : Parent( internal::empty_data_frame() ){}
43  DataFrame_Impl(SEXP x) : Parent(x) {
44  set__(x);
45  }
46  DataFrame_Impl( const DataFrame_Impl& other) : Parent() {
47  set__(other) ;
48  }
49 
50  template <typename T>
51  DataFrame_Impl( const T& obj ) ;
52 
54  if (*this != other) set__(other);
55  return *this;
56  }
57 
59  set__(x) ;
60  return *this ;
61  }
62 
63  // By definition, the number of rows in a data.frame is contained
64  // in its row.names attribute. If it has row names of the form 1:n,
65  // they will be stored as {NA_INTEGER, -<nrow>}. Unfortunately,
66  // getAttrib(df, R_RowNamesSymbol) will force an expansion of that
67  // compact form thereby allocating a huge vector when we just want
68  // the row.names. Hence this workaround.
69  inline int nrow() const {
70  SEXP rn = R_NilValue ;
71  SEXP att = ATTRIB( Parent::get__() ) ;
72  while( att != R_NilValue ){
73  if( TAG(att) == R_RowNamesSymbol ) {
74  rn = CAR(att) ;
75  break ;
76  }
77  att = CDR(att) ;
78  }
79  if (Rf_isNull(rn))
80  return 0;
81  if (TYPEOF(rn) == INTSXP && LENGTH(rn) == 2 && INTEGER(rn)[0] == NA_INTEGER)
82  return abs(INTEGER(rn)[1]);
83  return LENGTH(rn);
84  }
85 
86  // Offer multiple variants to accomodate both old interface here and signatures in other classes
87  inline int nrows() const { return DataFrame_Impl::nrow(); }
88  inline int rows() const { return DataFrame_Impl::nrow(); }
89 
90  inline R_xlen_t ncol() const { return DataFrame_Impl::length(); }
91  inline R_xlen_t cols() const { return DataFrame_Impl::length(); }
92 
94  return DataFrame_Impl() ;
95  }
96 
97  #include <Rcpp/generated/DataFrame_generated.h>
98 
99  private:
100  void set__(SEXP x){
101  if( ::Rf_inherits( x, "data.frame" )){
102  Parent::set__( x ) ;
103  } else{
104  SEXP y = internal::convert_using_rfunction( x, "as.data.frame" ) ;
105  Parent::set__( y ) ;
106  }
107  }
108 
109  static DataFrame_Impl from_list( Parent obj ){
110  bool use_default_strings_as_factors = true ;
111  bool strings_as_factors = true ;
112  int strings_as_factors_index = -1 ;
113  R_xlen_t n = obj.size() ;
114  CharacterVector names = obj.attr( "names" ) ;
115  if( !names.isNULL() ){
116  for( int i=0; i<n; i++){
117  if( names[i] == "stringsAsFactors" ){
118  strings_as_factors_index = i ;
119  use_default_strings_as_factors = false ;
120  if( !as<bool>(obj[i]) ) strings_as_factors = false ;
121  break ;
122  }
123  }
124  }
125  if( use_default_strings_as_factors )
126  return DataFrame_Impl(obj) ;
127  SEXP as_df_symb = Rf_install("as.data.frame");
128  SEXP strings_as_factors_symb = Rf_install("stringsAsFactors");
129 
130  obj.erase(strings_as_factors_index) ;
131  names.erase(strings_as_factors_index) ;
132  obj.attr( "names") = names ;
133  Shield<SEXP> call( Rf_lang3(as_df_symb, obj, wrap( strings_as_factors ) ) ) ;
134  SET_TAG( CDDR(call), strings_as_factors_symb ) ;
135  Shield<SEXP> res( Rcpp_eval( call ) ) ;
136  DataFrame_Impl out( res ) ;
137  return out ;
138 
139  }
140 
141  } ;
142 
144 }
145 
146 #endif
AttributeProxy attr(const std::string &name)
int nrows() const
Definition: DataFrame.h:87
int rows() const
Definition: DataFrame.h:88
R_xlen_t ncol() const
Definition: DataFrame.h:90
Vector< VECSXP, StoragePolicy > Parent
Definition: DataFrame.h:40
iterator erase(int position)
Definition: Vector.h:488
void set__(SEXP x)
Definition: DataFrame.h:100
SEXP Rcpp_eval(SEXP expr, SEXP env)
Definition: Rcpp_eval.h:25
bool isNULL() const
DataFrame_Impl & operator=(DataFrame_Impl &other)
Definition: DataFrame.h:53
static DataFrame_Impl create()
Definition: DataFrame.h:93
double df(double x, double df1, double df2, int lg)
Definition: Rmath.h:84
R_xlen_t size() const
Definition: Vector.h:274
DataFrame_Impl(SEXP x)
Definition: DataFrame.h:43
DataFrame_Impl(const DataFrame_Impl &other)
Definition: DataFrame.h:46
SEXP wrap(const Date &date)
Definition: Date.h:38
SEXP empty_data_frame()
Definition: DataFrame.h:28
int nrow() const
Definition: DataFrame.h:69
DataFrame_Impl< PreserveStorage > DataFrame
Definition: DataFrame.h:143
Rcpp API.
Definition: algo.h:28
DataFrame_Impl & operator=(SEXP x)
Definition: DataFrame.h:58
SEXP convert_using_rfunction(SEXP x, const char *const fun)
Definition: r_cast.h:30
R_xlen_t cols() const
Definition: DataFrame.h:91
static DataFrame_Impl from_list(Parent obj)
Definition: DataFrame.h:109