Передача функций
Часть раздела Логика и потоки выполнения путешествия по R на Coddy. Урок 28 из 64.
Функция может принимать другую функцию в качестве аргумента и вызывать её. apply_twice() ниже работает с любой функцией с одним аргументом:
apply_twice <- function(f, x) f(f(x))
print(apply_twice(\(x) x + 3, 10))
print(apply_twice(toupper, "ok"))Результат:
[1] 16
[1] "OK"Встроенные функции, такие как sum, max или toupper, тоже являются значениями, поэтому передавайте их по имени без скобок. Со скобками вместо этого они были бы вызваны:
summarize <- function(xs, how) how(xs)
print(summarize(c(4, 9, 2), max))
print(summarize(c(4, 9, 2), sum))Вывод:
[1] 9
[1] 15Функция, принимающая предикат — функцию, возвращающую TRUE или FALSE, — может подсчитывать или выбирать значения по любому правилу:
count_if <- function(xs, keep) {
n <- 0
for (x in xs) if (keep(x)) n <- n + 1
n
}
print(count_if(c(3, 8, 10, 5), \(x) x %% 2 == 0))
print(count_if(c(3, 8, 10, 5), \(x) x > 4))Результат:
[1] 2
[1] 3Вызывающая сторона определяет поведение, а функция предоставляет цикл, поэтому одна функция охватывает множество случаев:
transform_each <- function(xs, f) {
out <- c()
for (x in xs) out <- c(out, f(x))
out
}
print(transform_each(1:4, \(x) x * 10))
print(transform_each(c("a", "b"), toupper))Вывод:
[1] 10 20 30 40
[1] "A" "B"Задание
ЛегкоРеализуйте apply_n(f, x, n). Вызовите f для x, затем для результата — всего n раз, и верните итоговое значение. Если n равно 0, верните x без изменений.
Предоставленный код определяет три функции: double, inc и half. Он считывает имя одной из них, начальное значение и n, а затем выводит результат работы apply_n().
Попробуйте сами
apply_n <- function(f, x, n) {
# Напишите свой код здесь
x
}
# Предоставленный код ввода/вывода: оставьте его как есть
input <- suppressWarnings(readLines(file("stdin")))
ops <- list(double = \(x) x * 2, inc = \(x) x + 1, half = \(x) x / 2)
cat(apply_n(ops[[input[1]]], as.numeric(input[2]), as.numeric(input[3])), 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