วิธีการรวมหลายเงื่อนไขเพื่อเซตย่อย data-frame โดยใช้“ หรือ”?


174

ฉันมี data.frame ใน R ฉันต้องการลองสองเงื่อนไขที่แตกต่างกันในสองคอลัมน์ที่แตกต่างกัน แต่ฉันต้องการให้รวมเงื่อนไขเหล่านี้ ดังนั้นฉันต้องการใช้ "หรือ" เพื่อรวมเงื่อนไข ฉันใช้ไวยากรณ์ต่อไปนี้มาก่อนด้วยความสำเร็จมากมายเมื่อฉันต้องการใช้เงื่อนไข "และ"

my.data.frame <- data[(data$V1 > 2) & (data$V2 < 4), ]

แต่ฉันไม่ทราบวิธีการใช้ 'หรือ' ข้างต้น

คำตอบ:


249
my.data.frame <- subset(data , V1 > 2 | V2 < 4)

ทางเลือกอื่นที่เลียนแบบพฤติกรรมของฟังก์ชั่นนี้และจะเหมาะสมกว่าสำหรับการรวมไว้ในส่วนของฟังก์ชั่น:

new.data <- data[ which( data$V1 > 2 | data$V2 < 4) , ]

บางคนวิพากษ์วิจารณ์การใช้whichที่ไม่จำเป็น แต่ก็ป้องกันไม่ให้NAคุณค่ากลับมาทิ้งผลลัพธ์ที่ไม่พึงประสงค์ ค่าเทียบเท่า (.ie ไม่ส่งคืนแถว NA สำหรับ NA ใด ๆ ใน V1 หรือ V2) ไปยังสองตัวเลือกที่แสดงด้านบนโดยไม่ต้องwhichมี:

 new.data <- data[ !is.na(data$V1 | data$V2) & ( data$V1 > 2 | data$V2 < 4)  , ]

หมายเหตุ: ฉันต้องการขอบคุณผู้มีส่วนร่วมนิรนามที่พยายามแก้ไขข้อผิดพลาดในโค้ดด้านบนทันทีการแก้ไขที่ผู้ดูแลถูกปฏิเสธ มีข้อผิดพลาดเพิ่มเติมที่ฉันสังเกตเห็นเมื่อฉันแก้ไขข้อผิดพลาดแรก ประโยคเงื่อนไขที่ตรวจสอบค่า NA จำเป็นต้องเป็นอันดับแรกหากมีการจัดการตามที่ฉันต้องการเนื่องจาก ...

> NA & 1
[1] NA
> 0 & NA
[1] FALSE

ลำดับของการขัดแย้งอาจมีความสำคัญเมื่อใช้ '& "


1
นี่คือคำถามที่โหวตสูงสุดแล้วหนึ่งคำถามที่ค้นพบ: stackoverflow.com/questions/9860090/…
PatrickT

1
ข้อดีคือความกะทัดรัดและเข้าใจง่าย ข้อเสียคือการขาดประโยชน์ในการสร้างฟังก์ชั่น หากต้องการทำซ้ำสิ่งนี้ด้วย[สิ่งที่ต้องการห่อหุ้มwhichหรือใช้!is.naข้อ จำกัดเพิ่มเติม
IRTFM

เป็น 'ซึ่ง' จำเป็นและถ้าไม่ทำไมคุณใช้หรือไม่
Cleb

1
มันไม่ได้ "ต้อง" whichแต่คุณอาจจะได้รับผลที่แตกต่างกันถ้าคุณปล่อยให้ออก ถ้าทั้ง V1 และ V2 เป็น NA whichคุณจะได้รับแถวของนาที่ตำแหน่งว่าถ้าคุณซ้ายออก ฉันทำงานกับชุดข้อมูลขนาดใหญ่และแม้แต่เปอร์เซ็นต์ที่ค่อนข้างเล็กของ NA จะเติมเต็มหน้าจอของฉันด้วยเอาต์พุตขยะ บางคนคิดว่านี่เป็นคุณสมบัติ ฉันไม่.
IRTFM

คุณจะรวมการเรียกgreplหรือgrepด้วยสิ่งนี้เพื่อจับคู่รูปแบบสำหรับแถวที่ต้องการได้อย่างไรนอกเหนือจากเงื่อนไขเหล่านี้
user5359531

31

คุณกำลังมองหา "|." ดู http://cran.r-project.org/doc/manuals/R-intro.html#Logical-vectors

my.data.frame <- data[(data$V1 > 2) | (data$V2 < 4), ]

สิ่งนี้ไม่แข็งแกร่งต่อการดำรงอยู่ของNAs ใน dataframe:vc <- data.frame(duzey=factor(c("Y","O","Y","D","Y","Y","O"), levels=c("D","O","Y"), ordered=TRUE), cinsiyet=c("E","E","K",NA,"K","E","K"), yas=c(8,3,9,NA,7,NA,6), Not=c(NA,1,1,NA,NA,2,1)); vc; vc[vc$cinsiyet == "E" | vc$Not < 4,]; vc[vc$cinsiyet == "E" & vc$Not < 2,]
Erdogan CEVHER

17

เพื่อความสมบูรณ์เราสามารถใช้โอเปอเรเตอร์[และ[[:

set.seed(1)
df <- data.frame(v1 = runif(10), v2 = letters[1:10])

ตัวเลือกมากมาย

df[df[1] < 0.5 | df[2] == "g", ] 
df[df[[1]] < 0.5 | df[[2]] == "g", ] 
df[df["v1"] < 0.5 | df["v2"] == "g", ]

df $ name เทียบเท่า df [["ชื่อ", แน่นอน = FALSE]]

การใช้dplyr:

library(dplyr)
filter(df, v1 < 0.5 | v2 == "g")

การใช้sqldf:

library(sqldf)
sqldf('SELECT *
      FROM df 
      WHERE v1 < 0.5 OR v2 = "g"')

เอาต์พุตสำหรับตัวเลือกด้านบน:

          v1 v2
1 0.26550866  a
2 0.37212390  b
3 0.20168193  e
4 0.94467527  g
5 0.06178627  j

1
คุณจะทำสิ่งนี้อย่างไรสำหรับ 1 และเงื่อนไขและ 3 หรือเงื่อนไขเช่น: my.data.frame <- data [data $ V3> 10 & (ข้อมูล $ V1> 2) | (data $ V2 <4) | (ข้อมูล $ V4 <5)] เมื่อผมทำเช่นนี้มันไม่ทำงาน.
R คุรุ

1
ว้าว! sqldfแพคเกจดีเกินไป มีประโยชน์มากโดยเฉพาะอย่างยิ่งเมื่อsubset()ได้รับบิตเจ็บปวด :)
Dawny33
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.