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 ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- map() และรูปแบบที่ระบุชนิด
- map2() และ pmap() สำหรับอินพุตหลายรายการ
- reduce(), accumulate() และ walk()
- keep(), discard() และการกรองรายการ