Skip to content

Commit c7bc8bf

Browse files
committed
Comments on nrow impl
1 parent fcf7f39 commit c7bc8bf

File tree

1 file changed

+32
-26
lines changed

1 file changed

+32
-26
lines changed

inst/include/Rcpp/DataFrame.h

Lines changed: 32 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
#define Rcpp__DataFrame_h
2424

2525
namespace Rcpp{
26-
26+
2727
namespace internal{
2828
inline SEXP empty_data_frame(){
2929
Shield<SEXP> df( Rf_allocVector(VECSXP, 0) );
@@ -33,33 +33,39 @@ namespace Rcpp{
3333
return df;
3434
}
3535
}
36-
36+
3737
template <template <class> class StoragePolicy>
3838
class DataFrame_Impl : public Vector<VECSXP, StoragePolicy> {
39-
public:
39+
public:
4040
typedef Vector<VECSXP, StoragePolicy> Parent ;
41-
41+
4242
DataFrame_Impl() : Parent( internal::empty_data_frame() ){}
4343
DataFrame_Impl(SEXP x) {
44-
set__(x);
44+
set__(x);
4545
}
4646
DataFrame_Impl( const DataFrame_Impl& other){
47-
set__(other) ;
47+
set__(other) ;
4848
}
49-
49+
5050
template <typename T>
5151
DataFrame_Impl( const T& obj ) ;
52-
52+
5353
DataFrame_Impl& operator=( DataFrame_Impl& other){
54-
if (*this != other) set__(other);
54+
if (*this != other) set__(other);
5555
return *this;
5656
}
57-
57+
5858
DataFrame_Impl& operator=( SEXP x){
5959
set__(x) ;
6060
return *this ;
6161
}
62-
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.
6369
inline int nrows() const {
6470
SEXP rn = R_NilValue ;
6571
SEXP att = ATTRIB( Parent::get__() ) ;
@@ -68,20 +74,20 @@ namespace Rcpp{
6874
rn = CAR(att) ;
6975
break ;
7076
}
71-
att = CDR(att) ;
77+
att = CDR(att) ;
7278
}
7379
if (Rf_isNull(rn))
7480
return 0;
7581
if (TYPEOF(rn) == INTSXP && LENGTH(rn) == 2 && INTEGER(rn)[0] == NA_INTEGER)
7682
return -INTEGER(rn)[1];
7783
return LENGTH(rn);
7884
}
79-
80-
static DataFrame_Impl create(){
81-
return DataFrame_Impl() ;
85+
86+
static DataFrame_Impl create(){
87+
return DataFrame_Impl() ;
8288
}
8389

84-
#include <Rcpp/generated/DataFrame_generated.h>
90+
#include <Rcpp/generated/DataFrame_generated.h>
8591

8692
private:
8793
void set__(SEXP x){
@@ -92,7 +98,7 @@ namespace Rcpp{
9298
Parent::set__( y ) ;
9399
}
94100
}
95-
101+
96102
static DataFrame_Impl from_list( Parent obj ){
97103
bool use_default_strings_as_factors = true ;
98104
bool strings_as_factors = true ;
@@ -103,30 +109,30 @@ namespace Rcpp{
103109
for( int i=0; i<n; i++){
104110
if( names[i] == "stringsAsFactors" ){
105111
strings_as_factors_index = i ;
106-
use_default_strings_as_factors = false ;
112+
use_default_strings_as_factors = false ;
107113
if( !as<bool>(obj[i]) ) strings_as_factors = false ;
108-
break ;
114+
break ;
109115
}
110116
}
111117
}
112-
if( use_default_strings_as_factors )
118+
if( use_default_strings_as_factors )
113119
return DataFrame_Impl(obj) ;
114120
SEXP as_df_symb = Rf_install("as.data.frame");
115121
SEXP strings_as_factors_symb = Rf_install("stringsAsFactors");
116-
122+
117123
obj.erase(strings_as_factors_index) ;
118124
names.erase(strings_as_factors_index) ;
119125
obj.attr( "names") = names ;
120126
Shield<SEXP> call( Rf_lang3(as_df_symb, obj, wrap( strings_as_factors ) ) ) ;
121-
SET_TAG( CDDR(call), strings_as_factors_symb ) ;
122-
Shield<SEXP> res( Rcpp_eval( call ) ) ;
127+
SET_TAG( CDDR(call), strings_as_factors_symb ) ;
128+
Shield<SEXP> res( Rcpp_eval( call ) ) ;
123129
DataFrame_Impl out( res ) ;
124130
return out ;
125-
131+
126132
}
127-
133+
128134
} ;
129-
135+
130136
typedef DataFrame_Impl<PreserveStorage> DataFrame ;
131137
}
132138

0 commit comments

Comments
 (0)