Menu

Строки в R: paste, sprintf, gsub, substr и другие

Всё необходимое для работы с текстом в R: создание строк, склейка через paste и paste0, форматирование через sprintf и поиск через gsub, grepl и strsplit.

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

Создание строк в R

Строка в R — это текст между кавычками. Двойные и одинарные кавычки работают одинаково и означают ровно одно и то же; соглашение — двойные, с переходом на одинарные, когда сам текст содержит двойную кавычку:

Экранирование обратным слешем работает как в большинстве языков: \" — буквальная кавычка, \n — перевод строки, \t — табуляция, \\ — сам обратный слеш.

А теперь ошибка, которую каждый новичок в R делает ровно один раз: спросить у строки её длину через length().

nchar() считает символы — 5. length() считает элементы вектора, а одиночная строка — это вектор из одного элемента, поэтому получается 1. В R всё есть вектор, включая текст, и все функции на этой странице тихо работают поэлементно по целым символьным векторам. Это преимущество — как только вы перестанете этому удивляться.

Склейка строк: paste() и paste0()

В R нет + для строк. Конкатенация — это paste(), которая соединяет свои аргументы пробелом по умолчанию, и paste0(), которая соединяет без разделителя:

Поскольку paste векторизована, передача ей вектора строит сразу много строк — так в одну строку кода генерируют имена файлов, подписи и идентификаторы:

А аргумент collapse делает обратное: он сливает целый вектор в одну строку с выбранным разделителем:

Запомните разделение: sep задаёт склейку между аргументами, collapse — склейку между элементами одного вектора. Можно использовать оба в одном вызове.

Форматирование через sprintf()

Когда нужны числа, отформатированные внутри текста, — фиксированное число знаков после запятой, заданная ширина, — paste() выдыхается, и в дело вступает sprintf(). Она использует форматные коды в стиле C: %s для строк, %d для целых чисел, %f для дробных:

%.1f означает «один знак после запятой», %.3f — три, а %05d дополняет до пяти цифр нулями. Удвоенный %% даёт буквальный знак процента. sprintf() тоже векторизована, поэтому может отформатировать целый столбец значений одним вызовом — см. паттерн sprintf() + cat() для отчётов в статье про ввод и вывод.

Смена регистра и срезы: toupper(), tolower(), substr()

Преобразование регистра — ровно то, чем кажется:

tolower() окупается при нормализации грязных данных перед сравнением: "Yes", "YES" и "yes" становятся одним значением.

substr(x, start, stop) извлекает срез по позициям символов, считая с 1 (в R везде индексация с единицы):

Обе границы включаются: позиции с 1 по 11 дают "Programming".

Поиск и замена: sub(), gsub() и grepl()

sub() заменяет первое вхождение шаблона; gsub() («global substitute») заменяет все:

Одна критичная деталь: шаблон по умолчанию — регулярное выражение, а не буквальный текст. Символы регулярных выражений вроде ., *, ( и ? имеют особый смысл — голая . совпадает с любым символом. Когда вы имеете в виду буквальный текст, передавайте fixed = TRUE:

Первая строка даёт a-b-c; вторая даёт -----, потому что как регулярное выражение . совпала с каждым символом. Пока вы не освоили регулярные выражения, сделайте fixed = TRUE вариантом по умолчанию — и никогда не обожжётесь.

grepl() ничего не заменяет — она проверяет, совпадает ли каждый элемент, и возвращает логический вектор. Это делает её стандартным инструментом фильтрации текста:

Первый результат помечает, какие имена файлов содержат .csv; второй использует этот логический вектор, чтобы оставить только совпадения.

Разделение и обрезка: strsplit() и trimws()

strsplit() разрезает строку по разделителю. Её единственная особенность: она возвращает список, потому что может разделить сразу много строк. Для одной строки берите первый элемент через [[1]]:

А trimws() срезает пробелы, в которые всегда завёрнуты данные из реального мира:

По умолчанию она обрезает с обеих сторон; which = "left" или "right" обрезает только одну (названия относятся к началу и концу строки).

Альтернатива stringr

Всё вышеописанное — базовый R: всегда доступен, ничего устанавливать не нужно. Пакет stringr из tidyverse оборачивает те же операции в согласованную схему имён str_*, где строка всегда идёт первым аргументом, — многим так проще запоминать (об установке см. статью про пакеты):

library(stringr)

str_detect(files, "csv")            # like grepl(), data first
str_replace_all(s, "good", "great") # like gsub(), arguments reordered
str_length("hello")                 # like nchar()

Строковые функции базового R стоит знать в любом случае — вы встретите их в каждом скрипте, каждом ответе на Stack Overflow и каждом сообщении об ошибке. Сначала выучите базовые имена; переходите на stringr, когда непоследовательные порядки аргументов начнут раздражать.

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

  • По соглашению строки пишут в двойных кавычках; nchar() считает символы, length() — элементы вектора.
  • Склеивайте через paste() / paste0(); sep соединяет аргументы, collapse соединяет вектор в одну строку.
  • sprintf() отвечает за форматированный вывод: %s, %d, %.2f.
  • sub() заменяет первое совпадение, gsub() — все, grepl() проверяет наличие совпадения — и всё это по умолчанию с регулярными выражениями, так что для буквального текста передавайте fixed = TRUE.
  • strsplit() возвращает список (берите [[1]]); trimws() чистит вход с лишними пробелами.

Дальше: как загонять текст в программу и выводить его наружу — печать через print() и cat() и чтение пользовательского ввода.

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

Как склеить строки в R?

С помощью paste() или paste0() — в R нет + для строк. paste("data", "science") даёт "data science" (по умолчанию через пробел); paste0("data", "science") склеивает без разделителя. Используйте sep =, чтобы сменить разделитель, и collapse =, чтобы слить весь вектор в одну строку.

Как узнать длину строки в R?

nchar("hello") возвращает 5 — число символов. length("hello") возвращает 1: в R length() считает элементы вектора, а одиночная строка — это вектор из одного элемента. Путаница между length() и nchar() — классическая ошибка новичка.

В чём разница между sub() и gsub() в R?

Обе ищут и заменяют, но sub() заменяет только первое совпадение, а gsub() («global sub») заменяет все. Обе по умолчанию трактуют шаблон как регулярное выражение — передайте fixed = TRUE, чтобы искать буквальный текст.

Как разделить строку в R?

strsplit(x, split) разделяет по шаблону, но возвращает список (потому что может разделить сразу много строк). Для одной строки берите первый элемент: strsplit("a,b,c", ",")[[1]] даёт символьный вектор "a" "b" "c".

Coddy programming languages illustration

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

НАЧАТЬ