#ifndef Rcpp__DataFrame_h #define Rcpp__DataFrame_h namespace Rcpp{ template < template class StoragePolicy> class DataFrame_Impl : public RObjectMethods>, public AttributeProxyPolicy> { public: using List = Vector; DataFrame_Impl() : data(empty_data_frame()){} DataFrame_Impl(SEXP x) { set_sexp(x) ; } DataFrame_Impl( const DataFrame_Impl& other) : data(other.data){} template DataFrame_Impl( const T& obj) : DataFrame_Impl(wrap(obj)){} template DataFrame_Impl( const GenericProxy& proxy ) : DataFrame_Impl( proxy.get() ){} DataFrame_Impl& operator=( DataFrame_Impl& other) { data = other.data ; return *this ; } DataFrame_Impl& operator=( SEXP x) { set_sexp(x) ; } inline int size() const { return data.size() ; } int nrows() const { SEXP att = ATTRIB( get() ); while( att != R_NilValue ){ if( TAG(att) == R_RowNamesSymbol ){ SEXP rn = CAR(att) ; if( TYPEOF(rn) == INTSXP && LENGTH(rn) == 2 && INTEGER(rn)[0] == NA_INTEGER ) return abs(INTEGER(rn)[1]) ; return LENGTH(rn) ; } att = CDR(att) ; } return 0 ; } template static DataFrame_Impl create(const Args&... args){ return from_list( List::create( args...) ) ; } inline typename List::Proxy operator[](int i){ return data[i] ; } inline typename List::const_Proxy operator[](int i) const { return data[i] ; } inline typename List::NameProxy operator[]( const std::string& name ){ return data[name] ; } inline typename List::const_NameProxy operator[]( const std::string& name ) const { return data[name] ; } inline operator SEXP() const { return get() ; } private: List data ; void set_sexp(SEXP x) { if( ::Rf_inherits( x, "data.frame" )){ data = x ; } else{ data = internal::convert_using_rfunction( x, "as.data.frame" ) ; } } inline SEXP get() const { return data ; } static DataFrame_Impl from_list( Rcpp::List obj ) { bool use_default_strings_as_factors = true ; bool strings_as_factors = true ; int strings_as_factors_index = -1 ; int n = obj.size() ; CharacterVector names = obj.attr( "names" ) ; if( !names.isNULL() ){ for( int i=0; i(obj[i]) ) strings_as_factors = false ; break ; } } } if( use_default_strings_as_factors ) return DataFrame(obj) ; SEXP as_df_symb = Rf_install("as.data.frame"); SEXP strings_as_factors_symb = Rf_install("stringsAsFactors"); obj.erase(strings_as_factors_index) ; names.erase(strings_as_factors_index) ; obj.attr( "names") = names ; Shield call = Rf_lang3(as_df_symb, obj, wrap( strings_as_factors ) ) ; SET_TAG( CDDR(call), strings_as_factors_symb ) ; Shield res = Rcpp_eval( call ) ; DataFrame out( res ) ; return out ; } inline SEXP empty_data_frame(){ Shield df = Rf_allocVector(VECSXP, 0) ; Rf_setAttrib( df, R_NamesSymbol, Rf_allocVector(STRSXP,0) ) ; Rf_setAttrib( df, R_RowNamesSymbol, Rf_allocVector(STRSXP,0) ) ; Rf_setAttrib( df, R_ClassSymbol, Rf_mkString( "data.frame" ) ); return df ; } } ; } #endif