เลือกองค์ประกอบแรกของรายการที่ซ้อนกัน


88

สมมติว่าฉันมีรายชื่อดังนี้:

x = list(list(1,2), list(3,4), list(5,6))

ฉันต้องการรายการที่มีเฉพาะองค์ประกอบแรกของรายการที่ซ้อนกัน ฉันสามารถทำได้โดยส่งคืนรายการอื่นเช่นนั้น

x1 = lapply(x, function(l) l[[1]])

มีสัญกรณ์ทางลัดสำหรับสิ่งนี้หรือไม่?

คำตอบ:


144

ทางลัดไม่มากนัก แต่คุณสามารถทำได้:

lapply(x, `[[`, 1)
# [[1]]
# [1] 1
#
# [[2]]
# [1] 3
#
# [[3]]
# [1] 5

1
ฉันยอมรับว่ามันดูเท่กว่า ฉันหวังว่าจะมีวิธีที่สั้นกว่านี้ แต่ฉันจะหาวิธีที่เจ๋งกว่านี้!
Alex

@ A5C1D2H2I1M1N2O1R2T1 ฉันขอขอบคุณในความสะอาดและความสั้น แต่คุณช่วยอธิบาย "[[" ได้ไหม ฉันไม่พบสิ่งที่เป็นประโยชน์ใน? lapply
Mehrad Mahmoudian

2
@MehradMahmoudian สถานที่ที่ดีกว่าในการดูคือ "extract" ( stat.ethz.ch/R-manual/R-devel/library/base/html/Extract.html )
A5C1D2H2I1M1N2O1R2T1

44

ความเป็นไปได้อื่นใช้purrrไลบรารีที่ดี:

library(purrr)
map(x, 1)

5
สำหรับผู้ที่สงสัยสิ่งนี้ใช้ได้ตั้งแต่mapการตีความค่าตัวเลขว่าเป็นการดึงข้อมูลเช่น[[
qwr

12

สำหรับรายการตัวอย่างของคุณคุณสามารถทำได้:

unlist(x)[ c(TRUE,FALSE) ]

แต่ขึ้นอยู่กับแต่ละรายการย่อยที่มี 2 องค์ประกอบ

หากมีจำนวนองค์ประกอบที่แตกต่างกันก่อนอื่นคุณสามารถsapplyคำนวณความยาวจากนั้นคำนวณตำแหน่งองค์ประกอบที่ 1 ที่เกี่ยวข้อง (ดูcumsum) จากนั้นเลือกค่าเหล่านั้นจากunlistรายการ ed แต่เมื่อถึงเวลานั้นคำตอบที่ได้รับการยอมรับอาจจะง่ายกว่ามาก

หากรายการย่อยทั้งหมดมีความยาวเท่ากัน (แต่อาจแตกต่างจาก 2) คุณสามารถทำสิ่งต่อไปนี้

do.call( rbind, x)[,1]

หรือโยนอื่น ๆ ไปยังวัตถุทั่วไป แต่ฉันสงสัยว่าวิธีนี้จะมีประสิทธิภาพพอ ๆ กับlapplyแนวทางนี้


3

เราสามารถใช้pluckจากrvestที่เลือกองค์ประกอบที่ 1 จากแต่ละรายการที่ซ้อนกัน

rvest::pluck(x, 1)
#[[1]]
#[1] 1

#[[2]]
#[1] 3

#[[3]]
#[1] 5

โปรดทราบว่านี้จะช่วยให้ผลที่แตกต่างกันpluckจากpurrrที่เลือกองค์ประกอบที่ 1 ( x[[1]])

purrr::pluck(x, 1)

#[[1]]
#[1] 1

#[[2]]
#[1] 2

0

ไม่ใช่สัญกรณ์สั้น ๆ แต่สามารถทำได้ด้วยการพับ:

Reduce(function(a, b) c(a, b[1]), x, init = c()) 

# [[1]]
# [1] 1
# 
# [[2]]
# [1] 3
# 
# [[3]]
# [1] 5
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.