cat()
cat(... , file = "", sep = " ", fill = FALSE, labels = NULL, append = FALSE) cat() is a base R function that outputs objects to the console or a file. Unlike print(), it does not add quotation marks around strings and offers fine-grained control over separators and output destinations.
Syntax
cat(... , file = "", sep = " ", fill = FALSE, labels = NULL, append = FALSE)
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
... | objects | , | Objects to be concatenated and printed |
file | character | "" | Filename or connection to write to; "" outputs to console |
sep | character | " " | String inserted between objects |
fill | logical | FALSE | If TRUE, wrap lines after fill characters |
labels | character | NULL | Character vector of line labels (when fill=TRUE) |
append | logical | FALSE | If TRUE, append to file instead of overwriting |
Examples
Basic console output
cat("Hello", "world", "!")
# Hello world !
Custom separator
Changing the sep argument controls what gets inserted between each argument in the output. Setting sep = "-" creates hyphen-delimited output, useful for generating slugs or compact identifiers. Setting sep = "\n" places each argument on its own line, which is handy for printing vectors or lists vertically in the console. Unlike paste(), where sep defaults to a space, cat() also defaults to a single space between arguments.
cat("a", "b", "c", sep = "-")
# a-b-c
cat("x", "y", "z", sep = "\n")
# x
# y
# z
Writing to a file
Redirecting cat() output to a file uses the file argument. Pass a filename as a character string, and cat() opens the file, writes the concatenated text, and closes it — all in one call. To add content without erasing what is already there, set append = TRUE. The function creates the file if it does not exist, so no separate file.create() step is needed before writing.
# Write to a file (overwrites by default)
cat("Hello, file!", file = "greeting.txt")
# Append to existing file
cat("\nGoodbye!", file = "greeting.txt", append = TRUE)
# Read back the content
readLines("greeting.txt")
# [1] "Hello, file!" "Goodbye!"
Building strings for processing
cat() is often used in scripts to assemble status messages from multiple components. By setting sep = "", you can concatenate strings, numbers, and symbols without any automatic spacing, giving you pixel-perfect control over the output format. The trailing \n is necessary because cat() does not add a newline on its own — omitting it means the next cat() call will continue on the same line, which is sometimes the desired effect for progress bars.
# Useful in scripts to build status messages
status <- "processing"
percent <- 75
cat("Status:", status, "(", percent, "% complete)\n", sep = "")
# Status: processing (75% complete)
Common patterns
Progress indicators in loops: When processing many items sequentially, printing a running counter with cat() and a carriage return (\r) gives you an in-place progress display that updates on a single terminal line. The \r moves the cursor back to the start before each write, so each iteration’s output overwrites the previous one. After the loop finishes, call cat("Done!\n") to advance to a new line and confirm completion.
for (i in 1:5) {
cat("Processing item", i, "\r")
Sys.sleep(0.5)
}
cat("Done!\n")
# Processing item 5
# Done!
Logging to file with timestamps: Wrapping cat() in a helper function that prepends a timestamp gives you a reusable logging mechanism. Using format(Sys.time(), "%Y-%m-%d %H:%M:%S") produces an ISO-style timestamp that sorts correctly when you review the log later. Each call appends a new line to the log file, so the log grows incrementally as the script runs, and you can inspect it mid-execution with tail -f app.log from another terminal.
log_msg <- function(msg) {
timestamp <- format(Sys.time(), "%Y-%m-%d %H:%M:%S")
cat(timestamp, " -", msg, "\n", file = "app.log", append = TRUE)
}
log_msg("Application started")
log_msg("Data loaded successfully")
cat() vs print() vs message()
cat() writes character representations directly to stdout (or a connection), with no quotation marks, no [1] prefix, and no trailing newline by default. It is designed for generating output that will be read by humans or piped to another process, not for R object inspection.
print() formats R objects for display, it adds quotation marks around strings, index prefixes like [1], and type information. Use print() for debugging and interactive inspection. Use cat() when you need clean output without R-specific formatting.
message() sends output to stderr and is the right choice for progress updates, warnings, and informational messages in scripts and packages. Unlike cat(), message() output appears even when stdout is redirected to a file, and it can be suppressed with suppressMessages().
For writing multiple lines to a file, writeLines() is preferable to cat(), it adds newlines automatically and handles the output connection cleanly.
cat() output routing
cat() writes directly to the output connection without going through R’s printing infrastructure. By default, that connection is stdout(), but you can redirect with file: cat("log entry ", file = stderr()) writes to standard error, and cat(output, file = "results.txt", append = TRUE) appends to a file without overwriting.
Unlike print(), cat() does not add a trailing newline automatically, you must include explicitly. This is intentional: it lets you build a line incrementally across multiple cat() calls before terminating it.
For diagnostic messages that should be suppressible, prefer message() over cat(). message() writes to stderr() and can be suppressed with suppressMessages() or captured with tryCatch(). Warnings from cat() are not suppressible via the standard messaging interface. In functions and packages, message() is the recommended choice for informational output; cat() is best reserved for cases where you need exact control over the output format, such as generating text files or formatted reports.
When cat() is called with sep = "", it concatenates all arguments without any separator. When sep = " ", it places each argument on its own line. The fill argument wraps output at a given line width (in characters), inserting newlines at word boundaries — useful for formatting long prose output to a fixed-width terminal.