reduce(), accumulate() และ walk()
พับรายการ สร้างผลลัพธ์สะสม และใช้ผลข้างเคียงด้วย walk()
reduce(), accumulate() และ walk() เป็นบทเรียน R Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน R Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส R Academy มีบทเรียนทั้งหมด 4 บทเรียน
นอกเหนือจาก map() — ฟังก์ชันอื่นของ purrr
แม้ map() จะใช้ฟังก์ชันกับแต่ละองค์ประกอบอย่างอิสระ แต่งานบางอย่างต้องรวมองค์ประกอบ (reduce), สะสมผลลัพธ์ระหว่างทาง หรือใช้ฟังก์ชันเพื่อผลข้างเคียงเท่านั้น (walk) purrr มีฟังก์ชันเฉพาะสำหรับแต่ละกรณี
library(purrr)
# Example: combining a list of numbers into a single value
nums <- list(1, 2, 3, 4, 5)
# We want: 1 + 2 + 3 + 4 + 5 = 15
# map() can't do this — it returns 5 separate results
# reduce() folds the list into one value
result <- reduce(nums, `+`)
cat('Sum via reduce:', result)reduce() — ยุบรายการให้เหลือค่าเดียว
reduce(.x, .f, .init) ใช้ .f กับองค์ประกอบของ .x แบบสะสมจากซ้ายไปขวา โดยยุบรายการให้เหลือค่าเดียว reduce(list(a,b,c), f) จะคำนวณ f(f(a,b),c)
library(purrr)
# reduce with max: find the overall maximum
values <- list(42, 17, 89, 55, 23)
result <- reduce(values, max)
cat('Maximum:', result, '\n')
# reduce with paste: concatenate strings
words <- list('The', 'quick', 'brown', 'fox')
reduce(words, paste)reduce() กับ .init
อาร์กิวเมนต์ .init กำหนดค่าเริ่มต้น (ค่า seed) การเรียกครั้งแรกจะเป็น f(.init, x[1]) สิ่งนี้จำเป็นเมื่อรายการอาจว่างเปล่า (ผลลัพธ์จะเป็น .init) หรือเมื่อคุณต้องการสถานะเริ่มต้นเฉพาะ
library(purrr)
# Running count of elements matching a condition
data <- list(5, 12, 3, 18, 7, 15, 2)
# Count values greater than 10, starting from 0
reduce(data, function(count, x) count + (x > 10), .init = 0L)
# Also useful for string building:
reduce(c('A','B','C'), paste, sep='-', .init='START')reduce() กับกรอบข้อมูล — การเชื่อมต่อการรวม
การใช้งาน reduce() ที่ทรงพลังอย่างหนึ่งคือการรวมรายการกรอบข้อมูล แทนที่จะเขียน left_join(left_join(df1, df2), df3) ให้ใช้ reduce(list_of_dfs, left_join, by='key')
library(purrr)
library(dplyr)
base_df <- data.frame(id=1:3, name=c('Alice','Bob','Carol'))
scores <- data.frame(id=1:3, score=c(85,90,78))
grades <- data.frame(id=1:3, grade=c('B','A','C'))
city <- data.frame(id=1:3, city=c('NYC','LA','Chicago'))
dfs <- list(base_df, scores, grades, city)
reduce(dfs, left_join, by='id')accumulate() — เก็บผลลัพธ์ระหว่างทาง
accumulate(.x, .f) คล้ายกับ reduce() แต่เก็บค่าระหว่างทางทั้งหมดไว้ โดยคืนค่าเป็นเวกเตอร์ (หรือรายการ) ที่มีความยาวเท่ากับข้อมูลนำเข้า และแสดงผลลัพธ์สะสมหลังแต่ละขั้นตอน
library(purrr)
# Running sum — same as cumsum() but via accumulate
values <- c(100, 120, 95, 140, 160)
accumulate(values, `+`)
# Running maximum
accumulate(c(50, 52, 48, 55, 53, 58), max)accumulate() สำหรับผลลัพธ์ทีละขั้นตอน
accumulate() มีประโยชน์เป็นพิเศษสำหรับติดตามขั้นตอนของอัลกอริทึม การสร้างสตริงทีละอักขระ หรือกระบวนการใด ๆ ที่คุณต้องการตรวจสอบสถานะระหว่างทางทุกขั้น ไม่ใช่เฉพาะผลลัพธ์สุดท้าย
library(purrr)
# Compound interest step by step
principal <- 1000
rates <- c(0.05, 0.05, 0.05, 0.05, 0.05) # 5% per year
accumulate(rates, function(balance, rate) {
round(balance * (1 + rate), 2)
}, .init = principal)walk() — ผลข้างเคียงโดยไม่คืนค่า
walk(.x, .f) ใช้ .f กับแต่ละองค์ประกอบของ .x เพื่อสร้างผลข้างเคียงเท่านั้น (การพิมพ์ การเขียนไฟล์ การส่งข้อความ) ฟังก์ชันนี้คืนค่า .x แบบไม่แสดงผล จึงใช้ในกระบวนการทำงานต่อเนื่องได้โดยไม่ทำให้สายการทำงานขาดตอน
library(purrr)
# Print a summary for each dataset
datasets <- list(
mtcars = mtcars[,1:3],
iris = iris[,1:3]
)
walk(datasets, function(df) {
cat('Rows:', nrow(df), '| Cols:', ncol(df),
'| NAs:', sum(is.na(df)), '\n')
})walk() ในกระบวนการทำงานต่อเนื่อง
เนื่องจาก walk() คืนค่า .x แบบไม่แสดงผล คุณจึงแทรกไว้ในกระบวนการทำงานต่อเนื่องของ dplyr เพื่อบันทึกหรือพิมพ์ผลลัพธ์ระหว่างทางได้โดยไม่ทำให้ลำดับการทำงานขาดตอน ลองนึกภาพว่าเป็นจุดแทรกสำหรับแก้จุดบกพร่องหรือบันทึกเหตุการณ์
library(purrr)
library(dplyr)
results <- list(
East = data.frame(rep=c('A','B'), sales=c(100,120)),
West = data.frame(rep=c('C','D'), sales=c(200,190))
)
# Log each region's data, then continue processing
region_totals <- results %>%
walk(~cat('Processing:', nrow(.x), 'rows\n')) %>%
map_dbl(~sum(.x$sales))
print(region_totals)walk2() — ผลข้างเคียงกับข้อมูลนำเข้าสองชุด
walk2(.x, .y, .f) คือรูปแบบของ walk() ที่รับข้อมูลนำเข้าสองชุด กรณีใช้งานคลาสสิกคือการเขียนกรอบข้อมูลหลายรายการลงไฟล์ โดย .x เป็นรายการกรอบข้อมูล และ .y เป็นรายการเส้นทางไฟล์
library(purrr)
data_list <- list(
east = data.frame(x=1:3, y=4:6),
west = data.frame(x=7:9, y=10:12)
)
file_paths <- list(
'/tmp/east_data.csv',
'/tmp/west_data.csv'
)
# Write each data frame to its corresponding path
walk2(data_list, file_paths, function(df, path) {
write.csv(df, path, row.names=FALSE)
cat('Written:', path, '\n')
})iwalk() — walk พร้อมดัชนี
iwalk(.x, .f) คล้ายกับ walk() แต่ส่งชื่อองค์ประกอบ (หรือดัชนี) เป็นอาร์กิวเมนต์ที่สอง .y วิธีนี้สะดวกเมื่อคุณต้องทราบว่ากำลังประมวลผลองค์ประกอบใดเพื่อสร้างผลข้างเคียง
library(purrr)
region_counts <- list(East=150, West=200, North=85, South=120)
# Print each region with its rank
iwalk(region_counts, function(count, name) {
cat(name, ':', count, 'customers\n')
})reduce_right() — การยุบจากขวาไปซ้าย
reduce(.x, .f, .dir='backward') (หรือ reduce_right() ที่เลิกใช้แล้ว) ใช้ฟังก์ชันจากขวาไปซ้าย: f(a, f(b, f(c, d))) เรื่องนี้สำคัญสำหรับการดำเนินการที่สลับที่ไม่ได้ เช่น การลบหรือการสร้างสตริง
library(purrr)
words <- c('fox','brown','quick','The')
# Left-to-right: 'The quick brown fox'
reduce(rev(words), paste)
# Right-to-left: same effect but starting from right
reduce(words, function(a, b) paste(b, a))ตรวจสอบอย่างรวดเร็ว
คุณจะใช้ walk() แทน map() เมื่อใด
สรุป: reduce, accumulate, walk
ประเด็นสำคัญของ reduce, accumulate และ walk:
reduce(.x, .f)— ยุบรายการให้เหลือค่าเดียว (จากซ้ายไปขวา);.initกำหนดค่าเริ่มต้นreduce(list_of_dfs, left_join)— รูปแบบที่มีประสิทธิภาพสำหรับเชื่อมต่อการรวมหลายครั้งaccumulate(.x, .f)— คล้าย reduce แต่คืนผลลัพธ์ระหว่างทางทั้งหมดwalk(.x, .f)— ใช้เพื่อผลข้างเคียง (พิมพ์ เขียน บันทึก); คืนค่า.xwalk2(.x, .y, .f)— walk ที่รับข้อมูลเข้าสองชุด (เช่น กรอบข้อมูล + เส้นทางไฟล์)iwalk(.x, .f)— walk ที่ส่งชื่อองค์ประกอบเป็นอาร์กิวเมนต์ที่สอง
library(purrr)
library(dplyr)
# reduce() joins a list of data frames, accumulate() shows interim states
monthly_sums <- c(100, 120, 95, 140, 160, 130)
cat('reduce (total): ', reduce(monthly_sums, `+`), '\n')
cat('accumulate (running):', accumulate(monthly_sums, `+`), '\n')
# walk() for side-effect logging
results <- list(a=42, b=17, c=89)
walk(results, ~cat('Value:', .x, '\n'))เรียนรู้ R ด้วย AI tutor — ฟรี
เขียนและเรียกใช้โค้ดจริงในเบราว์เซอร์ของคุณ รับความช่วยเหลือทันทีจาก AI tutor 24/7 และเรียนรู้ต่อจากที่คุณหยุดบนเว็บหรือในแอป
- คอร์ส
- 43
- บทเรียน
- 159
คำถามที่พบบ่อย
บทเรียน “reduce(), accumulate() และ walk()” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “reduce(), accumulate() และ walk()” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส R Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส R Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “reduce(), accumulate() และ walk()”
พับรายการ สร้างผลลัพธ์สะสม และใช้ผลข้างเคียงด้วย walk() คุณปฏิบัติ R Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน R Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน R Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน
บทเรียน “reduce(), accumulate() และ walk()” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน R Academy นี้ได้ไหม
ได้ บทเรียน R Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- map() และรูปแบบที่ระบุชนิด
- map2() และ pmap() สำหรับอินพุตหลายรายการ
- reduce(), accumulate() และ walk()
- keep(), discard() และการกรองรายการ