R Academy · Aula

keep(), discard() e filtragem de listas

Filtre elementos de listas por funções predicado para criar fluxos organizados.

Aula 4 de 413 etapas

keep(), discard() e filtragem de listas é uma aula grátis de R Academy no CoddyKit. Esta é a aula 4 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.

Filtrando listas com purrr

O purrr oferece uma família de funções para filtrar, pesquisar e testar listas com base em predicados. Um predicado é uma função que retorna TRUE ou FALSE. Essas funções substituem chamadas extensas de Filter() e laços condicionais.

library(purrr)

# A mixed list to filter
mixed <- list(1L, 'hello', 3.14, NULL, TRUE, 42L, 'world', NULL)

cat('Total elements:', length(mixed), '\n')
cat('Non-NULL elements:', length(compact(mixed)))

keep() — Mantendo elementos que correspondem a um predicado

keep(.x, .p) mantém apenas os elementos de .x para os quais o predicado .p retorna TRUE. É o oposto de discard(). O predicado pode ser um nome de função, uma fórmula ou um vetor lógico.

library(purrr)

mixed <- list(1L, 'hello', 3.14, TRUE, 42L, 'world', 2.7)

# Keep only numeric values
numeric_only <- keep(mixed, is.numeric)
print(numeric_only)

# Keep values greater than 5
keep(mixed, ~is.numeric(.x) && .x > 5)

discard() — Removendo elementos que correspondem a um predicado

discard(.x, .p) remove os elementos para os quais o predicado retorna TRUE, mantendo os demais. É o inverso de keep(). Use-o para filtrar valores nulos, NAs ou tipos indesejados de uma lista.

library(purrr)

results <- list(
  model_a = list(rmse=2.5, converged=TRUE),
  model_b = list(rmse=NA, converged=FALSE),
  model_c = list(rmse=1.8, converged=TRUE),
  model_d = list(rmse=NA, converged=FALSE)
)

# Discard models that did not converge
converged_models <- discard(results, ~!.x$converged)
map_dbl(converged_models, ~.x$rmse)

compact() — Removendo elementos NULL

compact(.x) remove todos os elementos NULL de uma lista — equivale a discard(.x, is.null), mas é mais conciso. É especialmente útil após chamadas de map() que podem retornar NULL para algumas entradas.

library(purrr)

# Simulate fetching data that might return NULL
ids <- 1:6
fetch_data <- function(id) {
  if (id %% 2 == 0) NULL else list(id=id, value=id*10)
}

raw_results <- map(ids, fetch_data)
cat('With NULLs:', length(raw_results), '\n')

clean_results <- compact(raw_results)
cat('Without NULLs:', length(clean_results))

detect() — Encontrando a primeira correspondência

detect(.x, .p) retorna o primeiro elemento que satisfaz o predicado. Se nenhum elemento corresponder, retorna NULL. Use detect(.right=TRUE) para pesquisar da direita e encontrar a última correspondência.

library(purrr)

prices <- list(15.99, 8.50, 23.99, 5.25, 19.99, 4.75)

# Find first price under $10
first_cheap <- detect(prices, ~.x < 10)
cat('First price under $10:', first_cheap, '\n')

# Find last price under $10
last_cheap <- detect(prices, ~.x < 10, .right=TRUE)
cat('Last price under $10:', last_cheap)

detect_index() — Encontrando a posição da primeira correspondência

detect_index(.x, .p) retorna o índice do primeiro elemento que satisfaz o predicado (ou 0L se nenhum for encontrado). É útil quando você precisa da posição, e não do valor — por exemplo, para atualizar ou extrair esse elemento.

library(purrr)

models <- list(
  list(name='lm', rmse=3.5),
  list(name='rf', rmse=2.1),
  list(name='xgb', rmse=1.8),
  list(name='svm', rmse=2.4)
)

# Find the index of the best model (lowest RMSE)
best_idx <- detect_index(models, function(m) m$rmse < 2.0)
cat('Best model index:', best_idx, '\n')
cat('Best model name:', models[[best_idx]]$name)

every() — Todos os elementos correspondem?

every(.x, .p) retorna TRUE se o predicado for satisfeito para todos os elementos. Interrompe a avaliação ao encontrar o primeiro FALSE. Equivale a all(map_lgl(.x, .p)), mas é avaliado de forma preguiçosa.

library(purrr)

batch_results <- list(
  list(status='success', rows=150),
  list(status='success', rows=200),
  list(status='success', rows=175)
)

failed_batch <- list(
  list(status='success', rows=150),
  list(status='error', rows=0),
  list(status='success', rows=175)
)

cat('All success (good):', every(batch_results, ~.x$status == 'success'), '\n')
cat('All success (bad):', every(failed_batch, ~.x$status == 'success'))

