В чем разница между кошкой и печатью?
cat
и print
оба, кажется, предлагают функциональность "print" в R.
x <- 'Hello world!\n'
cat(x)
# Hello world!
print(x)
# [1] "Hello world!\n"
Мое впечатление, что cat
больше всего напоминает типичную функцию "печать". Когда я использую cat
, и когда я использую print
?
Ответы
Ответ 1
cat
действителен только для атомных типов (логического, целочисленного, реального, сложного, символьного) и имен. Это означает, что вы не можете вызвать cat
в непустом списке или любом типе объекта. На практике он просто преобразует аргументы в символы и конкатенации, поэтому вы можете думать о чем-то вроде as.character() %>% paste()
.
print
- это общая функция, поэтому вы можете определить конкретную реализацию для определенного класса S3.
> 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"
Другим отличием между cat
и печатью является возвращаемое значение. cat
invisibly возвращает NULL
, а print
возвращает свой аргумент. Это свойство print
делает его особенно полезным в сочетании с трубами:
coefs <- lm(Sepal.Width ~ Petal.Length, iris) %>%
print() %>%
coefficients()
В большинстве случаев вы хотите print
. cat
может быть полезен для таких вещей, как запись строки в файл:
sink("foobar.txt")
cat('"foo"\n')
cat('"bar"')
sink()
Как указал baptiste, вы можете использовать cat
для перенаправления вывода непосредственно в файл. Таким образом, эквивалент вышеупомянутого будет примерно таким:
cat('"foo"', '"bar"', file="foobar.txt", sep="\n")
Если вы хотите последовательно писать строки, вы должны использовать аргумент append
:
cat('"foo"', file="foobar.txt", append=TRUE)
cat('"bar"', file="foobar.txt", append=TRUE)
По сравнению с подходом sink
это далеко не много для моего вкуса, но это все еще вариант.
Ответ 2
Существенное различие между cat
и print
- это класс возвращаемого объекта. Это различие имеет практические последствия для того, что вы можете сделать с возвращенным объектом.
print
возвращает вектор символов:
> 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
возвращает объект класса 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"
В некоторых случаях важно вернуть результат как есть в вашей консоли, например, если вы хотите скопировать-вставить вывод. В таких случаях вы действительно не хотите возвращать вектор символов. В этих случаях я нашел полезной стратегией объединения print
и cat
: используйте print
для создания объекта, используйте cat
для печати на консоли.
> 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
Использование пакета xtable
для печати таблиц LaTeX в 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"