การสร้างและเลือกองค์ประกอบในรายการด้วยภาษา R
⚡ สรุปอย่างชาญฉลาด
R List คืออ็อบเจ็กต์ที่ใช้เก็บเวกเตอร์ เมทริกซ์ ดาต้าเฟรม และแม้แต่ลิสต์อื่นๆ ไว้ในคอนเทนเนอร์เดียว ฟังก์ชัน list() ใช้สำหรับสร้าง List และวงเล็บเหลี่ยมคู่ใช้สำหรับดึงองค์ประกอบใดๆ ออกมา

R List คืออะไร?
รายชื่ออาร์ เป็นอ็อบเจ็กต์ในการเขียนโปรแกรม R ซึ่งรวมถึงเมทริกซ์ เวกเตอร์ กรอบข้อมูล หรือรายการภายในนั้น R List ยังใช้เพื่อจัดเก็บคอลเลกชันของวัตถุและใช้เมื่อเราต้องการ เรานึกภาพ R list ว่าเป็นกระเป๋าสำหรับใส่สิ่งของต่างๆ มากมาย เมื่อเราจำเป็นต้องใช้สิ่งของ เราก็สามารถเปิดถุงออกมาใช้งานได้
ความแตกต่างกับเวกเตอร์นี่เองที่ทำให้ลิสต์มีประโยชน์ เวกเตอร์บังคับให้ทุกองค์ประกอบเป็นประเภทเดียว ดังนั้นการวางคำไว้ข้างตัวเลขจะเปลี่ยนตัวเลขนั้นให้กลายเป็นข้อความ แต่ลิสต์ไม่มีกฎเกณฑ์เช่นนั้น นั่นเป็นเหตุผลที่ลิสต์สามารถบรรจุเวกเตอร์ที่มีห้าองค์ประกอบหรือสองแถวได้ เมทริกซ์ และแสดงข้อมูลแบบ data frame ขนาด 714 แถวเคียงข้างกันโดยไม่เปลี่ยนแปลงข้อมูลใดๆ
ไวยากรณ์ของรายการใน R
เราสามารถใช้ฟังก์ชัน list() เพื่อสร้างลิสต์ในภาษา R ได้:
list(element_1, ...) arguments: -element_1: store any type of R object -...: pass as many objects as specifying. each object needs to be separated by a comma
แต่ละข้อโต้แย้งอาจถูกส่งมาโดยตรงหรือในรูปแบบอื่นก็ได้ แท็ก = ค่าอาร์กิวเมนต์แบบไม่มีชื่อจะกลายเป็นองค์ประกอบเชิงตำแหน่งที่เข้าถึงได้เฉพาะโดยหมายเลขของมัน ในขณะที่อาร์กิวเมนต์ที่มีแท็กจะได้รับชื่อด้วย เอกสารอ้างอิงพื้นฐานของ R สำหรับ รายการ() เอกสารระบุทั้งรูปแบบและหมายเหตุว่า unlist() ทำหน้าที่เป็นตัวผกผันโดยประมาณของ as.list()
วิธีสร้างรายการใน R
ด้านล่างนี้เป็นกระบวนการทีละขั้นตอนเกี่ยวกับวิธีสร้างรายการใน R:
ในตัวอย่างด้านล่าง เราจะสร้างวัตถุที่แตกต่างกันสามชิ้น ได้แก่ เวกเตอร์ เมทริกซ์ และ a กรอบข้อมูล การใช้ฟังก์ชันรายการใน R
ขั้นตอนที่ 1) สร้างเวกเตอร์
ใช้โค้ดด้านล่างเพื่อสร้างเวกเตอร์ใน R
# Vector with numeric from 1 up to 5
vect <- 1:5
ตัวดำเนินการโคลอนจะสร้างลำดับ 1, 2, 3, 4, 5 เป็นเวกเตอร์จำนวนเต็ม และลูกศรกำหนดค่าจะเก็บเวกเตอร์นั้นไว้ภายใต้ชื่อ vect
ขั้นตอนที่ 2) สร้างเมทริกซ์
ต่อไปนี้คือการสร้างเมทริกซ์โดยใช้โค้ดต่อไปนี้
# A 2x 5 matrix
mat <- matrix(1:9, ncol = 5)
dim(mat)
มีรายละเอียดสองอย่างที่ควรให้ความสนใจ ตารางที่มีสองแถวและห้าคอลัมน์ต้องการค่าสิบค่า แต่มีการป้อนค่ามาเพียงเก้าค่า ดังนั้น R จึงนำค่าเหล่านั้นกลับมาใช้ใหม่และแสดงคำเตือนว่าความยาวของข้อมูลไม่ใช่ผลหารย่อยของจำนวนแถว ค่าที่นำกลับมาใช้ใหม่นี้เองที่ทำให้แถวที่สองของเมทริกซ์ที่พิมพ์ออกมาลงท้ายด้วย 1 แทนที่จะเป็น 10 จากนั้นการเรียกใช้ฟังก์ชัน dim() จะแสดงรูปร่างของเมทริกซ์
Output:
## [1] 2 5
ขั้นตอนที่ 3) สร้างกรอบข้อมูล
สร้าง data frame ใน R โดยใช้โค้ดด้านล่าง
# select the 10th row of the built-in R data set EuStockMarkets
df <- EuStockMarkets[1:10,]
ข้อความแสดงความคิดเห็นกล่าวถึงแถวที่สิบ แต่สูตรจะเก็บเฉพาะแถวที่ 1 ถึง 10 ของอนุกรม EuStockMarkets ที่มีอยู่แล้ว การเลือกข้อมูลย่อยยังตัดคลาสอนุกรมเวลาออกไปด้วย ดังนั้นสิ่งที่ได้กลับมาจึงเป็นเมทริกซ์ตัวเลขแทนที่จะเป็นเฟรมข้อมูลจริง ซึ่งเป็นเหตุผลว่าทำไมผลลัพธ์ที่พิมพ์ด้านล่างจึงมีป้ายกำกับแถวแบบ [1,] แทนที่จะเป็นชื่อแถว ควรใช้ as.data.frame() ครอบการเรียกใช้ทุกครั้งเมื่อต้องการเฟรมข้อมูลจริง
ขั้นตอนที่ 4) สร้างรายการใน R
ตอนนี้เราสามารถใส่วัตถุทั้งสามรายการลงในรายการ R โดยใช้โค้ดด้านล่าง
# Construct list with these vec, mat, and df:
my_list <- list(vect, mat, df)
my_list
Output:
## [[1]] ## [1] 1 2 3 4 5 ## [[2]] ## [,1] [,2] [,3] [,4] [,5] ## [1,] 1 3 5 7 9 ## [2,] 2 4 6 8 1 ## [[3]] ## DAX SMI CAC FTSE ## [1,] 1628.75 1678.1 1772.8 2443.6 ## [2,] 1613.63 1688.5 1750.5 2460.2 ## [3,] 1606.51 1678.6 1718.0 2448.2 ## [4,] 1621.04 1684.1 1708.1 2470.4 ## [5,] 1618.16 1686.6 1723.1 2484.7 ## [6,] 1610.61 1671.6 1714.3 2466.8 ## [7,] 1630.75 1682.9 1734.5 2487.9 ## [8,] 1640.17 1703.6 1757.4 2508.4 ## [9,] 1635.47 1697.5 1754.0 2510.5 ## [10,] 1645.89 1716.3 1754.3 2497.4
ส่วนหัววงเล็บสองชั้นสามส่วนในผลลัพธ์นั้นคือตำแหน่งในรายการ ไม่มีอะไรถูกแปลงหรือบังคับ: องค์ประกอบที่หนึ่งยังคงเป็นเวกเตอร์จำนวนเต็ม องค์ประกอบที่สองยังคงเป็นเมทริกซ์ และองค์ประกอบที่สามยังคงเก็บราคาหุ้นทั้งสิบแถวไว้
เลือกองค์ประกอบจากรายการ R
หลังจากที่เราสร้างลิสต์เสร็จแล้ว เราก็สามารถเข้าถึงลิสต์นั้นได้ค่อนข้างง่าย เราต้องใช้ [[index]] เพื่อเลือกองค์ประกอบในลิสต์ ค่าภายในวงเล็บเหลี่ยมสองชั้นแสดงถึงตำแหน่งของรายการในลิสต์ที่เราต้องการเลือกtracตัวอย่างเช่น หากเราใส่เลข 2 เข้าไปในวงเล็บ R จะคืนค่าองค์ประกอบที่สองที่ระบุไว้
ตอนนี้อยู่ในนี้ กวดวิชา Rลองเลือกรายการที่สองของรายการใน R ชื่อ my_list เราใช้ my_list[[2]]
# Print second element of the list
my_list[[2]]
Output:
## [,1] [,2] [,3] [,4] [,5] ## [1,] 1 3 5 7 9 ## [2,] 2 4 6 8 1
วงเล็บเดี่ยวและวงเล็บคู่ไม่สามารถใช้แทนกันได้ และการสับสนระหว่างสองอย่างนี้เป็นสาเหตุที่พบบ่อยที่สุดของข้อผิดพลาดในรายการ วงเล็บเดี่ยวจะคงกรอบไว้ ส่วนวงเล็บคู่จะลบกรอบออก
| การแสดงออก | อะไรกลับมา | คลาสของผลลัพธ์ | ใช้เมื่อ |
|---|---|---|---|
| รายการของฉัน[[2]] | องค์ประกอบที่จัดเก็บไว้เอง | ไม่ว่าอะไรจะถูกจัดเก็บไว้ ที่นี่คือเมทริกซ์ | คุณต้องคำนวณบนองค์ประกอบหนึ่งตัว |
| รายการของฉัน[2] | รายการย่อยที่ประกอบด้วยองค์ประกอบนั้นหนึ่งรายการ | รายการ | คุณต้องเก็บตัวห่อรายการไว้ |
| my_list[c(1, 3)] | รายการย่อยขององค์ประกอบที่เลือก | รายการ | คุณต้องการองค์ประกอบหลายอย่างพร้อมกัน |
| มายลิสต์[-2] | ทุกองค์ประกอบยกเว้นองค์ประกอบที่สอง | รายการ | คุณต้องลบองค์ประกอบหนึ่งออก |
# Compare the two bracket styles class(my_list[[2]]) # the matrix itself class(my_list[2]) # a list of length one # Several elements, and everything but one element my_list[c(1, 3)] my_list[-2]
รายการที่มีชื่อใน R
ดัชนีตามตำแหน่งนั้นเปราะบาง: เมื่อแทรกองค์ประกอบหนึ่งเข้าไป ตัวเลขทุกตัวที่อยู่ถัดจากนั้นจะเลื่อนไป การตั้งชื่อให้กับองค์ประกอบจะช่วยขจัดความเสี่ยงนั้นและทำให้โค้ดอ่านง่ายเหมือนกับข้อมูลที่มันอธิบาย ชื่อสามารถระบุได้เมื่อสร้างรายการ หรือแนบภายหลังด้วยเมธอด names()
# Tag each element at creation time named_list <- list(numbers = vect, grid = mat, prices = df) # Three ways to reach the same element named_list$grid named_list[["grid"]] named_list["grid"] # returns a one-element list # Read or replace the names later names(named_list) names(named_list)[2] <- "grid_2x5"
ตัวดำเนินการ $ และวงเล็บเหลี่ยมคู่มีความแตกต่างกันในประเด็นหนึ่งที่อาจทำให้ผู้เริ่มต้นสับสน ตัวดำเนินการ $ ทำการจับคู่แบบบางส่วน ดังนั้น named_list$pri ยังคงค้นหาราคาได้ ในขณะที่ named_list[[“pri”]] จะคืนค่า NULL เนื่องจากวงเล็บเหลี่ยมคู่จะจับคู่แบบตรงกันทุกประการ เว้นแต่จะส่งค่า exact = FALSE การจับคู่แบบบางส่วนสะดวกในการใช้งานในคอนโซล แต่ไม่ปลอดภัยในสคริปต์ ดังนั้นควรเลือกใช้รูปแบบการจับคู่แบบตรงกันทุกประการในโค้ดที่บันทึกไว้
# A compact map of the whole structure
str(named_list)
ฟังก์ชัน str() จะพิมพ์ข้อมูลหนึ่งบรรทัดต่อองค์ประกอบ โดยระบุประเภทและขนาด ซึ่งเป็นวิธีที่เร็วที่สุดในการตรวจสอบว่ารายการนั้นมีสิ่งที่คุณคาดหวังก่อนที่จะเข้าถึงข้อมูลในรายการนั้น
แก้ไข เพิ่ม และลบองค์ประกอบในรายการ R
รายการจะไม่คงที่เมื่อสร้างขึ้นแล้ว ตัวเข้าถึงเดียวกันที่อ่านองค์ประกอบก็จะเขียนลงในองค์ประกอบนั้นด้วย ดังนั้นการอัปเดต การขยาย และการลดขนาดรายการจึงใช้การกำหนดค่าแบบปกติทั้งหมด
# Replace an element in place named_list[["numbers"]] <- 1:10 # Add a new element simply by naming it named_list[["created"]] <- Sys.Date() # Append without a name: the element lands at the end named_list <- append(named_list, list(TRUE)) # Delete an element by assigning NULL to it named_list[["created"]] <- NULL
- แทนที่: การกำหนดค่าให้กับชื่อที่มีอยู่แล้วจะเขียนทับองค์ประกอบนั้น แต่ตำแหน่งขององค์ประกอบนั้นจะไม่เปลี่ยนแปลง
- Add: การกำหนดค่าให้กับชื่อที่ไม่มีอยู่จริง จะเป็นการเพิ่มองค์ประกอบใหม่เข้าไปที่ท้ายรายการ
- ผนวก: ฟังก์ชัน `append()` รับลิสต์เป็นอาร์กิวเมนต์ตัวที่สอง ดังนั้นจึงต้องห่อค่าเปล่าๆ ด้วยฟังก์ชัน `list()` ก่อนที่จะส่งเข้าไป
- ลบ: การกำหนดค่า NULL ด้วยวงเล็บสองชั้นจะลบองค์ประกอบนั้นออกและทำให้รายการสั้นลง
ผลที่ตามมาอย่างหนึ่งที่มักทำให้คนสับสนคือ เนื่องจาก NULL หมายถึงการลบ คุณจึงไม่สามารถเก็บค่า NULL จริงๆ ด้วยวงเล็บสองชั้นได้ ให้ใช้การกำหนดค่าด้วยวงเล็บชั้นเดียวแทน เช่น named_list[“empty”] <- list(NULL) ซึ่งจะคงช่องไว้และใส่ค่า NULL เข้าไปข้างใน
รายการซ้อนและการใช้ unlist() ใน R
เนื่องจากลิสต์สามารถเก็บอ็อบเจ็กต์ใดๆ ก็ได้ในภาษา R ดังนั้นจึงสามารถเก็บลิสต์อื่นไว้ภายในได้ การซ้อนกันเป็นวิธีการแสดงอ็อบเจ็กต์การกำหนดค่า การตอบสนอง JSON และผลลัพธ์ของโมเดลในภาษา R ดังนั้นการเข้าถึงลิสต์ที่ซ้อนกันและการทำให้ลิสต์แบนราบจึงเป็นงานประจำวัน
# A list whose elements are themselves lists project <- list( meta = list(owner = "analyst", year = 2026), data = list(vect, mat) ) # Chain the accessors to reach an inner value project$meta$year project[["data"]][[2]] # Flatten every level into one atomic vector flat <- unlist(project) # Strip a single level and keep the rest as a list half <- unlist(project, recursive = FALSE)
การทำให้แบนราบนั้นมีต้นทุนที่ควรทำความเข้าใจ ฟังก์ชัน unlist() ต้องส่งคืนเวกเตอร์อะตอมิกหนึ่งตัว ดังนั้นจึงแปลงค่าทุกค่าให้เป็นประเภททั่วไปที่สุดที่มีอยู่ โดยเรียงลำดับตามตรรกะ จำนวนเต็ม ทศนิยม และอักขระ ดังนั้นลิสต์ซ้อนกันที่ผสมตัวเลขกับข้อความจึงได้ผลลัพธ์เป็นข้อความทั้งหมด ชื่อของผลลัพธ์ถูกสร้างขึ้นโดยการรวมแท็กภายนอกและภายในเข้าด้วยกัน ซึ่งเป็นเหตุผลว่าทำไมองค์ประกอบจึงปรากฏในรูปแบบ meta.owner แทนที่จะเป็น owner
ส่งค่า use.names = FALSE เมื่อไม่ต้องการชื่อผสมเหล่านั้น และตั้งค่า recursive = FALSE เมื่อต้องการลบเฉพาะเลเยอร์นอกสุดเท่านั้น หากค่าต่างๆ ต้องคงประเภทเดิมไว้ ให้คงโครงสร้างไว้เหมือนเดิมและดำเนินการผ่านรายการแทนที่จะทำให้แบนราบ
Data Frame ในตัวใน R
รายการข้อมูลมักถูกเติมด้วยข้อมูลที่อ่านจากดิสก์หรือจากเว็บ ดังนั้นการดูว่าเฟรมข้อมูลมาถึงได้อย่างไรก่อนที่จะถูกจัดเก็บลงในเฟรมข้อมูลจึงเป็นประโยชน์ ก่อนที่จะสร้างเฟรมข้อมูลของเราเอง เราสามารถดูชุดข้อมูล R ที่มีอยู่ทางออนไลน์ได้ ชุดข้อมูลเรือนจำมีมิติ 714×5 เราสามารถดูส่วนล่างของเฟรมข้อมูลได้อย่างรวดเร็วด้วยฟังก์ชัน tail() ในทำนองเดียวกัน ฟังก์ชัน head() จะแสดงส่วนบนของเฟรมข้อมูล คุณสามารถระบุจำนวนแถวที่แสดงด้วย head(df, 5) เราจะเรียนรู้เพิ่มเติมเกี่ยวกับฟังก์ชัน read.csv() ในหัวข้อต่อไป นำเข้าข้อมูลใน R เกี่ยวกับการสอน
PATH <-'https://raw.githubusercontent.com/guru99-edu/R-Programming/master/prison.csv'
df <- read.csv(PATH)[1:5]
head(df, 5)
Output:
## X state year govelec black ## 1 1 1 80 0 0.2560 ## 2 2 1 81 0 0.2557 ## 3 3 1 82 1 0.2554 ## 4 4 1 83 0 0.2551 ## 5 5 1 84 0 0.2548
[1:5] ที่ตามหลัง read.csv() จะเลือกคอลัมน์ห้าคอลัมน์แรก ไม่ใช่แถวห้าแถวแรก เพราะเฟรมข้อมูลนั้นเป็นรายการของคอลัมน์ การใช้ดัชนีวงเล็บเดี่ยวในรายการจะส่งคืนรายการที่เล็กลง และในที่นี้ รายการที่เล็กลงนั้นก็ยังคงเป็นเฟรมข้อมูลอยู่
เราสามารถตรวจสอบโครงสร้างของ data frame ด้วย str:
# Structure of the data
str(df)
Output:
## 'data.frame': 714 obs. of 5 variables: ## $ X : int 1 2 3 4 5 6 7 8 9 10 ... ## $ state : int 1 1 1 1 1 1 1 1 1 1 ... ## $ year : int 80 81 82 83 84 85 86 87 88 89 ... ## $ govelec: int 0 0 1 0 0 0 1 0 0 0 ... ## $ black : num 0.256 0.256 0.255 0.255 0.255 ...
ตัวแปรทั้งหมดจะถูกเก็บไว้ใน เชิงตัวเลข รูปแบบดังกล่าว เครื่องหมาย $ นำหน้าแต่ละบรรทัดเป็นตัวดำเนินการเดียวกันกับที่ใช้กับลิสต์ที่มีชื่อก่อนหน้านี้ ซึ่งยืนยันว่าดาต้าเฟรมเป็นลิสต์ของคอลัมน์ที่มีความยาวเท่ากันและมีป้ายกำกับเป็นรูปสี่เหลี่ยมผืนผ้า ดังนั้นทุกสิ่งที่เรียนรู้เกี่ยวกับการตั้งชื่อ การเลือก และการลบองค์ประกอบในลิสต์จึงสามารถนำไปใช้กับดาต้าเฟรมได้โดยตรง ประเภทข้อมูล R และไปยังคอลัมน์ของดาต้าเฟรม
