--- title: "Основы программирования в R" subtitle: "Ввод и вывод в R" author: "Алла Тамбовцева, НИУ ВШЭ" output: pdf_document: latex_engine: xelatex toc: true mainfont: CMU Serif header-includes: - \usepackage[russian]{babel} - \usepackage{hyperref} - \hypersetup{colorlinks = true, urlcolor = blue, linkcolor=magenta} --- ## Вывод сообщения на экран В R для вывода сообщения на экран есть две функции: `print()` и `cat()`. С `print()` мы уже знакомы: ```{r} print(8) print("hello") ``` Или так: ```{r} x <- 5 print(x) ``` Как можно заметить, когда с помощью `print()` на экран выводится текст, он печатается в кавычках. При желании это можно изменить, добавив аргумент `quote=FALSE`: ```{r} print("hello", quote = FALSE) ``` А что делает `cat()`? Тоже выводит сообщение на экран, только сразу без кавычек: ```{r} cat("hello") ``` Видно, что `cat()` при печати к тому же не выводит номер строки. Но это всё мелочи. В чём состоит принципиальное отличие `print()` от `cat()`? Во-первых, `cat()`, в отличие от `print()`, умеет «склеивать» то, что мы подаём ему на вход. Сравним: ```{r} print(1, 8) # only 1st element ``` ```{r} cat(1, 8) # all elements ``` Во-вторых, `cat()` умеет работать только с одномерными объектами (числа, строки, вектора), а `print()` может вывести на экран что угодно. Рассмотрим пример с векторами, где обе функции сработают: ```{r} v <- c(3, 6, 9) print(v) # ok cat(v) # ok ``` А теперь рассмотрим пример с матрицами, где `print()` сработает, а `cat()` выведет все элементы матрицы в одну строчку: ```{r} m <- matrix(3, nrow = 2, ncol = 3) print(m) # matrix form ``` ```{r} cat(m) # all in one line ``` И, наконец, пример со списками, когда `print()` сработает, а `cat()` — нет: ```{r} L <- list(c(1, 2, 3), c(0, 1)) print(L) ``` ```{r, eval=FALSE} cat(L) # error ``` В-третьих, `cat()` просто выводит объект на экран, не сохраняя информацию о нем, а `print()` сохраняет сам объект. Другими словами, функция `cat()` просто выводит информацию на экран, ничего не возращая, то есть возвращая пустой объект типа `NULL`, а функция `print()` выводит объект на экран и возвращает сам объект: ```{r} a <- cat(9) a class(a) b <- print(9) b class(b) ``` В функции `cat()` можно настраивать вид вывода, например, указывать разделитель между элементами в выдаче, выставив аргумент `sep`: ```{r} cat("Hello", ",", "world", sep = "") cat(24, 1, 2020, sep = "-") ``` Как быть, если мы хотим вывести некоторый текст и значение переменной? Для этого можем использовать `cat()`, потому что он умеет «склеивать» записи: ```{r} name <- "Alla" cat("Hello, ", name) ``` А если мы хотим, чтобы переменная была где-то внутри текста? Для этого есть функция `sprintf()`: ```{r} cat(sprintf("Hello, %s!", name)) # s - string ``` В то место, куда мы хотим добавить значение переменной, мы вписываем знак `%` и сокращённое название типа это переменной: `s` для строк (*string*), `i` для целочисленных (*integer*), `f` для чисел с плавающей точкой (*float*). ```{r} cat(sprintf("Age: %i", 25)) # i - integer cat(sprintf("Age: %f", 25.5)) # f - float ``` У чисел с плавающей точкой можно контролировать число знаков после запятой: ```{r} cat(sprintf("Age: %f", 25.5)) # 6 digits ``` ```{r} cat(sprintf("Age: %.1f", 25.5)) # 1 digit ``` ## Ввод данных с клавиатуры Как быть, если мы хотим запрашивать информацию у пользователя, а затем её использовать? Для этого есть функция `readline()`, аналог функции `input()` в Python. Для примера попросим пользователя ввести свое имя: ```{r, eval = FALSE} name <- readline(prompt = "Enter your name: ") ``` И оформим приветствие: ```{r} cat("Hello, ", name, "!", sep = "") ``` Также как и в Python, тут важно учитывать, что функция `readline()` всегда возвращает текст, то есть объект типа `character`, даже если пользователь ввёл число: ```{r, include = FALSE} n <- "7" ``` ```{r, eval = FALSE} n <- readline(prompt = "Enter a number: ") ``` ```{r} class(n) ``` Но исправлять такие вещи — конвертировать строки в числа — мы умеем. ```{r} n <- as.numeric(readline(prompt = "Enter your name: ")) class(n) ```