some() — Algum elemento corresponde?

some(.x, .p) retorna TRUE se pelo menos um elemento satisfizer o predicado. Interrompe a avaliação ao encontrar o primeiro TRUE. Equivale a any(map_lgl(.x, .p)), mas é avaliado de forma preguiçosa.

library(purrr)

datasets <- list(
  data.frame(x=1:3, y=c(1,NA,3)),
  data.frame(x=4:6, y=7:9),
  data.frame(x=7:9, y=c(NA,NA,NA))
)

# Does any dataset contain NAs?
cat('Any NAs:', some(datasets, anyNA), '\n')

# Is every dataset NA-free?
cat('All clean:', every(datasets, ~!anyNA(.x)))

none() — Nenhum elemento corresponde?

none(.x, .p) retorna TRUE se nenhum elemento satisfizer o predicado. Equivale a !some(.x, .p), mas é mais claro em contextos de validação nos quais você deseja afirmar a ausência de uma condição.

library(purrr)

api_responses <- list(
  list(code=200, data='OK'),
  list(code=200, data='OK'),
  list(code=201, data='Created')
)

# Ensure no errors occurred
no_errors <- none(api_responses, ~.x$code >= 400)
cat('No errors:', no_errors, '\n')

# Check another batch
bad_batch <- c(api_responses, list(list(code=500, data='Error')))
none(bad_batch, ~.x$code >= 400)

Combinando keep() com map()

Encadear keep() (ou discard()) com map() é um padrão comum: primeiro filtre a lista para manter os elementos relevantes e depois aplique uma transformação. Isso separa claramente a lógica de filtragem da lógica de processamento.

library(purrr)

model_results <- list(
  list(name='A', converged=TRUE, rmse=2.5),
  list(name='B', converged=FALSE, rmse=NA),
  list(name='C', converged=TRUE, rmse=1.8),
  list(name='D', converged=TRUE, rmse=3.1)
)

# Keep converged, extract RMSE
model_results %>%
  keep(~.x$converged) %>%
  map_dbl(~.x$rmse)

Usando keep() com funções is.*

As funções predicadas integradas do R, is.* (is.numeric, is.character, is.null, is.na, is.finite), funcionam diretamente como predicados em keep() e discard(), sem a necessidade de envolvê-las em ~.

library(purrr)

mixed_env <- list(
  count = 42L,
  name = 'Alice',
  ratio = 3.14,
  flag = TRUE,
  missing = NULL,
  data = data.frame(x=1:3)
)

# Extract different types
numeric_items <- keep(mixed_env, is.numeric)
cat('Numeric items:', length(numeric_items), '\n')

# Remove NULL items
cleaned <- discard(mixed_env, is.null)
cat('After removing NULL:', length(cleaned))

Verificação rápida

O que detect(.x, .p) retorna quando nenhum elemento de .x satisfaz o predicado .p?

Recapitulação: funções de filtragem de listas

Principais conclusões sobre as ferramentas de filtragem de listas do purrr:

  • keep(.x, .p) — mantém os elementos cujo predicado é TRUE
  • discard(.x, .p) — remove os elementos cujo predicado é TRUE
  • compact(.x) — remove todos os elementos NULL
  • detect(.x, .p) — retorna o primeiro elemento que corresponde ao predicado (ou NULL)
  • detect_index(.x, .p) — retorna o índice da primeira correspondência (ou 0L)
  • every(.x, .p) — TRUE se todos os elementos corresponderem
  • some(.x, .p) — TRUE se algum elemento corresponder
  • none(.x, .p) — TRUE se nenhum elemento corresponder
library(purrr)

scores <- list(45, 72, 88, 53, 91, 67, 39, 85)

passing <- keep(scores, ~.x >= 60)
failing <- discard(scores, ~.x >= 60)

cat('Passing:', length(passing), 'students\n')
cat('Failing:', length(failing), 'students\n')
cat('All pass:', every(scores, ~.x >= 60), '\n')
cat('Any fail:', some(scores, ~.x < 60), '\n')
cat('First pass score:', detect(scores, ~.x >= 60))
Grátis para começar

Aprenda R com um tutor de IA — grátis

Escreva e execute código real no seu navegador, obtenha ajuda instantânea de um tutor de IA 24/7 e continue de onde parou na web ou no app.

Cursos
43
Aulas
159

Perguntas Frequentes

A aula “keep(), discard() e filtragem de listas” é grátis?

Sim — o texto completo de “keep(), discard() e filtragem de listas” é 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 “keep(), discard() e filtragem de listas”?

Filtre elementos de listas por funções predicado para criar fluxos organizados. 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 4 de 4.

Quanto tempo leva a aula “keep(), discard() e filtragem de listas”?

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