-
Notifications
You must be signed in to change notification settings - Fork 12
Expand file tree
/
Copy pathDataFrame.h
More file actions
131 lines (108 loc) · 4.47 KB
/
DataFrame.h
File metadata and controls
131 lines (108 loc) · 4.47 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
#ifndef Rcpp__DataFrame_h
#define Rcpp__DataFrame_h
namespace Rcpp{
template < template <class> class StoragePolicy>
class DataFrame_Impl :
public RObjectMethods<DataFrame_Impl<StoragePolicy>>,
public AttributeProxyPolicy<DataFrame_Impl<StoragePolicy>>
{
public:
using List = Vector<VECSXP, StoragePolicy>;
DataFrame_Impl() : data(empty_data_frame()){}
DataFrame_Impl(SEXP x) {
set_sexp(x) ;
}
DataFrame_Impl( const DataFrame_Impl& other) : data(other.data){}
template <typename T>
DataFrame_Impl( const T& obj) : DataFrame_Impl(wrap(obj)){}
template <typename Proxy>
DataFrame_Impl( const GenericProxy<Proxy>& 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 <typename... Args>
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<n; i++){
if( names[i] == "stringsAsFactors" ){
strings_as_factors_index = i ;
use_default_strings_as_factors = false ;
if( !as<bool>(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<SEXP> call = Rf_lang3(as_df_symb, obj, wrap( strings_as_factors ) ) ;
SET_TAG( CDDR(call), strings_as_factors_symb ) ;
Shield<SEXP> res = Rcpp_eval( call ) ;
DataFrame out( res ) ;
return out ;
}
inline SEXP empty_data_frame(){
Shield<SEXP> 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