What is the difference between cat and print?
Solution 1:
cat
is valid only for atomic types (logical, integer, real, complex, character) and names. It means you cannot call cat
on a non-empty list or any type of object. In practice it simply converts arguments to characters and concatenates so you can think of something like as.character() %>% paste()
.
print
is a generic function so you can define a specific implementation for a certain S3 class.
> foo <- "foo"
> print(foo)
[1] "foo"
> attributes(foo)$class <- "foo"
> print(foo)
[1] "foo"
attr(,"class")
[1] "foo"
> print.foo <- function(x) print("This is foo")
> print(foo)
[1] "This is foo"
Another difference between cat
and print is returned value. cat
invisibly returns NULL
while print
returns its argument. This property of print
makes it particularly useful when combined with pipes:
coefs <- lm(Sepal.Width ~ Petal.Length, iris) %>%
print() %>%
coefficients()
Most of the time what you want is print
. cat
can useful for things like writing a string to file:
sink("foobar.txt")
cat('"foo"\n')
cat('"bar"')
sink()
As pointed by baptiste you can use cat
to redirect output directly to file. So equivalent of the above would be something like this:
cat('"foo"', '"bar"', file="foobar.txt", sep="\n")
If you want to write lines incrementally you should use append
argument:
cat('"foo"', file="foobar.txt", append=TRUE)
cat('"bar"', file="foobar.txt", append=TRUE)
Compared to sink
approach it is far to verbose for my taste, but it is still an option.
Solution 2:
An essential difference between cat
and print
is the class of the object they return. This difference has practical consequences for what you can do with the returned object.
print
returns a character vector:
> print(paste("a", 100* 1:3))
[1] "a 100" "a 200" "a 300"
> class(print(paste("a", 100* 1:3)))
[1] "a 100" "a 200" "a 300"
[1] "character"
cat
returns an object of class NULL
.
> cat(paste("a", 100* 1:3))
a 100 a 200 a 300
> class(cat(paste("a", 100* 1:3)))
a 100 a 200 a 300[1] "NULL"
In some cases, it is important to return the output as is in your console, for example when you want to copy-paste the output. In those cases, you really don't want to return a character vector. I found it a useful strategy in those cases to combine print
and cat
: Use print
to create the object, use cat
to print it to your console.
> output <- print(paste("a", 100* 1:3)) # use print to create the object
> cat(output) # use cat to print it *as is* to your console
a 100 a 200 a 300
Using xtable
package for printing LaTeX tables in R:
> require(xtable)
> df <- data.frame(a = 1, č = 5) # dataframe with foreign characters
> output <- print(xtable(df), include.rownames = FALSE)
> output <- gsub("č", "c", output) # replace foreign characters before
> # copying to LaTeX
> cat(output)
\begin{table}[ht]
\centering
\begin{tabular}{rr}
\hline
a & c \\
\hline
1.00 & 5.00 \\
\hline
\end{tabular}\end{table}
> print(output)
[1] "\\begin{table}[ht]\n\\centering\n\\begin{tabular}{rr}\n
\hline\na & c \\\\ \n \\hline\n1.00 & 5.00 \\\\ \n
\\hline\n\\end{tabular}\n\\end{table}\n"