การซ้อนและคลายการซ้อนดาต้าเฟรม
ใช้ nest() และ unnest() เพื่อทำงานกับคอลัมน์รายการในกระบวนงาน tidy
การซ้อนและคลายการซ้อนดาต้าเฟรม เป็นบทเรียน R Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน R Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส R Academy มีบทเรียนทั้งหมด 4 บทเรียน
คอลัมน์แบบรายการและข้อมูลซ้อนกัน
คอลัมน์แบบรายการ คือคอลัมน์ใน data frame ที่แต่ละเซลล์เก็บออบเจ็กต์ของ R ไว้ (เวกเตอร์ data frame โมเดล หรือรายการ) ทำให้สามารถเก็บข้อมูลย่อยที่มีโครงสร้างไว้ร่วมกับคอลัมน์อื่นได้ และรองรับกระบวนการทำงานแบบแยกตามกลุ่มที่มีประสิทธิภาพ
library(tidyr)
library(dplyr)
# A simple data frame with a list-column
df <- data.frame(
group = c('A','B','C'),
n = c(3, 2, 4)
)
df$values <- list(c(1,2,3), c(4,5), c(6,7,8,9))
print(df)
print(df$values[[1]]) # Access the first list elementnest() — การสร้าง data frame แบบซ้อนกัน
nest(df, data = c(col1, col2)) จัดกลุ่มแถวตามคอลัมน์ที่ไม่ได้ซ้อนกัน แล้วบรรจุคอลัมน์ที่ระบุลงในคอลัมน์แบบรายการซึ่งประกอบด้วย data frame โดยแต่ละกลุ่มมีหนึ่งแถว และแต่ละแถวมี data frame ขนาดย่อมของกลุ่มนั้น
library(tidyr)
library(dplyr)
df <- data.frame(
region = c('East','East','East','West','West'),
month = c(1,2,3,1,2),
sales = c(100,120,110,200,190)
)
nested <- df %>%
nest(data = c(month, sales))
print(nested)
print(nested$data[[1]]) # East region's datanest() กับ group_by()
รูปแบบที่ใช้บ่อยที่สุดคือ ใช้ group_by() แล้วตามด้วย nest() เพื่อสร้างหนึ่งแถวต่อหนึ่งกลุ่ม โดยบรรจุคอลัมน์ที่เหลือทั้งหมดไว้ในคอลัมน์แบบรายการ data ซึ่งเทียบเท่ากับ nest(.by = group_col) ใน tidyr รุ่นใหม่กว่า
library(tidyr)
library(dplyr)
df <- data.frame(
category = c('A','A','A','B','B','C','C','C','C'),
x = c(1,2,3,4,5,6,7,8,9),
y = c(2,4,3,8,7,5,6,9,8)
)
nested <- df %>%
group_by(category) %>%
nest()
print(nested)
cat('Rows per category B:', nrow(nested$data[[2]]))map() กับ data frame แบบซ้อนกัน
เมื่อซ้อนข้อมูลแล้ว ให้ใช้ purrr::map() เพื่อใช้ฟังก์ชันกับ data frame ขนาดย่อมแต่ละรายการ ฟังก์ชันจะได้รับ data frame ครั้งละหนึ่งรายการ และผลลัพธ์จะกลายเป็นคอลัมน์แบบรายการใหม่ ซึ่งมักเป็นโมเดลที่ปรับให้เข้ากับข้อมูลแล้ว
library(tidyr)
library(dplyr)
library(purrr)
df <- data.frame(
group = c('A','A','A','B','B','B'),
x = c(1,2,3,1,2,3),
y = c(2.1,4.0,5.9,3.2,5.8,9.1)
)
models <- df %>%
group_by(group) %>%
nest() %>%
mutate(model = map(data, ~lm(y ~ x, data = .x)))
print(models)การดึงผลลัพธ์ของโมเดลด้วย map()
หลังจากปรับโมเดลแยกตามกลุ่มแล้ว ให้ใช้ map() ร่วมกับฟังก์ชันอย่าง broom::tidy() หรือ coef() เพื่อดึงผลลัพธ์จากแต่ละโมเดล ผลลัพธ์จะเป็นคอลัมน์แบบรายการอีกคอลัมน์หนึ่ง ซึ่งภายหลังสามารถคลายการซ้อนได้
library(tidyr)
library(dplyr)
library(purrr)
df <- data.frame(
group = c('A','A','A','B','B','B'),
x = c(1,2,3,1,2,3),
y = c(2.1,4.0,5.9,3.2,5.8,9.1)
)
df %>%
group_by(group) %>%
nest() %>%
mutate(
model = map(data, ~lm(y ~ x, data = .x)),
r_squared = map_dbl(model, ~summary(.x)$r.squared),
intercept = map_dbl(model, ~coef(.x)[1]),
slope = map_dbl(model, ~coef(.x)[2])
) %>%
select(group, r_squared, intercept, slope)unnest() — ขยายคอลัมน์แบบรายการ
unnest(df, cols = data) เป็นการทำงานย้อนกลับของ nest() โดยขยายคอลัมน์แบบรายการกลับเป็นคอลัมน์ปกติ และทำซ้ำคอลัมน์ตัวระบุตามความจำเป็น ใช้ cols เพื่อระบุคอลัมน์แบบรายการที่ต้องการคลายการซ้อน
library(tidyr)
library(dplyr)
nested <- data.frame(
region = c('East','West')
)
nested$data <- list(
data.frame(month=1:3, sales=c(100,120,110)),
data.frame(month=1:2, sales=c(200,190))
)
unnested <- unnest(nested, cols = data)
print(unnested)unnest_longer() — ขยายรายการเป็นแถว
unnest_longer(df, col) ขยายคอลัมน์แบบรายการ โดยให้สมาชิกแต่ละรายการกลายเป็นหนึ่งแถว แตกต่างจาก unnest() ที่คาดว่าจะได้รับ data frame ตรงที่ unnest_longer() ใช้ได้กับรายการเวกเตอร์หรือค่ามาตราส่วน
library(tidyr)
df <- data.frame(
person = c('Alice','Bob','Carol')
)
df$skills <- list(
c('R','Python','SQL'),
c('Excel','Tableau'),
c('R','Julia','Stan','BUGS')
)
unnest_longer(df, skills)unnest_wider() — ขยายรายการเป็นคอลัมน์
unnest_wider(df, col) ขยายสมาชิกแต่ละรายการเป็นชุดคอลัมน์ใหม่ รายการนั้นต้องมีสมาชิกที่มีชื่อกำกับ โดยชื่อเหล่านั้นจะกลายเป็นชื่อคอลัมน์ เหมาะสำหรับโครงสร้างข้อมูลลักษณะ JSON ที่ซ้อนกัน
library(tidyr)
df <- data.frame(id = 1:3)
df$info <- list(
list(name='Alice', age=30, city='NYC'),
list(name='Bob', age=25, city='LA'),
list(name='Carol', age=35, city='Chicago')
)
unnest_wider(df, info)รูปแบบกระบวนการทำงานกับข้อมูลซ้อนกันแบบครบถ้วน
กระบวนการทำงานกับ data frame แบบซ้อนกันอย่างครบถ้วนคือ group_by() + nest() → ใช้ฟังก์ชันด้วย map() → ดึงผลลัพธ์ → ใช้ unnest() เพื่อกลับเป็น data frame แบบแบน รูปแบบนี้ช่วยให้ดำเนินการวิเคราะห์ใด ๆ แยกตามกลุ่มได้
library(tidyr)
library(dplyr)
library(purrr)
df <- data.frame(
region = c('East','East','East','West','West','West'),
month = c(1,2,3,1,2,3),
revenue = c(100,120,115,200,195,210)
)
df %>%
group_by(region) %>%
nest() %>%
mutate(
mean_rev = map_dbl(data, ~mean(.x$revenue)),
trend = map_dbl(data, ~coef(lm(revenue~month, data=.x))[2])
) %>%
select(region, mean_rev, trend)การซ้อนหลายคอลัมน์
คุณสามารถเลือกได้ว่าจะให้คอลัมน์ใดเข้าไปอยู่ใน data frame แบบซ้อนกัน ระบุคอลัมน์เหล่านั้นอย่างชัดเจนใน nest(data = c(...)) คอลัมน์ที่ไม่ได้ระบุจะยังคงเป็นคอลัมน์ปกติใน data frame ชั้นนอก และอยู่ร่วมกับคอลัมน์แบบรายการ
library(tidyr)
library(dplyr)
df <- data.frame(
region = c('East','East','West','West'),
year = c(2023,2024,2023,2024),
q1 = c(100,110,200,210),
q2 = c(105,115,195,215),
target = c(105,112,198,212)
)
# Only nest quarterly data, keep target as outer column
nested <- df %>%
group_by(region, year) %>%
nest(quarters = c(q1, q2))
print(nested)เมื่อใดควรใช้ data frame แบบซ้อนกัน
data frame แบบซ้อนกันเหมาะอย่างยิ่งเมื่อคุณต้องการปรับโมเดลเดียวกันกับหลายกลุ่ม จำลองข้อมูลแยกตามกลุ่ม ใช้การแปลงที่ซับซ้อนกับชุดย่อย หรือทำงานกับข้อมูลลำดับชั้นลักษณะ JSON โดยจะช่วยจัดระเบียบข้อมูลเฉพาะกลุ่มไว้ร่วมกับข้อมูลเมทาดาทาระดับกลุ่ม
library(tidyr)
library(dplyr)
library(purrr)
# Bootstrap confidence interval per group
df <- data.frame(
group = c('A','A','A','A','B','B','B','B'),
value = c(10,12,11,13,20,22,19,21)
)
set.seed(42)
df %>%
group_by(group) %>%
nest() %>%
mutate(
boot_means = map(data, function(d) {
replicate(100, mean(sample(d$value, replace=TRUE)))
}),
ci_low = map_dbl(boot_means, ~quantile(.x, 0.025)),
ci_high = map_dbl(boot_means, ~quantile(.x, 0.975))
) %>%
select(group, ci_low, ci_high)ตรวจสอบความเข้าใจ
วิธีที่ถูกต้องในการขยายคอลัมน์แบบรายการของ data frame ให้กลับเป็น data frame แบบแบนคืออะไร
สรุป: การซ้อนและการคลายการซ้อน
ประเด็นสำคัญสำหรับกระบวนการทำงานกับ data frame แบบซ้อนกัน:
nest(data = c(cols))— บรรจุคอลัมน์ลงในคอลัมน์แบบรายการของ data frame โดยมีหนึ่งรายการต่อกลุ่มgroup_by() + nest()— รูปแบบมาตรฐานสำหรับซ้อนข้อมูลตามกลุ่มmap(nested$data, fn)— ใช้ฟังก์ชันใด ๆ กับ data frame แบบซ้อนกันแต่ละรายการunnest(cols = data)— ขยายคอลัมน์แบบรายการของ data frame กลับเป็นรูปแบบแบนunnest_longer(col)— ขยายรายการเวกเตอร์หรือค่ามาตราส่วนเป็นแถวunnest_wider(col)— ขยายรายการที่มีชื่อกำกับเป็นคอลัมน์- เหมาะสำหรับการสร้างโมเดลแยกตามกลุ่ม การสุ่มตัวอย่างซ้ำ และการประมวลผลข้อมูล JSON
library(tidyr)
library(dplyr)
library(purrr)
data.frame(
team = c('A','A','B','B'),
x = c(1,2,1,2),
y = c(2,4,3,6)
) %>%
group_by(team) %>%
nest() %>%
mutate(
model = map(data, ~lm(y ~ x, data = .x)),
slope = map_dbl(model, ~coef(.x)['x'])
) %>%
select(team, slope)คำถามที่พบบ่อย
บทเรียน “การซ้อนและคลายการซ้อนดาต้าเฟรม” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “การซ้อนและคลายการซ้อนดาต้าเฟรม” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส R Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส R Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “การซ้อนและคลายการซ้อนดาต้าเฟรม”
ใช้ nest() และ unnest() เพื่อทำงานกับคอลัมน์รายการในกระบวนงาน tidy คุณปฏิบัติ R Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน R Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน R Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน
บทเรียน “การซ้อนและคลายการซ้อนดาต้าเฟรม” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน R Academy นี้ได้ไหม
ได้ บทเรียน R Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- จากแบบกว้างเป็นแบบยาวด้วย pivot_longer()
- จากแบบยาวเป็นแบบกว้างด้วย pivot_wider()
- separate() และ unite() สำหรับคอลัมน์สตริง
- การซ้อนและคลายการซ้อนดาต้าเฟรม