---
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)
```
