0Pricing
R Academy · 강의

keep(), discard(), 목록 필터링

조건자 함수로 목록 요소를 필터링하여 깔끔한 파이프라인을 만듭니다.

keep(), discard(), 목록 필터링은(는) CoddyKit의 무료 R Academy 강의입니다. 이것은 4개 중 4번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 R Academy 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. R Academy 강의에는 총 4개의 강의가 포함되어 있습니다.

purrr로 목록 필터링하기

purrr는 조건자에 따라 목록을 필터링하고, 검색하고, 테스트하기 위한 함수 모음을 제공합니다. 조건자는 TRUE 또는 FALSE를 반환하는 함수입니다. 이러한 함수는 장황한 Filter() 호출과 조건부 반복문을 대신합니다.

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() — 조건자와 일치하는 요소 유지하기

keep(.x, .p)는 조건자 .p가 TRUE를 반환하는 .x의 요소만 유지합니다. discard()와 반대되는 함수입니다. 조건자는 함수 이름, 수식 또는 논리형 벡터일 수 있습니다.

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() — 조건자와 일치하는 요소 제거하기

discard(.x, .p)는 조건자가 TRUE를 반환하는 요소를 제거하고 나머지를 유지합니다. keep()의 반대 함수입니다. 목록에서 null, NA 또는 원하지 않는 형식을 걸러낼 때 사용하십시오.

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() — NULL 요소 제거하기

compact(.x)는 목록에서 모든 NULL 요소를 제거합니다. 이는 discard(.x, is.null)과 같지만 더 간결합니다. 일부 입력에 대해 NULL을 반환할 수 있는 map() 호출 뒤에 특히 유용합니다.

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() — 첫 번째 일치 항목 찾기

detect(.x, .p)는 조건자를 만족하는 첫 번째 요소를 반환합니다. 일치하는 요소가 없으면 NULL을 반환합니다. 오른쪽부터 검색하여 마지막 일치 항목을 찾으려면 detect(.right=TRUE)를 사용하십시오.

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() — 첫 번째 일치 항목의 위치 찾기

detect_index(.x, .p)는 조건자를 만족하는 첫 번째 요소의 인덱스를 반환합니다(찾지 못하면 0L). 값이 아니라 위치가 필요할 때 유용하며, 예를 들어 해당 요소를 수정하거나 추출할 때 사용할 수 있습니다.

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() — 모든 요소가 일치합니까?

every(.x, .p)는 모든 요소가 조건자를 만족하면 TRUE를 반환합니다. 첫 번째 FALSE에서 평가를 중단합니다. 지연 평가를 사용한다는 점을 제외하면 all(map_lgl(.x, .p))과 같습니다.

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() — 일치하는 요소가 있습니까?

some(.x, .p)는 하나 이상의 요소가 조건자를 만족하면 TRUE를 반환합니다. 첫 번째 TRUE에서 평가를 중단합니다. 지연 평가를 사용한다는 점을 제외하면 any(map_lgl(.x, .p))와 같습니다.

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() — 일치하는 요소가 없습니까?

none(.x, .p)는 조건자를 만족하는 요소가 하나도 없으면 TRUE를 반환합니다. !some(.x, .p)와 같지만, 조건이 없음을 확인하려는 검증 상황에서 의미가 더 분명하게 읽힙니다.

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)

keep()과 map() 결합하기

keep()(또는 discard())를 map()과 연결하는 방식은 흔히 사용되는 패턴입니다. 먼저 목록에서 관련 요소만 필터링한 다음 변환을 적용합니다. 이렇게 하면 필터링 로직과 처리 로직을 깔끔하게 분리할 수 있습니다.

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)

keep()과 is.* 함수 사용하기

R에 기본으로 제공되는 is.* 조건자 함수(is.numeric, is.character, is.null, is.na, is.finite)는 ~로 감싸지 않아도 keep()과 discard()에서 조건자로 바로 사용할 수 있습니다.

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))

빠른 확인

.x의 어떤 요소도 조건자 .p를 만족하지 않을 때 detect(.x, .p)는 무엇을 반환하나요?

복습: 목록 필터링 함수

purrr의 목록 필터링 도구에서 기억할 핵심 내용:

  • keep(.x, .p) — 조건자가 TRUE인 요소 유지
  • discard(.x, .p) — 조건자가 TRUE인 요소 제거
  • compact(.x) — 모든 NULL 요소 제거
  • detect(.x, .p) — 조건자와 일치하는 첫 번째 요소 반환(또는 NULL)
  • detect_index(.x, .p) — 처음 일치하는 요소의 인덱스 반환(또는 0L)
  • every(.x, .p) — 모든 요소가 일치하면 TRUE
  • some(.x, .p) — 하나 이상의 요소가 일치하면 TRUE
  • none(.x, .p) — 일치하는 요소가 없으면 TRUE
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))

자주 묻는 질문

“keep(), discard(), 목록 필터링” 강의는 무료인가요?

네 — “keep(), discard(), 목록 필터링” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 R Academy 강의 전체를 잠금 해제할 수 있습니다. R Academy 강의에는 총 4개의 강의가 포함되어 있습니다.

“keep(), discard(), 목록 필터링”에서 뭘 배우나요?

조건자 함수로 목록 요소를 필터링하여 깔끔한 파이프라인을 만듭니다. 브라우저에서 직접 실행하는 실습 코드로 R Academy을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.

R Academy을(를) 시작하는 데 경험이 필요한가요?

사전 경험은 필요하지 않습니다. CoddyKit의 R Academy은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 4번째 강의입니다.

“keep(), discard(), 목록 필터링” 강의는 얼마나 걸리나요?

대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.

이 R Academy 강의에서 코드를 작성하고 실행할 수 있나요?

네. 모든 R Academy 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.

이 강의의 모든 강의

  1. map()과 형식별 변형
  2. 여러 입력을 위한 map2()와 pmap()
  3. reduce(), accumulate(), walk()
  4. keep(), discard(), 목록 필터링
← R Academy(으)로 돌아가기