map() и типизированные варианты
Применяйте функции к спискам с помощью map(), map_dbl(), map_chr() и map_lgl().
«map() и типизированные варианты» — бесплатный урок R Academy на CoddyKit. Это урок 1 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения R Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс R Academy содержит 4 уроков всего.
Функциональное программирование с purrr
Пакет purrr предоставляет согласованные и типобезопасные инструменты для функционального программирования в R. Вместо написания циклов for Вы применяете функцию к списку или вектору с помощью map. В результате код становится понятнее, а его поведение — проще для анализа и комбинирования.
library(purrr)
# A list of numbers
numbers <- list(1, 4, 9, 16, 25)
# Apply sqrt() to each element
result <- map(numbers, sqrt)
print(result)map() — всегда возвращает список
map(.x, .f) применяет функцию .f к каждому элементу .x и возвращает список. Входными данными могут быть список, вектор или таблица данных (в этом случае перебираются столбцы). Это наиболее универсальный вариант map.
library(purrr)
# Map over a character vector
fruits <- c('apple', 'banana', 'cherry')
# nchar() counts characters in each string
result <- map(fruits, nchar)
print(result) # Returns a list
print(class(result))map_dbl() — возвращает числовой вектор
map_dbl(.x, .f) применяет .f к элементам .x и возвращает числовой (double) вектор. Если какой-либо результат не является одним числовым значением, возникает ошибка — такая типобезопасность помогает рано обнаруживать ошибки.
library(purrr)
groups <- list(
A = c(10, 20, 30),
B = c(5, 15, 25, 35),
C = c(100, 200)
)
# Compute mean for each group — returns a named numeric vector
means <- map_dbl(groups, mean)
print(means)
print(class(means))map_chr() — возвращает символьный вектор
map_chr(.x, .f) применяет функцию и возвращает символьный вектор. Это полезно для извлечения строковых атрибутов, форматирования результатов или построения путей к файлам. Функция должна возвращать одну строку для каждого элемента.
library(purrr)
models <- list(
m1 = lm(mpg ~ wt, data=mtcars),
m2 = lm(mpg ~ hp, data=mtcars),
m3 = lm(mpg ~ cyl, data=mtcars)
)
# Extract the formula from each model as a string
map_chr(models, function(m) deparse(formula(m)))map_lgl() — возвращает логический вектор
map_lgl(.x, .f) возвращает логический вектор из значений TRUE/FALSE. Это идеально подходит для проверки условий во всём списке — например, чтобы определить, какие элементы соответствуют критерию.
library(purrr)
datasets <- list(
df1 = data.frame(x=1:3, y=c(NA,2,3)),
df2 = data.frame(x=1:3, y=4:6),
df3 = data.frame(x=c(NA,NA,3), y=1:3)
)
# Does each data frame contain any NA values?
map_lgl(datasets, function(df) anyNA(df))map_int() — возвращает целочисленный вектор
map_int(.x, .f) возвращает целочисленный вектор. Используйте её, когда функция возвращает количества, индексы или другие целые числовые результаты. Обратите внимание: в R функции length() и nrow() возвращают целые числа.
library(purrr)
my_lists <- list(
a = 1:10,
b = letters[1:5],
c = c(TRUE, FALSE, TRUE, TRUE)
)
# Count elements in each list item
map_int(my_lists, length)map_df() / map_dfr() — возвращают датафрейм
map_df(.x, .f) (псевдоним: map_dfr()) применяет .f и объединяет результаты по строкам в один датафрейм. Для каждого элемента функция должна возвращать датафрейм или тиббл. map_dfc() вместо этого объединяет результаты по столбцам.
library(purrr)
files <- c('sales_q1', 'sales_q2', 'sales_q3')
# Simulate reading and labeling each file
map_df(files, function(f) {
data.frame(
file = f,
rows = sample(50:100, 1),
cols = 5
)
})Анонимные функции с ~
purrr поддерживает компактную формульную запись анонимных функций: ~expr, где .x обозначает текущий элемент. Это позволяет не писать function(x) expr и делает код лаконичнее. Обе записи работают одинаково.
library(purrr)
numbers <- list(1, 4, 9, 16, 25)
# Three equivalent ways:
result1 <- map(numbers, function(x) x^2)
result2 <- map(numbers, ~.x^2)
result3 <- map_dbl(numbers, ~.x^2)
print(result2)
print(result3)Обход именованного списка
Если .x — именованный список или вектор, результат map() сохраняет эти имена. map_dbl() и другие типизированные варианты также сохраняют имена, благодаря чему результаты понятны сами по себе.
library(purrr)
region_data <- list(
East = c(100, 120, 115, 130),
West = c(200, 195, 210, 205),
North = c(80, 85, 90, 88)
)
# Named results
map_dbl(region_data, mean)Использование map() со столбцами датафрейма
Датафрейм — это список столбцов. map(df, fn) применяет fn к каждому столбцу. В сочетании с map_dbl() это компактный способ сразу вычислить статистический показатель для каждого столбца.
library(purrr)
df <- data.frame(
score_a = c(85, 90, 78, 92),
score_b = c(88, 85, 80, 95),
score_c = c(92, 88, 84, 90)
)
# Mean of every column
map_dbl(df, mean)Вложенные вызовы map()
Вызовы map() можно вкладывать для многоуровневого перебора: внешний вызов выполняет обход групп, а внутренний — параметров. Это заменяет вложенные циклы for чистой структурой, которую легко комбинировать. Для удобства чтения ограничивайте глубину вложенности двумя уровнями.
library(purrr)
groups <- list(A = 1:5, B = 6:10)
functions <- list(mean=mean, sd=sd, min=min)
# Apply each function to each group
map(groups, function(g) {
map_dbl(functions, function(f) f(g))
})Быстрая проверка
В чём главное различие между map() и map_dbl()?
Итоги: map() и типизированные варианты
Главные выводы о map() и типизированных вариантах:
map(.x, .f)— всегда возвращает список; наиболее гибкий вариантmap_dbl()— возвращает числовой вектор; выдаёт ошибку при несовпадении типаmap_chr()— возвращает текстовый векторmap_lgl()— возвращает логический векторmap_int()— возвращает целочисленный векторmap_df()/map_dfr()— объединяют результаты по строкам в датафрейм- Сокращённая запись
~.x— компактный синтаксис анонимной функции - Именованные входные данные автоматически порождают именованные результаты
library(purrr)
# Typed map showcase
data_list <- list(
group_A = c(10, 20, 30),
group_B = c(5, 15),
group_C = c(100, 200, 300, 400)
)
cat('Counts:', map_int(data_list, length), '\n')
cat('Means: ', map_dbl(data_list, mean), '\n')
cat('Any>50:', map_lgl(data_list, ~any(.x > 50)), '\n')Изучай R с ИИ-репетитором — бесплатно
Пиши и запускай код прямо в браузере, получай мгновенную помощь от ИИ-репетитора 24/7 и продолжи учиться на сайте или в приложении.
- Курсы
- 43
- Уроки
- 159
Часто задаваемые вопросы
Урок «map() и типизированные варианты» бесплатный?
Да — полный текст урока «map() и типизированные варианты» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс R Academy, подпишись на CoddyKit PRO. Курс R Academy содержит 4 уроков всего.
Чему я научусь в уроке «map() и типизированные варианты»?
Применяйте функции к спискам с помощью map(), map_dbl(), map_chr() и map_lgl(). Ты практикуешь R Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать R Academy?
Предыдущий опыт не требуется. R Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 1 из 4.
Сколько времени занимает урок «map() и типизированные варианты»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке R Academy?
Да. Каждый урок R Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- map() и типизированные варианты
- map2() и pmap() для нескольких входных данных
- reduce(), accumulate() и walk()
- keep(), discard() и фильтрация списков