keep(), discard() e filtragem de listas
Filtre elementos de listas por funções predicado para criar fluxos organizados.
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 é TRUEdiscard(.x, .p)— remove os elementos cujo predicado é TRUEcompact(.x)— remove todos os elementos NULLdetect(.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 corresponderemsome(.x, .p)— TRUE se algum elemento correspondernone(.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))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
- map() e variantes tipadas
- map2() e pmap() para várias entradas
- reduce(), accumulate() e walk()
- keep(), discard() e filtragem de listas