Работа со строками
Базовые операции
Задание 1
Переведите в нижний регистр все названия месяцев из вектора month.name
.
tolower(month.name)
## [1] "january" "february" "march" "april" "may" "june"
## [7] "july" "august" "september" "october" "november" "december"
Задание 2
Переведите в верхний регистр все названия месяцев из вектора month.name
.
toupper(month.name)
## [1] "JANUARY" "FEBRUARY" "MARCH" "APRIL" "MAY" "JUNE"
## [7] "JULY" "AUGUST" "SEPTEMBER" "OCTOBER" "NOVEMBER" "DECEMBER"
Задание 3
Напишите выражение, которое будет возвращать строку "Текущие дата и время: x", где на месте x
будет подставляться, собственно, текущие дата и время.
Задание 4
В векторе month.name
, добавьте через _
каждому месяцу его номер, например, January_1
.
paste(month.name, 1:12, sep = '_')
## [1] "January_1" "February_2" "March_3" "April_4" "May_5"
## [6] "June_6" "July_7" "August_8" "September_9" "October_10"
## [11] "November_11" "December_12"
Задание 5
В векторе month.name
, добавьте через _
каждому месяцу его номер и квартал, например, January_1_Q1
.
Можно воспользоваться логикой повтора вектора до достижения длины максимально длинного вектора среди всех конкатенируемых. Так, векторы month.name
и 1:12
имеют длину 12, соответственно, все остальные векторы в выражении должны быть такой же длины. С элементами _
и _Q
нет проблем, они просто будут повторены 12 раз. Сложность может возникнуть с идентификатором квартала - всего кварталов 4, то есть, надо прямо указать, что каждый идентификатор должен быть повторен три раза, чтобы в результате получился вектор длиной в 12 элементов.
Задание 6
Напишите выражение, которое будет возвращать строку "Доля респондентов с высшим образованием в волне x: y%", где x - любое натуральное число, а у - доля, записанная в виде процентов, округленная до первого знака после запятой. X и Y могут задаваться в отдельных переменных.
Можно воспользоваться paste()
и собирать строку из параметров, в том числе с использованием функции округления. Несколько быстрее и проще будет воспользоваться функцией sprintf()
:
# решение через paste()
paste('Доля респондентов с высшим образованием в волне ', 5, ': ', round(0.333 * 100, 2), '%', sep = '')
## [1] "Доля респондентов с высшим образованием в волне 5: 33.3%"
# более простое решение через sprintf()
sprintf('Доля респондентов с высшим образованием в волне %d: %.2f%%', 5, 0.333 * 100)
## [1] "Доля респондентов с высшим образованием в волне 5: 33.30%"
Задание 7
Объедините первые пять элементов вектора letters
в один, с разделителем в виде -
.
paste(letters[1:5], collapse = '-')
## [1] "a-b-c-d-e"
Задание 8
Подсчитайте количество символов в каждом названии месяца из вектора month.name
.
nchar(month.name)
## [1] 7 8 5 5 3 4 4 6 9 7 8 8
Задание 9
Обрежьте каждое название месяца из вектора month.name
до трех букв.
strtrim(month.name, 3)
## [1] "Jan" "Feb" "Mar" "Apr" "May" "Jun" "Jul" "Aug" "Sep" "Oct" "Nov" "Dec"
Задание 10
Из строки На деревню дедушке, Константину Макаровичу
извлеките адрес.
adr <- 'На деревню дедушке, Константину Макаровичу'
strsplit(adr, ',')[[1]][1]
## [1] "На деревню дедушке"
Регулярные выражения
Задание 1
Выберите из вектора month.name
все месяцы, в названии которых встречается буква m
или M
.
В функции grep()
есть аргумент ignore.case
, которые позволяет игнорировать различия в регистре букв паттерна. Так же есть аргумент value
, которые задает, что в результате функции возвращаются не номера элементов вектора, по которому идет поиск, а сами значения этого вектора.
Задание 2
Выберите из вектора month.name
все месяцы, в названии которых встречается буква m
или M
, или буквосочетание ry
.
При создани паттерна можно пользоваться логическими операторами, в частности |
, или
.
grep('m|ry', month.name, ignore.case = TRUE, value = TRUE)
## [1] "January" "February" "March" "May" "September" "November"
## [7] "December"
Задание 3
Выберите из вектора month.name
все месяцы, в названии которых встречается буква u
и после нее n
, независимо от регистра.
В регулярных выражениях реализовать оператор и
в явном виде сложно и нередко бессмысленно. Поэтому проще воспользоваться символами подстановки и мультипликатором - .*
означает `любоё знак.
grep('u.*n', month.name, ignore.case = TRUE, value = TRUE)
## [1] "June"
Задание 4
Выберите из вектора month.name
все месяцы, в названии которых встречается буква u
и n
, независимо от регистра и порядка букв.
Для того, чтобы учесть разный порядок букв, надо строго указать такую возможность. Проще всего это сделать с помощью групп и логического оператора или
.
grep('(u.*n)|(n.*u)', month.name, ignore.case = TRUE, value = TRUE)
## [1] "January" "June"
Задание 5
У вас есть вектор mtcars_names
(создается как mtcars_names <- rownames(mtcars)
) названий машин из таблицы mtcars
. Используя классы символов или POSIX символьные классы, выберите все названия, в которых встречаются цифры.
mtcars_names <- rownames(mtcars)
# решение через классы символов
grep('[0-9]', mtcars_names, value = TRUE)
## [1] "Mazda RX4" "Mazda RX4 Wag" "Datsun 710" "Hornet 4 Drive"
## [5] "Duster 360" "Merc 240D" "Merc 230" "Merc 280"
## [9] "Merc 280C" "Merc 450SE" "Merc 450SL" "Merc 450SLC"
## [13] "Fiat 128" "Camaro Z28" "Fiat X1-9" "Porsche 914-2"
## [17] "Volvo 142E"
# решение через POSIX-классы символов
grep('[[:digit:]]', mtcars_names, value = TRUE)
## [1] "Mazda RX4" "Mazda RX4 Wag" "Datsun 710" "Hornet 4 Drive"
## [5] "Duster 360" "Merc 240D" "Merc 230" "Merc 280"
## [9] "Merc 280C" "Merc 450SE" "Merc 450SL" "Merc 450SLC"
## [13] "Fiat 128" "Camaro Z28" "Fiat X1-9" "Porsche 914-2"
## [17] "Volvo 142E"
Задание 6
Выберите из списка mtcars_names
все названия, которые начинаются с M
.
grep('^M', mtcars_names, value = TRUE)
## [1] "Mazda RX4" "Mazda RX4 Wag" "Merc 240D" "Merc 230"
## [5] "Merc 280" "Merc 280C" "Merc 450SE" "Merc 450SL"
## [9] "Merc 450SLC" "Maserati Bora"
Задание 7
Выберите из списка mtcars_names
все названия, которые начинаются с M
и заканчиваются на число и букву.
grep('^M.+([0-9][a-z])$', mtcars_names, ignore.case = TRUE, value = TRUE)
## [1] "Merc 240D" "Merc 280C"
Задание 8
Придумайте регулярное выражение, которое поможет выбрать следующие два названия из спиcка mtcars_names
: "Fiat X1-9" и "Porsche 914-2".
grep('(-[0-9]*)$', mtcars_names, ignore.case = TRUE, value = TRUE)
## [1] "Fiat X1-9" "Porsche 914-2"
Задание 9
Придумайте регулярное выражение, которое поможет выбрать название "Valiant" из спиcка mtcars_names
.
Valiant
- единственное название, в котором нет пробелов. Выделять паттерном все слова, в кторых нет пробелов (т.е., через отрицание) может быть достаточно долго. Поэтому проще выбрать все названия, в которых пробел встречается, и потом на уровне индекса извлечь все прочие элементы вектора, для которых grepl('\\s', mtcars_names)
вернет FALSE
.
mtcars_names[!grepl('\\s', mtcars_names)]
## [1] "Valiant"
Задание 10
В векторе mtcars_names
замените все пробелы на знак _
. Перезаписывать вектор не надо.
gsub('\\s+', '_', mtcars_names)
## [1] "Mazda_RX4" "Mazda_RX4_Wag" "Datsun_710"
## [4] "Hornet_4_Drive" "Hornet_Sportabout" "Valiant"
## [7] "Duster_360" "Merc_240D" "Merc_230"
## [10] "Merc_280" "Merc_280C" "Merc_450SE"
## [13] "Merc_450SL" "Merc_450SLC" "Cadillac_Fleetwood"
## [16] "Lincoln_Continental" "Chrysler_Imperial" "Fiat_128"
## [19] "Honda_Civic" "Toyota_Corolla" "Toyota_Corona"
## [22] "Dodge_Challenger" "AMC_Javelin" "Camaro_Z28"
## [25] "Pontiac_Firebird" "Fiat_X1-9" "Porsche_914-2"
## [28] "Lotus_Europa" "Ford_Pantera_L" "Ferrari_Dino"
## [31] "Maserati_Bora" "Volvo_142E"
Задание 11
В векторе mtcars_names
с помощью регулярных выражений удалите все символы, кроме первого слова (фактически останется только название производителя). Перезаписывать вектор не надо.
gsub('\\s.+', '', mtcars_names)
## [1] "Mazda" "Mazda" "Datsun" "Hornet" "Hornet" "Valiant"
## [7] "Duster" "Merc" "Merc" "Merc" "Merc" "Merc"
## [13] "Merc" "Merc" "Cadillac" "Lincoln" "Chrysler" "Fiat"
## [19] "Honda" "Toyota" "Toyota" "Dodge" "AMC" "Camaro"
## [25] "Pontiac" "Fiat" "Porsche" "Lotus" "Ford" "Ferrari"
## [31] "Maserati" "Volvo"
Задание 12
Скройте последние четыре цифры в номерах телефонов ('+7-812-999-9999', '+7-3832-66-6666', '+7-499-555-7878') знаками XXXX
.
Задание 13
У вас есть вектор номеров телефонов в разном формате. Необходимо все привести к одному формату вида +7-(xxx)-xxx-xxxx
. С учетом кода страны длина номера составляет ровно 11 цифр, значение фиксировано независимо от формата.
Самым простым решение будет сделать все в два этапа - сначала удалить все символы -
, а потом переразбить полученную строку через группы. Так как мы точно знаем, что у нас в каждом номере 11 знаков, мы можем их изначально разбить по группам с квантификаторами, чтобы потом эти группы пересобрать в нужном формате.
phones <- c('+7-916-999-9999', '+7-905-5557878', '+7-923-233-23-23', '+7-962-6666-666', '+79119000000')
phones <- gsub('-', '', phones)
gsub('\\+7([0-9]{3})([0-9]{3})([0-9]{4})', '+7-(\\1)-\\2-\\3', phones)
## [1] "+7-(916)-999-9999" "+7-(905)-555-7878" "+7-(923)-233-2323"
## [4] "+7-(962)-666-6666" "+7-(911)-900-0000"
Задание 14
Удалите из строки meta:chara.*cters
лишние знаки.
Так как символы .
и *
являются мета-символами, управляющими конструкциями, их необходимо экранировать двумя обратными слэшами \\
.
gsub(':|\\.|\\*', '', 'meta:chara.*cters')
## [1] "metacharacters"