snowfire257
snowfire257

Reputation: 55

Using cat for a progress bar

I'm trying to make a simple in-console progress bar so that I can see how far along my code is. I know there exist built-in options like txtProgressBar and winProgressBar but I was hoping to be able to format one myself. I'd like it to update in the same line rather than outputting a series of lines.

I currently have something that I feel should work - and sometimes does work fine - but also sometimes glitches out in ways I don't understand. This is my code:

for(i in 1:10000){
  #Rest of my code
  cat('\r',paste("Working  [",strrep("#",i/n*50),strrep(" ",50-i/n*50),"]   ",ceiling(i/n*100),"%",sep=""))
}

As far as I can tell this should format correctly every time. However by the time the program finishes the output usually looks something like this:

Working  [##################################################]   100%rking  [                                                 ]   5%

I can't figure out what goes wrong. Neither flush.console() nor Sys.sleep seems to help. Any advice or ideas would be appreciated. In case it matters, I'm using RStudio.

Upvotes: 3

Views: 2958

Answers (2)

hrbrmstr
hrbrmstr

Reputation: 78832

There is already a wheel. No need to re-invent:

library(dplyr)

n <- 10000
pb <- progress_estimated(n)
for(i in 1:n){
  pb$tick()$print()
  # your code goes here
}

Upvotes: 2

G5W
G5W

Reputation: 37661

The following worked for me both in the R console and in RStudio under Windows

n = 1000
cat("Working: ")
for(i in 1:n) {
    signal = floor(n/200)
    if(!(i %% signal)) { 
        prog = floor(i/n*50)
        cat('\r', "Working  [", strrep("#",prog), 
            strrep(" ", 50-prog), "] ", 2*prog, "%", sep="")
        flush.console() 
      }
    ## Pretend that some work is being done. 
    Sys.sleep(0.001)
    if(i == n) { cat(" \n\r") }
}

Upvotes: 2

Related Questions