Neal Barsch
Neal Barsch

Reputation: 2940

R display in console two progress bars stacked (with code)

IS IT POSSIBLE TO DO THIS? I'd like to display two progress bars at the same time, vertically stacked, in R as a function runs within another larger function.

One would be for the overall process status of the larger of the function, the other for individual processes within the function (downloads etc.).

  1. I'd like to use the progress package's progress_bar's if possible (if not possible, base or whatever solution is cool! :) )

  2. I'd like to stay in the console and not plot a progress bar with tk or a solution like this(https://www.r-bloggers.com/multiple-progress-bars/)

Thanks in advance!

Examples below of imitated desired functions and outcomes in both progress(preferred) and Base R:

 ###Example in progress package(preferred)
library(progress)

###Create the progress bars
overallbar <- progress_bar$new(
  format = " downloading :what [:bar] :percent Guestimated Remaining OVERALL: :eta",
  clear = FALSE, total = 1000, width = 60)
statusbar <- progress_bar$new(
  format = " [:bar] :percent Guestimated Remaining CURRENT FILE: :eta",
  clear = FALSE, total = 100, width = 60)

###Only displays the statusbar when I'd like to display both

for (i in 1:1000) {
  overallbar$tick()
  statusbar$tick()
  Sys.sleep(1 / 1000)
}

###Desired outcome (imitation only)
downloading THIS FILE NOW [] 100% Guestimated remaining OVERALL:  0s
[============] 100% Guestimated remaining CURRENT FILE:  0s

AN EXAMPLE USING BASE R INSTEAD (less desired than progress package style):

###Base R
pb1   <- txtProgressBar(1, 1000, style=3)
pb2   <- txtProgressBar(title="File Progress",1, 100, style=3)


###Like progress, base also only displays the second progress bar 

cat("OVERALL PROGRESS:")
for (i in 1:1000) {
  setTxtProgressBar(pb1, i)
  ###something is funky with the title option, not working
  ###I usually use progress package, you get the idea, I'd like a title
  setTxtProgressBar(title="File Progress:", pb2, i)
  Sys.sleep(1 / 1000)
}

###Desired outcome (imitation only)

OVERALL PROGRESS:
|========================================================================================| 100%
File Progress:
|========================================================================================| 100%

Upvotes: 4

Views: 1495

Answers (1)

jamieguinan
jamieguinan

Reputation: 1680

At least in the Base R case, progress bars work by simply re-drawing the same line. You can use ANSI escape sequences to jump between lines. Modifying your Base R example,

cat("OVERALL PROGRESS:\n\n") # 2 newlines leaving a blank between headers
cat("File Progress:\n") # 1 newline leaves in position for pb2
for (i in 1:1000) {
  cat("\033[2A")   # up 2 lines for pb1
  setTxtProgressBar(pb1, i)
  cat("\033[2B")   # down 2 lines for pb2
  setTxtProgressBar(title="File Progress:", pb2, i)
  Sys.sleep(1 / 1000)
}
cat("\033[2B\n") # for good measure

This works in Linux, probably also MacOS Terminal, and maybe even Windows although I did not test there.

Upvotes: 2

Related Questions