Bagaimana cara menggabungkan beberapa kondisi untuk mengelompokkan frame data menggunakan “OR”?

174

Saya memiliki data.frame di R. Saya ingin mencoba dua kondisi berbeda pada dua kolom berbeda, tapi saya ingin kondisi ini inklusif. Oleh karena itu, saya ingin menggunakan "ATAU" untuk menggabungkan kondisi. Saya telah menggunakan sintaks berikut sebelumnya dengan banyak keberhasilan ketika saya ingin menggunakan kondisi "DAN".

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

Tapi saya tidak tahu cara menggunakan 'ATAU' di atas.

Sam
sumber

Jawaban:

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

Solusi alternatif yang meniru perilaku fungsi ini dan akan lebih tepat untuk dimasukkan dalam badan fungsi:

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

Beberapa orang mengkritik penggunaan yang whichtidak diperlukan, tetapi hal itu mencegah NAnilai - nilai dari melemparkan kembali hasil yang tidak diinginkan. Persamaan (.yaitu tidak mengembalikan baris-NA untuk NA apa pun di V1 atau V2) ke dua opsi yang ditunjukkan di atas tanpa whichakan:

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

Catatan: Saya ingin berterima kasih kepada kontributor anonim yang berusaha memperbaiki kesalahan dalam kode di atas, perbaikan yang ditolak oleh moderator. Sebenarnya ada kesalahan tambahan yang saya perhatikan ketika saya memperbaiki yang pertama. Klausa bersyarat yang memeriksa nilai-nilai NA perlu menjadi yang pertama jika ingin ditangani seperti yang saya maksudkan, karena ...

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

Urutan argumen mungkin penting saat menggunakan '& ".

IRTFM
sumber
1
Ini adalah pertanyaan pilihan tertinggi dan kemudian orang menemukan: stackoverflow.com/questions/9860090/…
PatrickT
1
Keuntungannya adalah kekompakan dan mudah dipahami. Kerugiannya adalah kurangnya utilitas dalam tugas membangun fungsi. Jika seseorang ingin meniru ini dengan [satu kebutuhan untuk membungkus whichatau menggunakan !is.nakendala tambahan .
IRTFM
Apakah 'yang' diperlukan dan jika tidak mengapa Anda menggunakannya?
Cleb
1
Ini tidak "wajib", tetapi Anda mungkin mendapatkan hasil yang berbeda jika Anda meninggalkan which. Jika kedua V1 dan V2 adalah NA Anda akan mendapatkan deretan NA di posisi itu jika Anda meninggalkan which. Saya bekerja dengan dataset besar dan bahkan persentase yang relatif kecil dari NA akan benar-benar mengisi layar saya dengan output sampah. Beberapa orang berpikir ini adalah fitur. Bukan saya.
IRTFM
bagaimana Anda memasukkan panggilan ke greplatau grepdengan ini untuk juga melakukan pencocokan pola untuk baris yang diinginkan, selain persyaratan ini?
user5359531
31

Anda mencari "|." Lihat http://cran.r-project.org/doc/manuals/R-intro.html#Logical-vectors

my.data.frame <- data[(data$V1 > 2) | (data$V2 < 4), ]
ncray
sumber
Ini TIDAK kuat untuk keberadaan NAs dalam kerangka data: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

Hanya demi kelengkapan, kita dapat menggunakan operator [dan [[:

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

Beberapa opsi

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 setara dengan df [["name", exact = FALSE]]

Menggunakan dplyr:

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

Menggunakan sqldf:

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

Output untuk opsi di atas:

          v1 v2
1 0.26550866  a
2 0.37212390  b
3 0.20168193  e
4 0.94467527  g
5 0.06178627  j
mpalanco
sumber
1
bagaimana Anda melakukan ini untuk 1 DAN kondisi dan 3 ATAU kondisi kontingen jadi misalnya: my.data.frame <- data [data $ V3> 10 & ((data $ V1> 2) | (data $ V2 <4) | (data $ V4 <5),]. Ketika saya melakukan ini tidak berfungsi
R Guru
1
Wow! The sqldfpaket terlalu baik. Sangat berguna terutama ketika subset()mendapat sedikit menyakitkan :)
Dawny33