Rcpp Version 1.1.2
Loading...
Searching...
No Matches
DataFrame.h
Go to the documentation of this file.
1
2// DataFrame.h: Rcpp R/C++ interface class library -- data frames
3//
4// Copyright (C) 2010 - 2026 Dirk Eddelbuettel and Romain Francois
5//
6// This file is part of Rcpp.
7//
8// Rcpp is free software: you can redistribute it and/or modify it
9// under the terms of the GNU General Public License as published by
10// the Free Software Foundation, either version 2 of the License, or
11// (at your option) any later version.
12//
13// Rcpp is distributed in the hope that it will be useful, but
14// WITHOUT ANY WARRANTY; without even the implied warranty of
15// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16// GNU General Public License for more details.
17//
18// You should have received a copy of the GNU General Public License
19// along with Rcpp. If not, see <http://www.gnu.org/licenses/>.
20
21#ifndef Rcpp__DataFrame_h
22#define Rcpp__DataFrame_h
23
24namespace Rcpp{
25
26 namespace internal{
27 inline SEXP empty_data_frame(){
28 Shield<SEXP> df( Rf_allocVector(VECSXP, 0) );
29 Rf_setAttrib(df, R_NamesSymbol, Rf_allocVector(STRSXP, 0));
30 Rf_setAttrib(df, R_RowNamesSymbol, Rf_allocVector(INTSXP, 0));
31 Rf_setAttrib(df, R_ClassSymbol, Rf_mkString("data.frame"));
32 return df;
33 }
34 }
35
36 template <template <class> class StoragePolicy>
37 class DataFrame_Impl : public Vector<VECSXP, StoragePolicy> {
38 public:
40
41 DataFrame_Impl() : Parent( internal::empty_data_frame() ){}
42 DataFrame_Impl(SEXP x) : Parent(x) {
43 set__(x);
44 }
46 set__(other) ;
47 }
48
49 template <typename T>
50 DataFrame_Impl( const T& obj ) ;
51
53 if (*this != other) set__(other);
54 return *this;
55 }
56
58 set__(x) ;
59 return *this ;
60 }
61
62 // By definition, the number of rows in a data.frame is contained
63 // in its row.names attribute. Since R 3.5.0 this is returned as a
64 // compact sequence from which we can just take the (x)length
65 // But as this makes an allocation an even simpler check on length as
66 // discussed in #1430 is also possible and preferable. We also switch
67 // to returning R_xlen_t which as upcast from int is safe
68 inline R_xlen_t nrow() const {
69#if R_VERSION < R_Version(4,6,0)
70 Shield<SEXP> rn{Rf_getAttrib(Parent::get__(), R_RowNamesSymbol)};
71 return Rf_xlength(rn);
72#else
73 return R_nrow(Parent::get__());
74#endif
75 }
76
77 template <typename T>
78 void push_back( const T& object){
79 Parent::push_back(object);
81 }
82
83 template <typename T>
84 void push_back( const T& object, const std::string& name ){
85 Parent::push_back(object, name);
87 }
88
89 template <typename T>
90 void push_front( const T& object){
91 Parent::push_front(object);
93 }
94
95 template <typename T>
96 void push_front( const T& object, const std::string& name){
97 Parent::push_front(object, name);
99 }
100
101 // Offer multiple variants to accomodate both old interface here and signatures in other classes
102 inline R_xlen_t nrows() const { return DataFrame_Impl::nrow(); }
103 inline R_xlen_t rows() const { return DataFrame_Impl::nrow(); }
104
105 inline R_xlen_t ncol() const { return DataFrame_Impl::length(); }
106 inline R_xlen_t cols() const { return DataFrame_Impl::length(); }
107
109 return DataFrame_Impl() ;
110 }
111 template <typename... T>
112 static DataFrame_Impl create(const T&... args) {
114 }
115
116 private:
117 void set__(SEXP x){
118 if( ::Rf_inherits( x, "data.frame" )){
119 Parent::set__( x ) ;
120 } else{
121 Shield<SEXP> y(internal::convert_using_rfunction( x, "as.data.frame" )) ;
122 Parent::set__( y ) ;
123 }
124 }
125
127 R_xlen_t max_rows = 0;
128 bool invalid_column_size = false;
130 // Get the maximum number of rows
131 for (it = Parent::begin(); it != Parent::end(); ++it) {
132 if (Rf_xlength(*it) > max_rows) {
133 max_rows = Rf_xlength(*it);
134 }
135 }
136 if (max_rows > 0) {
137 for (it = Parent::begin(); it != Parent::end(); ++it) {
138 if (Rf_xlength(*it) == 0 || ( Rf_xlength(*it) > 1 && max_rows % Rf_xlength(*it) != 0 )) {
139 // We have a column that is not an integer fraction of the largest
140 invalid_column_size = true;
141 }
142 }
143 }
144 if (invalid_column_size) {
145 warning("Column sizes are not equal in DataFrame::push_back, object degrading to List\n");
146 } else {
148 }
149 }
150
152 bool use_default_strings_as_factors = true ;
153 bool strings_as_factors = true ;
154 int strings_as_factors_index = -1 ;
155 R_xlen_t n = obj.size() ;
156 CharacterVector names = obj.attr( "names" ) ;
157 if( !names.isNULL() ){
158 for( int i=0; i<n; i++){
159 if( names[i] == "stringsAsFactors" ){
160 strings_as_factors_index = i ;
161 use_default_strings_as_factors = false ;
162 if( !as<bool>(obj[i]) ) strings_as_factors = false ;
163 break ;
164 }
165 }
166 }
167 if( use_default_strings_as_factors )
168 return DataFrame_Impl(obj) ;
169 SEXP as_df_symb = Rf_install("as.data.frame");
170 SEXP strings_as_factors_symb = Rf_install("stringsAsFactors");
171
172 obj.erase(strings_as_factors_index) ;
173 names.erase(strings_as_factors_index) ;
174 obj.attr( "names") = names ;
175 Shield<SEXP> call( Rf_lang3(as_df_symb, obj, Rf_ScalarLogical(strings_as_factors) ) ) ;
176 SET_TAG( CDDR(call), strings_as_factors_symb ) ;
177 Shield<SEXP> res(Rcpp_fast_eval(call, R_GlobalEnv));
178 DataFrame_Impl out( res ) ;
179 return out ;
180
181 }
182
183 } ;
184
186}
187
188#endif
AttributeProxy attr(const std::string &name)
static DataFrame_Impl from_list(Parent obj)
Definition DataFrame.h:151
void push_back(const T &object)
Definition DataFrame.h:78
R_xlen_t cols() const
Definition DataFrame.h:106
DataFrame_Impl(const T &obj)
Definition DataFrame.h:25
void push_front(const T &object)
Definition DataFrame.h:90
R_xlen_t rows() const
Definition DataFrame.h:103
DataFrame_Impl(const DataFrame_Impl &other)
Definition DataFrame.h:45
Vector< VECSXP, StoragePolicy > Parent
Definition DataFrame.h:39
DataFrame_Impl & operator=(DataFrame_Impl &other)
Definition DataFrame.h:52
void push_front(const T &object, const std::string &name)
Definition DataFrame.h:96
R_xlen_t nrow() const
Definition DataFrame.h:68
static DataFrame_Impl create()
Definition DataFrame.h:108
void push_back(const T &object, const std::string &name)
Definition DataFrame.h:84
void set__(SEXP x)
Definition DataFrame.h:117
R_xlen_t nrows() const
Definition DataFrame.h:102
R_xlen_t ncol() const
Definition DataFrame.h:105
static DataFrame_Impl create(const T &... args)
Definition DataFrame.h:112
DataFrame_Impl & operator=(SEXP x)
Definition DataFrame.h:57
iterator erase(int position)
Definition Vector.h:504
R_xlen_t size() const
Definition Vector.h:274
void push_back(const T &object)
Definition Vector.h:464
void push_front(const T &object)
Definition Vector.h:478
iterator begin()
Definition Vector.h:332
static Vector create()
Definition Vector.h:1134
traits::r_vector_iterator< RTYPE, PreserveStorage >::type iterator
Definition Vector.h:46
internal implementation details
Definition Date.h:43
SEXP empty_data_frame()
Definition DataFrame.h:27
SEXP convert_using_rfunction(SEXP x, const char *const fun)
Definition r_cast.h:29
Rcpp API.
Definition algo.h:28
Vector< STRSXP > CharacterVector
SEXP Rcpp_fast_eval(SEXP expr, SEXP env)
Definition Rcpp_eval.h:49
DataFrame_Impl< PreserveStorage > DataFrame
Definition DataFrame.h:185
T as(SEXP x)
Definition as.h:150
void warning(const std::string &message)
Definition exceptions.h:115