0Pricing
R Academy · Aula

map2() e pmap() para várias entradas

Itere simultaneamente sobre duas ou mais listas com map2() e pmap().

map2() e pmap() para várias entradas é uma aula grátis de R Academy no CoddyKit. Esta é a aula 2 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de R Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de R Academy inclui 4 aulas no total.

Iterando sobre várias entradas

map() itera sobre uma entrada por vez. Porém, muitas funções precisam de duas ou mais entradas paralelas. O map2() do purrr trabalha com duas entradas; pmap() trabalha com qualquer quantidade. Ambos mantêm a mesma garantia de retorno com tipo seguro.

library(purrr)

# Simulate: add corresponding elements from two vectors
x <- c(1, 2, 3, 4)
y <- c(10, 20, 30, 40)

# map2 applies fn(x[i], y[i]) for each i
result <- map2(x, y, function(a, b) a + b)
print(result)

map2() — Duas entradas paralelas

map2(.x, .y, .f) aplica .f(x_i, y_i) aos elementos correspondentes de .x e .y. Os dois vetores devem ter o mesmo comprimento (ou um deles deve ter comprimento 1 e ser reciclado). Retorna uma lista.

library(purrr)

names_vec <- c('Alice','Bob','Carol')
scores_vec <- c(85, 92, 78)

# Build a personalized message for each student
map2_chr(names_vec, scores_vec,
         ~paste(.x, 'scored', .y, 'points'))

map2() com a forma abreviada ~

A forma abreviada de fórmula ~expr funciona com map2(): .x se refere à primeira entrada, e .y se refere à segunda. Isso mantém concisas as funções anônimas com dois argumentos.

library(purrr)

lower_bounds <- c(0, 10, 20, 50)
upper_bounds <- c(9, 19, 49, 100)

# Create labels for each range
map2_chr(lower_bounds, upper_bounds,
         ~paste0('[', .x, '-', .y, ']'))

Variantes tipadas de map2()

Assim como map(), map2() tem variantes tipadas para garantir retornos com tipo seguro: map2_dbl(), map2_chr(), map2_lgl(), map2_int() e map2_df(). Use a variante correspondente ao tipo de saída esperado.

library(purrr)

actual <- c(100, 150, 200, 120)
target <- c(110, 140, 195, 130)

# Numeric: percentage achievement
map2_dbl(actual, target, ~round(100 * .x / .y, 1))

# Logical: did they meet their target?
map2_lgl(actual, target, ~.x >= .y)

pmap() — Qualquer quantidade de entradas

pmap(.l, .f) recebe uma lista de vetores como primeiro argumento. Cada vetor é um fluxo de entrada separado. A função recebe simultaneamente os elementos correspondentes de todos os fluxos de entrada.

library(purrr)

# Three parallel inputs
params <- list(
  name = c('Alice','Bob','Carol'),
  score = c(85, 92, 78),
  grade = c('B','A','C')
)

pmap_chr(params, function(name, score, grade) {
  paste(name, ':', score, '(', grade, ')')
})

pmap() com um quadro de dados

Um quadro de dados é uma lista de colunas; portanto, pode ser passado diretamente como primeiro argumento para pmap(). A função recebe os valores de uma linha como argumentos nomeados, associando os nomes das colunas aos nomes dos parâmetros.

library(purrr)

params_df <- data.frame(
  mean_val = c(0, 5, 10),
  sd_val = c(1, 2, 3),
  n = c(100, 50, 200)
)

# Generate samples from different normal distributions
set.seed(42)
results <- pmap(params_df, function(mean_val, sd_val, n) {
  rnorm(n, mean=mean_val, sd=sd_val)
})

map_dbl(results, mean)

Iterando sobre grades de parâmetros

Um uso comum de pmap() é iterar sobre uma grade de parâmetros de modelo. Use expand.grid() ou tidyr::expand_grid() para criar as combinações de parâmetros e, em seguida, use pmap() para executar o experimento em cada linha.

library(purrr)

# Create a parameter grid
grid <- expand.grid(
  learning_rate = c(0.01, 0.1),
  epochs = c(10, 50),
  batch_size = c(32, 64)
)

# Simulate model training results
set.seed(42)
grid$accuracy <- pmap_dbl(grid, function(learning_rate, epochs, batch_size) {
  base <- 0.5 + 0.3 * log10(epochs) + 0.1 * learning_rate
  round(min(base + rnorm(1, 0, 0.02), 0.99), 3)
})

print(grid[order(-grid$accuracy),])

map2_df() — Criando quadros de dados

map2_df() (ou map2_dfr()) aplica uma função a duas entradas paralelas e combina por linhas os quadros de dados resultantes. Isso é útil para comparar dois conjuntos de itens ou mesclar conjuntos de dados paralelos.

library(purrr)

