66 - The replacement of NAs with non-NA values from subsequent vectors
77 - The conditional checks within parallelized loops
88*/
9- SEXP coalesce (SEXP x , SEXP inplaceArg ) {
9+ SEXP coalesce (SEXP x , SEXP inplaceArg , SEXP nan_is_na_arg ) {
1010 if (TYPEOF (x )!= VECSXP ) internal_error (__func__ , "input is list(...) at R level" ); // # nocov
1111 if (!IS_TRUE_OR_FALSE (inplaceArg )) internal_error (__func__ , "argument 'inplaceArg' must be TRUE or FALSE" ); // # nocov
12+ if (!IS_TRUE_OR_FALSE (nan_is_na_arg )) internal_error (__func__ , "argument 'nan_is_na_arg' must be TRUE or FALSE" ); // # nocov
1213 const bool inplace = LOGICAL (inplaceArg )[0 ];
14+ const bool nan_is_na = LOGICAL (nan_is_na_arg )[0 ];
1315 const bool verbose = GetVerbose ();
1416 int nprotect = 0 ;
1517 if (length (x )== 0 || isNull (VECTOR_ELT (x ,0 ))) return R_NilValue ; // coalesce(NULL, "foo") return NULL even though character type mismatches type NULL
@@ -106,7 +108,7 @@ SEXP coalesce(SEXP x, SEXP inplaceArg) {
106108 SEXP item = VECTOR_ELT (x , j + off );
107109 if (length (item )== 1 ) {
108110 double tt = REAL (item )[0 ];
109- if (ISNAN (tt )) continue ;
111+ if (nan_is_na ? ISNAN ( tt ) : ISNA (tt )) continue ;
110112 finalVal = tt ;
111113 break ;
112114 }
@@ -116,9 +118,9 @@ SEXP coalesce(SEXP x, SEXP inplaceArg) {
116118 #pragma omp parallel for num_threads(getDTthreads(nrow, true))
117119 for (int i = 0 ; i < nrow ; ++ i ) {
118120 double val = xP [i ];
119- if (!ISNAN (val )) continue ;
120- int j = 0 ; while (ISNAN (val ) && j < k ) val = ((double * )valP [j ++ ])[i ];
121- if (!ISNAN (val )) xP [i ]= val ; else if (final ) xP [i ]= finalVal ;
121+ if (!( nan_is_na ? ISNAN (val ) : ISNA ( val ) )) continue ;
122+ int j = 0 ; while (( nan_is_na ? ISNAN (val ) : ISNA ( val ) ) && j < k ) val = ((double * )valP [j ++ ])[i ];
123+ if (!( nan_is_na ? ISNAN (val ) : ISNA ( val ) )) xP [i ]= val ; else if (final ) xP [i ]= finalVal ;
122124 }
123125 }
124126 } break ;
0 commit comments