Skip to content

Commit 2952472

Browse files
duplicate loop for NA and NAN arg
1 parent e8a25cf commit 2952472

File tree

2 files changed

+40
-16
lines changed

2 files changed

+40
-16
lines changed

inst/tests/tests.Rraw

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15570,6 +15570,9 @@ test(2060.154, fcoalesce(list(x)), x)
1557015570
test(2060.155, setcoalesce(list(x)), x)
1557115571
test(2060.156, setcoalesce(list(x,y,z)), ans)
1557215572
test(2060.157, x, ans) # setcoalesce updated the first item (x) by reference
15573+
# nan parameter, #4567
15574+
test(2060.158, fcoalesce(c(NA_real_, NaN), 0, nan=NA), c(0, NaN))
15575+
test(2060.159, fcoalesce(c(NA_real_, NaN), 0, nan=NaN), c(0, 0))
1557315576
# factor of different levels
1557415577
x = factor(c('a','b',NA,NA,'b'))
1557515578
y = factor(c('b','b','a',NA,'b'))

src/coalesce.c

Lines changed: 37 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -104,23 +104,44 @@ SEXP coalesce(SEXP x, SEXP inplaceArg, SEXP nan_is_na_arg) {
104104
} else {
105105
double *xP = REAL(first), finalVal=NA_REAL;
106106
int k=0;
107-
for (int j=0; j<nval; ++j) {
108-
SEXP item = VECTOR_ELT(x, j+off);
109-
if (length(item)==1) {
110-
double tt = REAL(item)[0];
111-
if (nan_is_na ? ISNAN(tt) : ISNA(tt)) continue;
112-
finalVal = tt;
113-
break;
107+
if (nan_is_na) {
108+
for (int j=0; j<nval; ++j) {
109+
SEXP item = VECTOR_ELT(x, j+off);
110+
if (length(item)==1) {
111+
double tt = REAL(item)[0];
112+
if (ISNAN(tt)) continue;
113+
finalVal = tt;
114+
break;
115+
}
116+
valP[k++] = REAL_RO(item);
117+
}
118+
const bool final = !ISNAN(finalVal);
119+
#pragma omp parallel for num_threads(getDTthreads(nrow, true))
120+
for (int i=0; i<nrow; ++i) {
121+
double val=xP[i];
122+
if (!ISNAN(val)) continue;
123+
int j=0; while (ISNAN(val) && j<k) val=((double *)valP[j++])[i];
124+
if (!ISNAN(val)) xP[i]=val; else if (final) xP[i]=finalVal;
125+
}
126+
} else {
127+
for (int j=0; j<nval; ++j) {
128+
SEXP item = VECTOR_ELT(x, j+off);
129+
if (length(item)==1) {
130+
double tt = REAL(item)[0];
131+
if (ISNA(tt)) continue;
132+
finalVal = tt;
133+
break;
134+
}
135+
valP[k++] = REAL_RO(item);
136+
}
137+
const bool final = !ISNA(finalVal);
138+
#pragma omp parallel for num_threads(getDTthreads(nrow, true))
139+
for (int i=0; i<nrow; ++i) {
140+
double val=xP[i];
141+
if (!ISNA(val)) continue;
142+
int j=0; while (ISNA(val) && j<k) val=((double *)valP[j++])[i];
143+
if (!ISNA(val)) xP[i]=val; else if (final) xP[i]=finalVal;
114144
}
115-
valP[k++] = REAL_RO(item);
116-
}
117-
const bool final = !ISNAN(finalVal);
118-
#pragma omp parallel for num_threads(getDTthreads(nrow, true))
119-
for (int i=0; i<nrow; ++i) {
120-
double val=xP[i];
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;
124145
}
125146
}
126147
} break;

0 commit comments

Comments
 (0)