q1_sales <- list(East=100, West=200, North=80)
q2_sales <- list(East=120, West=190, North=95)

map2_df(q1_sales, q2_sales, function(q1, q2) {
  data.frame(
    q1 = q1,
    q2 = q2,
    change = q2 - q1,
    pct = round(100*(q2-q1)/q1, 1)
  )
}, .id = 'region')

Combinando pmap() com nest()

Combinar pmap() com quadros de dados aninhados e parâmetros de modelo permite um padrão poderoso: armazene os hiperparâmetros e os dados em um único quadro de dados e, em seguida, use pmap() nas linhas para ajustar modelos com cada conjunto de parâmetros.

library(purrr)
library(dplyr)

# Simulate polynomial regression with different degrees
set.seed(42)
x <- 1:20
y <- 2*x + 0.5*x^2 + rnorm(20, 0, 10)
df <- data.frame(x=x, y=y)

configs <- data.frame(degree = 1:3)
configs$r2 <- map_dbl(configs$degree, function(d) {
  m <- lm(y ~ poly(x, d), data=df)
  summary(m)$r.squared
})

print(configs)

Tratamento de erros com possibly()

Em fluxos de trabalho com map2()/pmap(), uma entrada inválida pode interromper toda a operação. Envolva sua função com possibly(fn, otherwise=NA) para capturar erros e retornar um valor padrão, mantendo o fluxo de processamento em execução mesmo quando algumas entradas falharem.

library(purrr)

safe_log <- possibly(log, otherwise=NA_real_)

values <- list(10, -5, 100, 0, 50)

# Without possibly(): log() warns for negative numbers
# With possibly(): errors return NA, computation continues
map_dbl(values, safe_log)

Prática: validação cruzada com pmap()

Uma aplicação prática de pmap() é executar uma validação cruzada em k partes iterando sobre as atribuições das partes. pmap() encaminha os dados de treinamento e de teste de cada parte para a função de ajuste, retornando uma métrica de desempenho por parte.

library(purrr)

set.seed(42)
df <- data.frame(x=1:20, y=2*(1:20)+rnorm(20,0,3))
df$fold <- sample(rep(1:5, 4))

# Compute RMSE for each held-out fold
folds <- 1:5
rmse_vals <- map_dbl(folds, function(k) {
  train <- df[df$fold != k, ]
  test <- df[df$fold == k, ]
  m <- lm(y ~ x, data=train)
  preds <- predict(m, newdata=test)
  sqrt(mean((test$y - preds)^2))
})

cat('Per-fold RMSE:', round(rmse_vals, 2), '\n')
cat('Mean RMSE:', round(mean(rmse_vals), 2))

Verificação rápida

Qual função do purrr é apropriada para iterar simultaneamente sobre mais de dois vetores de entrada paralelos?

Recapitulação: map2() e pmap()

Principais pontos sobre o mapeamento com várias entradas:

  • map2(.x, .y, .f) — itera sobre duas entradas paralelas; .x e .y na forma abreviada ~
  • map2_dbl/chr/lgl/int/df() — variantes tipadas para retornos com tipo seguro
  • pmap(.l, .f) — itera simultaneamente sobre uma lista com qualquer quantidade de vetores
  • Passe um quadro de dados para pmap() — os nomes das colunas tornam-se nomes dos parâmetros da função
  • Use expand.grid() + pmap() para pesquisar uma grade de parâmetros
  • Envolva as funções com possibly(fn, NA) para tratar erros com segurança
library(purrr)

# pmap with a data frame: each row = one function call
params <- data.frame(
  mean_val = c(0, 10, 100),
  sd_val = c(1, 5, 20),
  label = c('control','mid','high')
)

pmap_chr(params, function(mean_val, sd_val, label) {
  sprintf('%s: mean=%.0f, sd=%.0f', label, mean_val, sd_val)
})

Perguntas Frequentes

A aula “map2() e pmap() para várias entradas” é grátis?

Sim — o texto completo de “map2() e pmap() para várias entradas” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de R Academy, atualize para CoddyKit PRO. O curso de R Academy inclui 4 aulas no total.

O que vou aprender em “map2() e pmap() para várias entradas”?

Itere simultaneamente sobre duas ou mais listas com map2() e pmap(). Você pratica R Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.

Preciso ter experiência prévia para começar R Academy?

Nenhuma experiência prévia é necessária. R Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 2 de 4.

Quanto tempo leva a aula “map2() e pmap() para várias entradas”?

A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.

Posso escrever e executar código nesta aula de R Academy?

Sim. Cada aula de R Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.

Todas as aulas deste curso

  1. map() e variantes tipadas
  2. map2() e pmap() para várias entradas
  3. reduce(), accumulate() e walk()
  4. keep(), discard() e filtragem de listas
← Voltar para R Academy