keep(), discard() og filtrering av lister
Filtrer listeelementer med predikatfunksjoner for ryddige pipelines.
keep(), discard() og filtrering av lister er en gratis leksjon i R Academy på CoddyKit. Dette er leksjon 4 av 4. Du kan lese valgfritt 3 leksjoner fra denne læringsstien gratis i sin helhet – deretter låser CoddyKit PRO opp alle leksjoner, samt praktisk øving med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt. Den er en del av læringsløpet i R Academy, og fremdriften din synkroniseres mellom nettet og CoddyKit-appen. Kurset i R Academy inneholder totalt 4 leksjoner.
Filtrere lister med purrr
purrr tilbyr en familie med funksjoner for å filtrere, søke i og teste lister basert på predikater. Et predikat er en funksjon som returnerer TRUE eller FALSE. Disse funksjonene erstatter omstendelige kall til Filter() og betingede løkker.
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() — behold elementer som samsvarer med et predikat
keep(.x, .p) beholder bare elementene i .x der predikatet .p returnerer TRUE. Det er det motsatte av discard(). Predikatet kan være et funksjonsnavn, en formel eller en logisk vektor.
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() — fjern elementer som samsvarer med et predikat
discard(.x, .p) fjerner elementene der predikatet returnerer TRUE, og beholder resten. Det er motstykket til keep(). Bruk det til å filtrere bort nullverdier, NA-er eller uønskede typer fra en liste.
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() — fjern NULL-elementer
compact(.x) fjerner alle NULL-elementer fra en liste — tilsvarende discard(.x, is.null), men mer kortfattet. Dette er særlig nyttig etter map()-kall som kan returnere NULL for enkelte inndata.
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() — finn første treff
detect(.x, .p) returnerer det første elementet som oppfyller predikatet. Hvis ingen elementer samsvarer, returnerer den NULL. Bruk detect(.right=TRUE) til å søke fra høyre og finne det siste treffet.
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() — finn posisjonen til første treff
detect_index(.x, .p) returnerer indeksen til det første elementet som oppfyller predikatet (eller 0L hvis ingen blir funnet). Dette er nyttig når De trenger posisjonen, ikke verdien — for eksempel for å oppdatere eller hente ut elementet.
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() — samsvarer alle elementene?
every(.x, .p) returnerer TRUE hvis predikatet er oppfylt for alle elementene. Den avslutter ved første FALSE. Tilsvarer all(map_lgl(.x, .p)), men evalueres latensk.
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() — samsvarer noen av elementene?
some(.x, .p) returnerer TRUE hvis minst ett element oppfyller predikatet. Den avslutter ved første TRUE. Tilsvarer any(map_lgl(.x, .p)), men evalueres latensk.
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() — samsvarer ingen av elementene?
none(.x, .p) returnerer TRUE hvis ingen elementer oppfyller predikatet. Det tilsvarer !some(.x, .p), men er tydeligere i valideringssammenhenger der De vil bekrefte at en betingelse ikke forekommer.
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)Kombinere keep() med map()
Å lenke sammen keep() (eller discard()) med map() er et vanlig mønster: Filtrer først listen til relevante elementer, og bruk deretter en transformasjon. På denne måten holdes filtreringslogikken og behandlingslogikken tydelig atskilt.
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)Bruke keep() med is.*-funksjoner
R sine innebygde is.*-predikatfunksjoner (is.numeric, is.character, is.null, is.na, is.finite) fungerer direkte som predikater i keep() og discard(), uten at de må pakkes inn i ~.
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))Kort sjekk
Hva returnerer detect(.x, .p) når ingen elementer i .x oppfyller predikatet .p?
Oppsummering: Funksjoner for filtrering av lister
Dette er det viktigste å huske om purrrs verktøy for filtrering av lister:
keep(.x, .p)— beholder elementer der predikatet er TRUEdiscard(.x, .p)— fjerner elementer der predikatet er TRUEcompact(.x)— fjerner alle NULL-elementerdetect(.x, .p)— returnerer det første elementet som samsvarer med predikatet (eller NULL)detect_index(.x, .p)— returnerer indeksen til det første treffet (eller 0L)every(.x, .p)— TRUE hvis alle elementene samsvarersome(.x, .p)— TRUE hvis minst ett element samsvarernone(.x, .p)— TRUE hvis ingen elementer samsvarer
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))Lær deg R med en AI-veileder – gratis
Skriv og kjør ekte kode i nettleseren, få umiddelbar hjelp fra en AI-veileder som er tilgjengelig døgnet rundt, og fortsett der du slapp – på nettet eller i appen.
- Kurs
- 43
- Leksjoner
- 159
Ofte stilte spørsmål
Er leksjonen «keep(), discard() og filtrering av lister» gratis?
Ja – du kan lese valgfritt 3 av leksjonene i læringsstien R Academy, inkludert «keep(), discard() og filtrering av lister», gratis i sin helhet her på nettet. Deretter låser CoddyKit PRO opp alle leksjoner, samt interaktiv øving med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt. Kurset i R Academy inneholder totalt 4 leksjoner.
Hva lærer jeg i «keep(), discard() og filtrering av lister»?
Filtrer listeelementer med predikatfunksjoner for ryddige pipelines. Du øver på R Academy med praktisk kode som du kjører direkte i nettleseren, mens en AI-veileder som er tilgjengelig døgnet rundt, svarer på spørsmålene dine mens du jobber deg gjennom leksjonen.
Trenger jeg erfaring for å begynne med R Academy?
Ingen tidligere erfaring er nødvendig. R Academy på CoddyKit er lagt opp for både nybegynnere og viderekomne, så De kan begynne her eller helt fra start og lære i Deres eget tempo. Dette er leksjon 4 av 4.
Hvor lang tid tar leksjonen «keep(), discard() og filtrering av lister»?
De fleste CoddyKit-leksjoner tar omtrent 5–10 minutter. Hver leksjon er kort og interaktiv, slik at De gjør jevne fremskritt og kan fortsette akkurat der De slapp – både på nettet og i appen.
Kan jeg skrive og kjøre kode i denne R Academy-leksjonen?
Ja. Alle R Academy-leksjoner har en innebygd kodeeditor, slik at De kan skrive og kjøre ekte kode direkte i nettleseren og få umiddelbar tilbakemelding fra AI – uten lokal konfigurering.
Alle leksjonene i dette kurset
- map() og typede varianter
- map2() og pmap() for flere inndata
- reduce(), accumulate() og walk()
- keep(), discard() og filtrering av lister