Map и mapply
Часть раздела Логика и потоки выполнения путешествия по R на Coddy. Урок 33 из 64.
Map(f, xs, ys) проходит по двум или более векторам одновременно и вызывает f с одним элементом каждого из них: сначала с первыми элементами, затем со вторыми и так далее. Она возвращает список:
totals <- Map(function(q, p) q * p, c(2, 1, 3), c(4, 12, 2.5))
print(length(totals))
print(totals[[3]])Вывод:
[1] 3
[1] 7.5mapply() — это упрощающая версия, аналогичная sapply(), для нескольких векторов. unlist() также преобразует список из Map() в плоский вектор:
print(mapply(function(q, p) q * p, c(2, 1, 3), c(4, 12, 2.5)))
print(unlist(Map(function(a, b) a + b, 1:3, 4:6)))Результат:
[1] 8.0 12.0 7.5
[1] 5 7 9Векторы сопоставляются по позициям, поэтому они должны иметь одинаковую длину. mapply() задаёт текстовым результатам имена на основе первого вектора; USE.NAMES = FALSE удаляет имена:
items <- c("tea", "jam")
qty <- c(2, 3)
labels <- mapply(function(i, q) paste(q, "x", i), items, qty, USE.NAMES = FALSE)
print(labels)Вывод:
[1] "2 x tea" "3 x jam"Когда для каждой пары нужен if, напишите функцию с несколькими аргументами и передайте её в mapply(). Тогда условие выполнится один раз для каждой пары:
describe <- function(name, age) {
group <- if (age < 18) "minor" else "adult"
paste0(name, " (", group, ")")
}
print(mapply(describe, c("Ada", "Tim"), c(36, 12), USE.NAMES = FALSE))Вывод:
[1] "Ada (adult)" "Tim (minor)"Задание
ЛегкоДополните order_lines(items, qty, prices). Верните одну строку для каждого элемента, 2 x tea = 8.00: количество, x , элемент, = и произведение количества на цену с двумя знаками после десятичной точки. Используйте mapply() или Map().
Предоставленный код считывает элементы, количества и цены как три строки со значениями, разделёнными запятыми, и выводит каждую возвращённую строку.
Попробуйте сами
order_lines <- function(items, qty, prices) {
# Напишите свой код здесь
character(0)
}
# Предоставленный код ввода/вывода: оставьте его как есть
input <- suppressWarnings(readLines(file("stdin")))
cat(order_lines(strsplit(input[1], ",")[[1]], as.numeric(strsplit(input[2], ",")[[1]]), as.numeric(strsplit(input[3], ",")[[1]])), sep = "\n")
В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Логика и потоки выполнения
1Строки углублённо
Подстроки с substr()Форматирование с sprintf()Разделение и объединениеПоиск в строкахЗамена текстаПовторение — создание имени пользователя4Матрицы
Создание матрицИндексация матрицСводные данные по строкам и столбцамАрифметика матрицПовторение — схема рассадки7Семейство Apply
lapply и sapplyMap и mapplyFilter и FindReduceПовторение — конвейер обработки данных10Продвинутые конструкции управления
Функция switch()Векторизованный ifelse()repeat и breakРекурсивные функцииПовторение — классификатор оценок2Поиск по ключам и значениям
Поиск в именованных векторахПроверка ключейДобавление и удаление ключейПеребор имёнПовторение — биржа акций5Проект — Журнал оценок
Добавление учениковВыставление оценок3Множества и подсчёт
Уникальные значенияОперации с множествамиПроверка принадлежностиПодсчёт с помощью table()Повторение — гости мероприятия6Функции как значения
Анонимные функцииПередача функцийВозврат функцийЗамыкания с состояниемПовторение — правила скидок9Таблицы данных
Создание таблиц данныхСтолбцы и строкиФильтрация строкДобавление и сортировкаПовторение — отчёт о продажах12Проект — Трекер расходов
Запись расходовОбщие расходыПотренируйтесь самостоятельно: Онлайн-компилятор R