Menu

Синтаксис R: основы за 5 минут

Ядро синтаксиса R: присваивание через <-, выражения и автопечать, вызовы функций с именованными аргументами и правило «всё есть вектор».

На этой странице есть исполняемые редакторы: меняйте, запускайте и сразу видите результат.

Выражения и автопечать

R — язык выражений: почти каждая написанная вами строка порождает значение. В консоли выражение, набранное само по себе, вычисляется, и его значение печатается автоматически — print() не нужен:

Каждый результат предваряется префиксом [1] — так R сообщает позицию первого показанного значения; первый намёк на то, что R мыслит векторами (об этом ниже). У автопечати есть особенность, о которой стоит знать с первого дня: она работает для голых выражений на верхнем уровне. То же самое выражение внутри тела функции или цикла for не напечатает ничего — поэтому в скриптах для вывода, который вы обязаны увидеть, используют явные cat() или print().

Присваивание: стрелка

Оператор присваивания в R — <-, стрелка, указывающая на имя, которое получает значение:

Читайте radius <- 5 как «radius получает 5». Да, = тоже работает для присваивания на верхнем уровне, и да, новички спрашивают, зачем набирать два символа вместо одного. Ответ — соглашение, у которого есть зубы: все серьёзные руководства по стилю, документация базового R и практически весь код на R, который вам когда-либо встретится, используют <- для присваивания, оставляя = для одной конкретной задачи — именования аргументов внутри вызовов функций (следующий раздел). Соблюдение этого соглашения делает две операции визуально различимыми. В RStudio Alt+- (Option+- на macOS) набирает стрелку за вас.

Обратите внимание: присваивание не печатается автоматически — area <- 78.5 сохраняет значение молча. Поэтому в сниппете выше и нужен print().

Чувствительность к регистру

R строго чувствителен к регистру — и в именах, которые создаёте вы, и в именах, которые даёт сам язык:

Это две разные переменные. Точно так же mean() — функция, а Mean() не существует. Когда R встречает вас сообщением object 'x' not found или could not find function, проверьте регистр раньше всего остального — это самая частая ошибка начинающих.

Вызовы функций и именованные аргументы

Функции вызываются со скобками, аргументы разделяются запятыми. Аргументы могут сопоставляться по позиции, по имени или смешанно:

Вызов seq() показывает синтаксис именованных аргументов R — и именно здесь = отрабатывает своё место: внутри вызова name = value помечает аргумент. Именованные аргументы избавляют от необходимости помнить порядок параметров и делают вызовы самодокументируемыми; seq(0, 100, 25) работает точно так же, но говорит читателю меньше. Рабочее соглашение: первый аргумент (обычно данные) передавайте по позиции, остальные именуйте.

Справка по любой функции — в одно нажатие: ?seq в консоли открывает её документацию.

Всё есть вектор

Идея, из-за которой R ощущается иначе, чем другие языки: голых одиночных чисел не бывает. Даже 5 — это вектор длины один, а операции применяются поэлементно к целым векторам:

Никакого цикла — а преобразован каждый элемент. В большинстве языков это три итерации цикла for; в R это арифметика. Это векторизация, и она определяет всё — операторы сравнения, строковые функции и математические функции работают так же. Именно поэтому в идиоматичном R гораздо меньше циклов, чем можно было бы ожидать; полная история — в статье про векторы.

Фигурные скобки и блоки

Многострочные тела — для if, циклов и функций — группируются фигурными скобками {}:

Обратите внимание на две вещи. Условие живёт в круглых скобках, и это просто if, а не if: или if ... then. И, в отличие от Python, отступы в R не несут смысла — блок задают скобки, а отступы нужны людям. Опускать скобки в однострочниках законно, но это классический источник ошибок при правках; просто всегда их ставьте.

Пробелы и точки с запятой

R игнорирует лишние пробелы, а перевод строки завершает инструкцию — точка с запятой не требуется:

Перенос на другую строку работает потому, что третья строка заканчивается на +, и R понимает, что выражение не завершено. Это единственное правило, которое нужно помнить при разбиении длинных строк: переносите после оператора или запятой, никогда перед ними, иначе R сочтёт первую строку законченной. Точки с запятой существуют лишь для того, чтобы впихнуть две инструкции в одну строку (a <- 1; b <- 2) — законно, не одобряется, легко избегается.

Стиль: как пишут код на R

Помимо грамматики, у R есть сильные соглашения сообщества (закреплённые в руководстве по стилю tidyverse, которому следует большая часть экосистемы):

  • <- для присваивания, = только для аргументов внутри вызовов.
  • Имена в snake_case: monthly_revenue, а не monthlyRevenue или monthly.revenue. Точки в именах R законны, но их лучше избегать — они пересекаются с шаблоном именования, который использует внутренняя кухня R.
  • Пробелы вокруг операторов (x <- a * 2, а не x<-a*2) и после запятых.
  • Отступ в четыре пробела внутри скобок (некоторые команды используют два; выберите одно и придерживайтесь).
  • Одна инструкция на строку.

Ничего из этого не требует интерпретатор. Всё это потребует любой, кто читает ваш код. Продолжение темы именования — в статье про переменные.

Что вы уносите с собой

  • R вычисляет выражения и автоматически печатает голые выражения в консоли — но не внутри функций или циклов.
  • Присваивайте через <- («получает»); = используйте только для именования аргументов в вызовах функций.
  • R полностью чувствителен к регистру — опечатки в регистре вызывают большинство ранних ошибок «not found».
  • Всё есть вектор, и операции применяются поэлементно: c(1, 2, 3) * 2 — это 2 4 6, без цикла.
  • Фигурные скобки задают блоки, переводы строк завершают инструкции, а snake_case и соглашения о пробелах делают ваш код похожим на код всех остальных.

Дальше: комментарии — как аннотировать код на R и что делать с отсутствующим в R синтаксисом блочных комментариев.

Часто задаваемые вопросы

Что означает <- в R?

<- — это оператор присваивания в R: x <- 5 сохраняет значение 5 под именем x. Читайте его как «получает». = тоже присваивает на верхнем уровне, но принятое в сообществе соглашение — его требует любое серьёзное руководство по стилю — это <- для присваивания и = только для именования аргументов внутри вызовов функций.

Чувствителен ли R к регистру?

Да, полностью. total, Total и TOTAL — три разных имени, а вызов Mean(x) вместо mean(x) — это ошибка, а не предупреждение. Сообщения «could not find function» или «object not found» очень часто оказываются просто опечаткой в регистре.

Нужны ли в R точки с запятой?

Нет. Инструкцию завершает перевод строки. Точка с запятой нужна только чтобы втиснуть две инструкции в одну строку (a <- 1; b <- 2), что руководства по стилю всё равно не одобряют. Пишите по одной инструкции на строку — и забудьте про точки с запятой.

Что значит, что R векторизован?

Базовые операции R работают сразу над целыми векторами. c(1, 2, 3) * 2 даёт 2 4 6 — умножение применяется к каждому элементу без всякого цикла. Большая часть кода, который в другом языке был бы циклом for, в R умещается в одно выражение.

Coddy programming languages illustration

Учитесь программировать с Coddy

НАЧАТЬ