11#include "data.table.h"
22
3- void nafillDouble (double * x , uint_fast64_t nx , unsigned int type , double fill , bool nan_is_na , ans_t * ans , bool verbose ) {
3+ void nafillDouble (double * x , uint_fast64_t nx , unsigned int type , double fill , bool nan_is_na , ans_t * ans , bool verbose , double limit ) {
44 double tic = 0.0 ;
55 if (verbose )
66 tic = omp_get_wtime ();
@@ -15,34 +15,52 @@ void nafillDouble(double *x, uint_fast64_t nx, unsigned int type, double fill, b
1515 }
1616 }
1717 } else if (type == 1 ) { // locf
18+ uint_fast64_t fills = 0 ;
1819 if (nan_is_na ) {
1920 ans -> dbl_v [0 ] = ISNAN (x [0 ]) ? fill : x [0 ];
21+ if (ISNAN (x [0 ])) fills = 1 ;
2022 for (uint_fast64_t i = 1 ; i < nx ; i ++ ) {
21- ans -> dbl_v [i ] = ISNAN (x [i ]) ? ans -> dbl_v [i - 1 ] : x [i ];
23+ if (ISNAN (x [i ])) {
24+ if (fills < limit ) { ans -> dbl_v [i ] = ans -> dbl_v [i - 1 ]; fills ++ ; }
25+ else ans -> dbl_v [i ] = x [i ];
26+ } else { ans -> dbl_v [i ] = x [i ]; fills = 0 ; }
2227 }
2328 } else {
2429 ans -> dbl_v [0 ] = ISNA (x [0 ]) ? fill : x [0 ];
30+ if (ISNA (x [0 ])) fills = 1 ;
2531 for (uint_fast64_t i = 1 ; i < nx ; i ++ ) {
26- ans -> dbl_v [i ] = ISNA (x [i ]) ? ans -> dbl_v [i - 1 ] : x [i ];
32+ if (ISNA (x [i ])) {
33+ if (fills < limit ) { ans -> dbl_v [i ] = ans -> dbl_v [i - 1 ]; fills ++ ; }
34+ else ans -> dbl_v [i ] = x [i ];
35+ } else { ans -> dbl_v [i ] = x [i ]; fills = 0 ; }
2736 }
2837 }
2938 } else if (type == 2 ) { // nocb
39+ uint_fast64_t fills = 0 ;
3040 if (nan_is_na ) {
3141 ans -> dbl_v [nx - 1 ] = ISNAN (x [nx - 1 ]) ? fill : x [nx - 1 ];
42+ if (ISNAN (x [nx - 1 ])) fills = 1 ;
3243 for (int_fast64_t i = nx - 2 ; i >=0 ; i -- ) {
33- ans -> dbl_v [i ] = ISNAN (x [i ]) ? ans -> dbl_v [i + 1 ] : x [i ];
44+ if (ISNAN (x [i ])) {
45+ if (fills < limit ) { ans -> dbl_v [i ] = ans -> dbl_v [i + 1 ]; fills ++ ; }
46+ else ans -> dbl_v [i ] = x [i ];
47+ } else { ans -> dbl_v [i ] = x [i ]; fills = 0 ; }
3448 }
3549 } else {
3650 ans -> dbl_v [nx - 1 ] = ISNA (x [nx - 1 ]) ? fill : x [nx - 1 ];
51+ if (ISNA (x [nx - 1 ])) fills = 1 ;
3752 for (int_fast64_t i = nx - 2 ; i >=0 ; i -- ) {
38- ans -> dbl_v [i ] = ISNA (x [i ]) ? ans -> dbl_v [i + 1 ] : x [i ];
53+ if (ISNA (x [i ])) {
54+ if (fills < limit ) { ans -> dbl_v [i ] = ans -> dbl_v [i + 1 ]; fills ++ ; }
55+ else ans -> dbl_v [i ] = x [i ];
56+ } else { ans -> dbl_v [i ] = x [i ]; fills = 0 ; }
3957 }
4058 }
4159 }
4260 if (verbose )
4361 snprintf (ans -> message [0 ], 500 , _ ("%s: took %.3fs\n" ), __func__ , omp_get_wtime ()- tic );
4462}
45- void nafillInteger (int32_t * x , uint_fast64_t nx , unsigned int type , int32_t fill , ans_t * ans , bool verbose ) {
63+ void nafillInteger (int32_t * x , uint_fast64_t nx , unsigned int type , int32_t fill , ans_t * ans , bool verbose , double limit ) {
4664 double tic = 0.0 ;
4765 if (verbose )
4866 tic = omp_get_wtime ();
@@ -51,20 +69,30 @@ void nafillInteger(int32_t *x, uint_fast64_t nx, unsigned int type, int32_t fill
5169 ans -> int_v [i ] = x [i ]== NA_INTEGER ? fill : x [i ];
5270 }
5371 } else if (type == 1 ) { // locf
72+ uint_fast64_t fills = 0 ;
5473 ans -> int_v [0 ] = x [0 ]== NA_INTEGER ? fill : x [0 ];
74+ if (x [0 ]== NA_INTEGER ) fills = 1 ;
5575 for (uint_fast64_t i = 1 ; i < nx ; i ++ ) {
56- ans -> int_v [i ] = x [i ]== NA_INTEGER ? ans -> int_v [i - 1 ] : x [i ];
76+ if (x [i ]== NA_INTEGER ) {
77+ if (fills < limit ) { ans -> int_v [i ] = ans -> int_v [i - 1 ]; fills ++ ; }
78+ else ans -> int_v [i ] = x [i ];
79+ } else { ans -> int_v [i ] = x [i ]; fills = 0 ; }
5780 }
5881 } else if (type == 2 ) { // nocb
82+ uint_fast64_t fills = 0 ;
5983 ans -> int_v [nx - 1 ] = x [nx - 1 ]== NA_INTEGER ? fill : x [nx - 1 ];
84+ if (x [nx - 1 ]== NA_INTEGER ) fills = 1 ;
6085 for (int_fast64_t i = nx - 2 ; i >=0 ; i -- ) {
61- ans -> int_v [i ] = x [i ]== NA_INTEGER ? ans -> int_v [i + 1 ] : x [i ];
86+ if (x [i ]== NA_INTEGER ) {
87+ if (fills < limit ) { ans -> int_v [i ] = ans -> int_v [i + 1 ]; fills ++ ; }
88+ else ans -> int_v [i ] = x [i ];
89+ } else { ans -> int_v [i ] = x [i ]; fills = 0 ; }
6290 }
6391 }
6492 if (verbose )
6593 snprintf (ans -> message [0 ], 500 , _ ("%s: took %.3fs\n" ), __func__ , omp_get_wtime ()- tic );
6694}
67- void nafillInteger64 (int64_t * x , uint_fast64_t nx , unsigned int type , int64_t fill , ans_t * ans , bool verbose ) {
95+ void nafillInteger64 (int64_t * x , uint_fast64_t nx , unsigned int type , int64_t fill , ans_t * ans , bool verbose , double limit ) {
6896 double tic = 0.0 ;
6997 if (verbose )
7098 tic = omp_get_wtime ();
@@ -73,21 +101,31 @@ void nafillInteger64(int64_t *x, uint_fast64_t nx, unsigned int type, int64_t fi
73101 ans -> int64_v [i ] = x [i ]== NA_INTEGER64 ? fill : x [i ];
74102 }
75103 } else if (type == 1 ) { // locf
104+ uint_fast64_t fills = 0 ;
76105 ans -> int64_v [0 ] = x [0 ]== NA_INTEGER64 ? fill : x [0 ];
106+ if (x [0 ]== NA_INTEGER64 ) fills = 1 ;
77107 for (uint_fast64_t i = 1 ; i < nx ; i ++ ) {
78- ans -> int64_v [i ] = x [i ]== NA_INTEGER64 ? ans -> int64_v [i - 1 ] : x [i ];
108+ if (x [i ]== NA_INTEGER64 ) {
109+ if (fills < limit ) { ans -> int64_v [i ] = ans -> int64_v [i - 1 ]; fills ++ ; }
110+ else ans -> int64_v [i ] = x [i ];
111+ } else { ans -> int64_v [i ] = x [i ]; fills = 0 ; }
79112 }
80113 } else if (type == 2 ) { // nocb
114+ uint_fast64_t fills = 0 ;
81115 ans -> int64_v [nx - 1 ] = x [nx - 1 ]== NA_INTEGER64 ? fill : x [nx - 1 ];
116+ if (x [nx - 1 ]== NA_INTEGER64 ) fills = 1 ;
82117 for (int_fast64_t i = nx - 2 ; i >=0 ; i -- ) {
83- ans -> int64_v [i ] = x [i ]== NA_INTEGER64 ? ans -> int64_v [i + 1 ] : x [i ];
118+ if (x [i ]== NA_INTEGER64 ) {
119+ if (fills < limit ) { ans -> int64_v [i ] = ans -> int64_v [i + 1 ]; fills ++ ; }
120+ else ans -> int64_v [i ] = x [i ];
121+ } else { ans -> int64_v [i ] = x [i ]; fills = 0 ; }
84122 }
85123 }
86124 if (verbose )
87125 snprintf (ans -> message [0 ], 500 , _ ("%s: took %.3fs\n" ), __func__ , omp_get_wtime ()- tic );
88126}
89127
90- void nafillString (const SEXP * x , uint_fast64_t nx , unsigned int type , SEXP fill , ans_t * ans , bool verbose ) {
128+ void nafillString (const SEXP * x , uint_fast64_t nx , unsigned int type , SEXP fill , ans_t * ans , bool verbose , double limit ) {
91129 double tic = 0.0 ;
92130 if (verbose )
93131 tic = omp_get_wtime ();
@@ -96,16 +134,26 @@ void nafillString(const SEXP *x, uint_fast64_t nx, unsigned int type, SEXP fill,
96134 SET_STRING_ELT (ans -> char_v , i , x [i ]== NA_STRING ? fill : x [i ]);
97135 }
98136 } else if (type == 1 ) { // locf
137+ uint_fast64_t fills = 0 ;
99138 SET_STRING_ELT (ans -> char_v , 0 , x [0 ]== NA_STRING ? fill : x [0 ]);
139+ if (x [0 ]== NA_STRING ) fills = 1 ;
100140 const SEXP * thisans = SEXPPTR_RO (ans -> char_v ); // takes out STRING_ELT from loop
101141 for (uint_fast64_t i = 1 ; i < nx ; i ++ ) {
102- SET_STRING_ELT (ans -> char_v , i , x [i ]== NA_STRING ? thisans [i - 1 ] : x [i ]);
142+ if (x [i ]== NA_STRING ) {
143+ if (fills < limit ) { SET_STRING_ELT (ans -> char_v , i , thisans [i - 1 ]); fills ++ ; }
144+ else SET_STRING_ELT (ans -> char_v , i , x [i ]);
145+ } else { SET_STRING_ELT (ans -> char_v , i , x [i ]); fills = 0 ; }
103146 }
104147 } else if (type == 2 ) { // nocb
148+ uint_fast64_t fills = 0 ;
105149 SET_STRING_ELT (ans -> char_v , nx - 1 , x [nx - 1 ]== NA_STRING ? fill : x [nx - 1 ]);
150+ if (x [nx - 1 ]== NA_STRING ) fills = 1 ;
106151 const SEXP * thisans = SEXPPTR_RO (ans -> char_v ); // takes out STRING_ELT from loop
107152 for (int_fast64_t i = nx - 2 ; i >=0 ; i -- ) {
108- SET_STRING_ELT (ans -> char_v , i , x [i ]== NA_STRING ? thisans [i + 1 ] : x [i ]);
153+ if (x [i ]== NA_STRING ) {
154+ if (fills < limit ) { SET_STRING_ELT (ans -> char_v , i , thisans [i + 1 ]); fills ++ ; }
155+ else SET_STRING_ELT (ans -> char_v , i , x [i ]);
156+ } else { SET_STRING_ELT (ans -> char_v , i , x [i ]); fills = 0 ; }
109157 }
110158 }
111159 if (verbose )
@@ -117,7 +165,7 @@ void nafillString(const SEXP *x, uint_fast64_t nx, unsigned int type, SEXP fill,
117165 over columns of the input data. This includes handling different data types
118166 and applying the designated filling method to each column in parallel.
119167*/
120- SEXP nafillR (SEXP obj , SEXP type , SEXP fill , SEXP nan_is_na_arg , SEXP inplace , SEXP cols ) {
168+ SEXP nafillR (SEXP obj , SEXP type , SEXP fill , SEXP nan_is_na_arg , SEXP inplace , SEXP cols , SEXP limit ) {
121169 int protecti = 0 ;
122170 const bool verbose = GetVerbose ();
123171
@@ -128,6 +176,8 @@ SEXP nafillR(SEXP obj, SEXP type, SEXP fill, SEXP nan_is_na_arg, SEXP inplace, S
128176 if (verbose )
129177 tic = omp_get_wtime ();
130178
179+ double limit_val = REAL (limit )[0 ];
180+
131181 bool copy = !LOGICAL (inplace )[0 ];
132182 if (!IS_TRUE_OR_FALSE (nan_is_na_arg ))
133183 error (_ ("'%s' must be TRUE or FALSE" ), "nan_is_na" ); // # nocov
@@ -253,16 +303,16 @@ SEXP nafillR(SEXP obj, SEXP type, SEXP fill, SEXP nan_is_na_arg, SEXP inplace, S
253303 switch (TYPEOF (VECTOR_ELT (x , i ))) {
254304 case REALSXP : {
255305 if (isInt64 [i ]) {
256- nafillInteger64 (i64x [i ], inx [i ], itype , hasFill ? ((int64_t * )fillp [i ])[0 ] : NA_INTEGER64 , & vans [i ], verbose );
306+ nafillInteger64 (i64x [i ], inx [i ], itype , hasFill ? ((int64_t * )fillp [i ])[0 ] : NA_INTEGER64 , & vans [i ], verbose , limit_val );
257307 } else {
258- nafillDouble (dx [i ], inx [i ], itype , hasFill ? ((double * )fillp [i ])[0 ] : NA_REAL , nan_is_na , & vans [i ], verbose );
308+ nafillDouble (dx [i ], inx [i ], itype , hasFill ? ((double * )fillp [i ])[0 ] : NA_REAL , nan_is_na , & vans [i ], verbose , limit_val );
259309 }
260310 } break ;
261311 case LGLSXP : case INTSXP : {
262- nafillInteger (ix [i ], inx [i ], itype , hasFill ? ((int32_t * )fillp [i ])[0 ] : NA_INTEGER , & vans [i ], verbose );
312+ nafillInteger (ix [i ], inx [i ], itype , hasFill ? ((int32_t * )fillp [i ])[0 ] : NA_INTEGER , & vans [i ], verbose , limit_val );
263313 } break ;
264314 case STRSXP : {
265- nafillString (sx [i ], inx [i ], itype , hasFill ? ((SEXP * )fillp [i ])[0 ] : NA_STRING , & vans [i ], verbose );
315+ nafillString (sx [i ], inx [i ], itype , hasFill ? ((SEXP * )fillp [i ])[0 ] : NA_STRING , & vans [i ], verbose , limit_val );
266316 } break ;
267317 }
268318 }
0 commit comments