0Pricing
R Academy · บทเรียน

keep(), discard() และการกรองรายการ

กรองสมาชิกของรายการด้วยฟังก์ชันเพรดิเคตเพื่อสร้างไปป์ไลน์ที่สะอาด

keep(), discard() และการกรองรายการ เป็นบทเรียน R Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน 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) จะเก็บเฉพาะองค์ประกอบของ .x ที่ฟังก์ชันเงื่อนไข .p คืนค่าเป็น TRUE ซึ่งตรงข้ามกับ 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) แต่กระชับกว่า ฟังก์ชันนี้มีประโยชน์เป็นพิเศษหลังการเรียก map() ที่อาจคืนค่า NULL สำหรับข้อมูลนำเข้าบางชุด

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.*

ฟังก์ชันเพรดิเคต is.* ในตัวของ R (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() และการกรองรายการ” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส R Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส R Academy มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “keep(), discard() และการกรองรายการ”

กรองสมาชิกของรายการด้วยฟังก์ชันเพรดิเคตเพื่อสร้างไปป์ไลน์ที่สะอาด คุณปฏิบัติ R Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน R Academy หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน R Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 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