nachocab
nachocab

Reputation: 14374

Is there a simpler way to erase the end of the line using cat in R?

I like to do use this in my scripts:

cat("Saving...")
do_something_slow()
cat("\rSaved\n")

The problem is that the carriage return is applied without erasing the rest of the line, so I get this:

Savedg...

To fix it I can do:

cat("\rSaved\033[K\n")

but it's kind of ugly. Is there a simpler way?

Upvotes: 2

Views: 791

Answers (2)

jthetzel
jthetzel

Reputation: 3623

I like to use message() instead of cat() for generating messages. For example:

cat("Saving..."); cat("\rSaved\n")

returns:

Savdg...

While:

message("Saving..."); message("\rSaved\n")

returns:

Saving...
Saved

Edit:

Inspired by @gauden answer, another function could be:

replaceMessage <- function(x, width = 80)
{
    message("\r", rep(" ", times = width - length(x)), "\r", appendLF = F)
    message(x, appendLF = F)
}

And then:

replaceMessage("Saving..."); Sys.sleep(1); replaceMessage("Saved\n")

Note:

While replaceMessage() behaves as expected in Linux and Rterm on Windows, it behaves strangely in my Rgui (2.15.0, Windows x64). Specifically, Saving... is never displayed, and after Saved is displayed, the cursor is moved width spaces (in the example, 80 spaces) to the right. I am not sure why.

Upvotes: 5

daedalus
daedalus

Reputation: 10923

Assuming you want the messages to all appear serially on one line, how about something whimsical?

cleancat <- function(astring, width=80) {
    # Reserves a line of 80 (default) characters
    # and uses it for serial updates
    require("stringr")
    astring <- paste("\r", astring, sep="")
    cat(str_pad(astring, 80, "right"))
    # pretend to do something slow
    # delete this line if cleancat is used in production
    Sys.sleep(0.5) 
}

# imitate printing a series of updates
test <- lapply(c("Saving -", 
                 "Saving \\", 
                 "Saving |", 
                 "Saving /", 
                 "Saving -", 
                 "Saving \\", 
                 "Saving |", 
                 "Saving /", 
                 "Saved"), cleancat)

Of course, you would need to load the stringr package and set up the cleancat function in your environment which you might think is even uglier...

Upvotes: 6

Related Questions