Skip to content

Commit 7d6715a

Browse files
ben-schwenMichaelChirico
authored andcommitted
allow showProgress=INTEGER to set progress bar update time (Rdatatable#7259)
* allow showProgress=INTEGER to set progress bar update time * add NEWS * cleanup merge * refine NEWS * make check more explicit * adjust docs * adjust nocov to what they really should cover * phrasing comment Co-authored-by: Michael Chirico <michaelchirico4@gmail.com> * Update NEWS.md Co-authored-by: Michael Chirico <michaelchirico4@gmail.com> * refine NEWS * update man * remove as.integer from signature * remove unnecessary brackets --------- Co-authored-by: Michael Chirico <michaelchirico4@gmail.com>
1 parent b4ca39e commit 7d6715a

4 files changed

Lines changed: 11 additions & 8 deletions

File tree

NEWS.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616

1717
1. `nafill()`, `setnafill()` extended to work on logical vectors (part of [#3992](https://github.com/Rdatatable/data.table/issues/3992)). Thanks @jangorecki for the request and @MichaelChirico for the PR.
1818

19+
2. `[,showProgress=]` and `options(datatable.showProgress)` now accept an integer to control the progress bar update interval in seconds, allowing finer control over progress reporting frequency; `TRUE` uses the default 3-second interval, [#6514](https://github.com/Rdatatable/data.table/issues/6514). Thanks @ethanbsmith for the report and @ben-schwen for the PR.
20+
1921
2. `tables()` can now optionally report `data.table` objects stored one level deep inside list objects when `list_search=TRUE`, with `list_len_threshold` to avoid scanning extremely long lists, [#2606](https://github.com/Rdatatable/data.table/issues/2606).
2022

2123
### Notes

R/data.table.R

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,7 @@ replace_dot_alias = function(e) {
244244
if ((isTRUE(which)||is.na(which)) && !missing(j)) stopf("which==%s (meaning return row numbers) but j is also supplied. Either you need row numbers or the result of j, but only one type of result can be returned.", which)
245245
if (is.null(nomatch) && is.na(which)) stopf("which=NA with nomatch=0|NULL would always return an empty vector. Please change or remove either which or nomatch.")
246246
if (!with && missing(j)) stopf("j must be provided when with=FALSE")
247-
if (!missing(by) && !isTRUEorFALSE(showProgress)) stopf("%s must be TRUE or FALSE", "showProgress")
247+
if (!missing(by) && !(isTRUEorFALSE(showProgress) || (is.numeric(showProgress) && length(showProgress)==1L && showProgress >= 0))) stopf("showProgress must be TRUE, FALSE, or a single non-negative number") # nocov
248248
irows = NULL # Meaning all rows. We avoid creating 1:nrow(x) for efficiency.
249249
notjoin = FALSE
250250
rightcols = leftcols = integer()
@@ -1972,7 +1972,7 @@ replace_dot_alias = function(e) {
19721972
}
19731973
ans = c(g, ans)
19741974
} else {
1975-
ans = .Call(Cdogroups, x, xcols, groups, grpcols, jiscols, xjiscols, grporder, o__, f__, len__, jsub, SDenv, cols, newnames, !missing(on), verbose, showProgress)
1975+
ans = .Call(Cdogroups, x, xcols, groups, grpcols, jiscols, xjiscols, grporder, o__, f__, len__, jsub, SDenv, cols, newnames, !missing(on), verbose, as.integer(showProgress))
19761976
}
19771977
# unlock any locked data.table components of the answer, #4159
19781978
# MAX_DEPTH prevents possible infinite recursion from truly recursive object, #4173

man/data.table.Rd

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ data.table(\dots, keep.rownames=FALSE, check.names=FALSE, key=NULL, stringsAsFac
181181
182182
\item{env}{ List or an environment, passed to \code{\link{substitute2}} for substitution of parameters in \code{i}, \code{j} and \code{by} (or \code{keyby}). Use \code{verbose} to preview constructed expressions. For more details see \href{../doc/datatable-programming.html}{\code{vignette("datatable-programming")}}. }
183183
184-
\item{showProgress}{ \code{TRUE} shows progress indicator with estimated time to completion for lengthy "by" operations. }
184+
\item{showProgress}{ \code{TRUE} (default when \code{interactive()}) shows a progress indicator with estimated time to completion for lengthy "by" operations, updating every 3 seconds. An integer value controls the update interval in seconds (minimum 3). \code{FALSE} disables the progress indicator. }
185185
}
186186
\details{
187187
\code{data.table} builds on base \R functionality to reduce 2 types of time:\cr

src/dogroups.c

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -86,9 +86,10 @@ SEXP dogroups(SEXP dt, SEXP dtcols, SEXP groups, SEXP grpcols, SEXP jiscols, SEX
8686
SEXP SDall = PROTECT(findVar(install(".SDall"), env)); nprotect++; // PROTECT for rchk
8787
SEXP SD = PROTECT(findVar(install(".SD"), env)); nprotect++;
8888

89-
const bool showProgress = LOGICAL(showProgressArg)[0]==1 && ngrp > 1; // showProgress only if more than 1 group
89+
int updateTime = INTEGER(showProgressArg)[0];
90+
const bool showProgress = updateTime > 0 && ngrp > 1; // showProgress only if more than 1 group
9091
double startTime = (showProgress) ? wallclock() : 0; // For progress printing, startTime is set at the beginning
91-
double nextTime = (showProgress) ? startTime+3 : 0; // wait 3 seconds before printing progress
92+
double nextTime = (showProgress) ? startTime + MAX(updateTime, 3) : 0; // wait at least 3 seconds before starting to print progress
9293

9394
hashtab * specials = hash_create(3 + ngrpcols + xlength(SDall)); // .I, .N, .GRP plus columns of .BY plus SDall
9495
PROTECT(specials->prot); nprotect++;
@@ -451,17 +452,17 @@ SEXP dogroups(SEXP dt, SEXP dtcols, SEXP groups, SEXP grpcols, SEXP jiscols, SEX
451452
// could potentially refactor to use fread's progress() function, however we would lose some information in favor of simplicity.
452453
double now;
453454
if (showProgress && (now=wallclock())>=nextTime) {
455+
// # nocov start. Requires long-running test case
454456
double avgTimePerGroup = (now-startTime)/(i+1);
455457
int ETA = (int)(avgTimePerGroup*(ngrp-i-1));
456458
if (hasPrinted || ETA >= 0) {
457-
// # nocov start. Requires long-running test case
458459
if (verbose && !hasPrinted) Rprintf(_("\n"));
459460
Rprintf("\r"); // # notranslate. \r is not internationalizable
460461
Rprintf(_("Processed %d groups out of %d. %.0f%% done. Time elapsed: %ds. ETA: %ds."), i+1, ngrp, 100.0*(i+1)/ngrp, (int)(now-startTime), ETA);
461-
// # nocov end
462462
}
463-
nextTime = now+1;
463+
nextTime = now+updateTime;
464464
hasPrinted = true;
465+
// # nocov end
465466
}
466467
ansloc += maxn;
467468
if (firstalloc) {

0 commit comments

Comments
 (0)