В R для вывода сообщения на экран есть две функции: print()
и cat()
. С print()
мы уже знакомы:
print(8)
## [1] 8
print("hello")
## [1] "hello"
Или так:
x <- 5
print(x)
## [1] 5
Как можно заметить, когда с помощью print()
на экран выводится текст, он печатается в кавычках. При желании это можно изменить, добавив аргумент quote=FALSE
:
print("hello", quote=FALSE)
## [1] hello
А что делает cat()
? Тоже выводит сообщение на экран, только сразу без кавычек:
cat("hello")
## hello
Видно, что cat()
при печати к тому же не выводит номер строки. Но это все мелочи. В чем состоит принципиальное отличие print()
от cat()
?
Во-первых, cat()
, в отличие от print()
, умеет «склеивать» то, что мы подаем ему на вход. Сравним:
print(1, 8) # выводится только первый элемент
## [1] 1
cat(1, 8) # выводятся все элементы
## 1 8
Во-вторых, cat()
умеет работать только с одномерными объектами (числа, строки, вектора), а print()
может вывести на экран что угодно. Рассмотрим пример с векторами, где обе функции сработают:
v <- c(3, 6, 9)
print(v) # ок
## [1] 3 6 9
cat(v) # oк
## 3 6 9
А теперь рассмотрим пример с матрицами, где print()
сработает, а cat()
выведет все элементы матрицы в одну строчку:
m <- matrix(3, nrow = 2, ncol = 3)
print(m) # сохранил матрицу
## [,1] [,2] [,3]
## [1,] 3 3 3
## [2,] 3 3 3
cat(m) # склеил все элементы в одну строку
## 3 3 3 3 3 3
И, наконец, пример со списками, когда print()
сработает, а cat()
— нет:
L <- list(c(1, 2, 3), c(0, 1))
print(L)
## [[1]]
## [1] 1 2 3
##
## [[2]]
## [1] 0 1
cat(L) # ошибка
В-третьих, cat()
просто выводит объект на экран, не сохраняя информацию о нем, а print()
сохраняет сам объект. Другими словами, функция cat()
просто выводит информацию на экран, ничего не возращая, то есть возвращая пустой объект типа NULL
, а функция print()
выводит объект на экран и возвращает сам объект:
a <- cat(9)
## 9
a
## NULL
class(a)
## [1] "NULL"
b <- print(9)
## [1] 9
b
## [1] 9
class(b)
## [1] "numeric"
В функции cat()
можно настраивать вид вывода, например, указывать разделитель между элементами в выдаче, выставив аргумент sep
:
cat("Hello", ",", "world", sep = "") # пустота
## Hello,world
cat(24, 1, 2020, sep = "-") # дефис
## 24-1-2020
Как быть, если мы хотим вывести некоторый текст и значение переменной? Для этого можем использовать cat()
, потому что он умеет «склеивать» записи:
name <- "Alla"
cat("Hello, ", name)
## Hello, Alla
А если мы хотим, чтобы переменная была где-то внутри текста? Для этого есть функция sprintf()
:
cat(sprintf("Hello, %s!", name)) # s - string
## Hello, Alla!
В то место, куда мы хотим добавить значение переменной, мы вписываем знак %
и сокращенное название типа это переменной: s
для строк (string), i
для целочисленных (integer), f
для чисел с плавающей точкой (float).
cat(sprintf("Age: %i", 25)) # i - integer
## Age: 25
cat(sprintf("Age: %f", 25.5)) # f - float
## Age: 25.500000
У чисел с плавающей точкой можно контролировать число знаков после запятой:
cat(sprintf("Age: %f", 25.5)) # по умолчанию 6 знаков
## Age: 25.500000
cat(sprintf("Age: %.3f", 25.5)) # 3 знака
## Age: 25.500
Как быть, если мы хотим запрашивать информацию у пользователя, а затем ее использовать? Для этого есть функция readline()
, аналог функции input()
в Python. Для примера попросим пользователя ввести свое имя:
name <- readline(prompt = "Enter your name: ")
И оформим приветствие:
cat("Hello, ", name, "!", sep = "")
## Hello, Alla!
Также как и в Python, тут важно учитывать, что функция readline()
всегда возвращает текст, то есть объект типа character
, даже если пользователь ввел число:
n <- readline(prompt = "Enter a number: ")
class(n)
## [1] "character"
Но исправлять такие вещи — конвертировать строки в числа — мы умеем.
n <- as.numeric(readline(prompt = "Enter your name: "))
## Enter your name:
class(n)
## [1] "numeric"
А что делать, если введено сразу несколько элементов, например несколько чисел через пробел?
inputs <- readline(prompt = "Enter something: ") # 2 3 4
Воспользуемся функцией strsplit()
и разобьем получившуюся строку по пробелу:
res <- strsplit(inputs, split = " ")
res
## [[1]]
## [1] "1" "2" "3"
Результат исполнения этой функции — это список (list). Про списки мы поговорим позже, пока к ним можно относиться как к вложенным спискам в Python. Для удобства работы превратим список в вектор:
res_v <- unlist(res) # раскрываем список и сохраняем в вектор
res_v
## [1] "1" "2" "3"
Сделаем все элементы вектора числами:
res_v <- as.numeric(res_v) # сделаем числовым
res_v
## [1] 1 2 3