You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
# for dogroups.c to know that shorter results (including when na.rm results in a length-1) should be padded with NA to match the length of longer items
73
+
# head and tail with na.rm=TRUE are by their nature returning a vector and therefore shouldn't be recycled when length-1; test 2240.81
74
+
# TODO: new function pad() could be provided so user can do things like DT[, .(pad(na.omit(B)), pad(na.omit(C))), by=grp]
75
+
# to avoid the error 'Supplied 2 items for column 1 of group 1 which has 3 rows ...'
76
+
# and/or pad= could be added to [.data.table to allow padding all results
77
+
# Since gforce_dynamic optimizes head/tail it knows to pad and that's optimized. However, default last(x) and first(x) (i.e. n=1 na.rm=FALSE) are
78
+
# single-valued like mean,median etc and are recycled in the same way. This is consistent with n=1 na.rm=FALSE already not being treated as
79
+
# gforce_dynamic in gsumm.c either.
80
+
# ***** TODO *****: n=1 na.rm=TRUE is not vector result and should be recycled to be consistent with n=1 na.rm=FALSE. It's just n>1 that is true vector then.
# aligning two gforce dynamic columns the same between optimized and unoptimized
18916
-
# needs to be top aligned otherwise dogroups.c would need knowledge of R first/last (last was aligned at the bottom in the PR before this test added)
18917
-
# but outstanding is that dogroups.c recycles length-1 whereas gforce_dynamic currently NA fills with vector output from
18918
-
# first/last n>1 na.rm=TRUE in mind. So this test fails when not optimized (2240.81) currently.
18916
+
# needs to be top aligned otherwise dogroups.c would need knowledge of whether first or last was called (last was aligned at the bottom in the PR before
18917
+
# this test added). dogroups.c now just needs to know whether the vector is a true vector to know not to recycle length-1 and to pad with NA
error(_("Column %d of result for group %d is type '%s' but expecting type '%s'. Column types must be consistent for each group."), j+1, i+1, type2char(TYPEOF(source)), type2char(TYPEOF(target)));
417
-
if (thislen>1&&thislen!=maxn&&grpn>0) { // grpn>0 for grouping empty tables; test 1986
418
-
error(_("Supplied %d items for column %d of group %d which has %d rows. The RHS length must either be 1 (single values are ok) or match the LHS length exactly. If you wish to 'recycle' the RHS please use rep() explicitly to make this intent clear to readers of your code."), thislen, j+1, i+1, maxn);
419
-
}
420
417
boolcopied= false;
421
418
if (isNewList(target) &&anySpecialStatic(source)) { // see comments in anySpecialStatic()
// first() and last() set truelength to mark that it is a true vector; see comments at the end of last.R and test 2240.81
424
+
// a true vector is not recycled when length-1 and is padded with NA to match the length of the longest result
425
+
memrecycle(target, R_NilValue, thisansloc, thislen, source, 0, -1, 0, ""); // just using memrecycle to copy contents
426
+
writeNA(target, thisansloc+thislen, maxn-thislen, true); // pad with NA
427
+
} else {
428
+
if (thislen>1&&thislen!=maxn&&grpn>0) // grpn>0 for grouping empty tables; test 1986
429
+
error(_("Supplied %d items for column %d of group %d which has %d rows. The RHS length must either be 1 (single values are ok) or match the LHS length exactly. If you wish to 'recycle' the RHS please use rep() explicitly to make this intent clear to readers of your code."), thislen, j+1, i+1, maxn);
0 commit comments