Jak połączyć wiele warunków, aby podzielić ramkę danych za pomocą „LUB”?

174

Mam ramkę danych w R. Chcę wypróbować dwa różne warunki w dwóch różnych kolumnach, ale chcę, aby te warunki były włącznie. Dlatego chciałbym użyć „LUB”, aby połączyć warunki. Używałem następującej składni już wcześniej, z dużym powodzeniem, gdy chciałem użyć warunku „AND”.

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

Ale nie wiem, jak użyć „LUB” w powyższym.

Sam
źródło

Odpowiedzi:

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

Alternatywne rozwiązanie, które naśladuje zachowanie tej funkcji i byłoby bardziej odpowiednie do włączenia do treści funkcji:

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

Niektórzy ludzie krytykują użycie whichjako niepotrzebne, ale zapobiega to NAodrzucaniu niepożądanych wyników przez wartości. Odpowiednik (tj. Nie zwracający wierszy NA dla żadnych NA w wersji V1 lub V2) dwóm opcjom przedstawionym powyżej bez opcji whichbyłby:

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

Uwaga: chcę podziękować anonimowemu współautorowi, który próbował naprawić błąd w kodzie powyżej, poprawka, która została odrzucona przez moderatorów. W rzeczywistości pojawił się dodatkowy błąd, który zauważyłem, poprawiając pierwszy. Klauzula warunkowa, która sprawdza wartości NA, musi być pierwsza, jeśli ma być obsługiwana zgodnie z planem, ponieważ ...

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

Kolejność argumentów może mieć znaczenie w przypadku używania znaku „&”.

IRTFM
źródło
1
To jest najwyżej głosowane pytanie, a następnie znajduje się: stackoverflow.com/questions/9860090/ ...
PatrickT
1
Zaletą jest zwartość i łatwość zrozumienia. Wadą jest brak użyteczności w zadaniach budowania funkcji. Jeśli ktoś chce to powielić, [trzeba zawinąć whichlub zastosować dodatkowe !is.naograniczenia.
IRTFM,
Czy „który” jest wymagany, a jeśli nie, to dlaczego go używasz?
Cleb
1
Nie jest to „wymagane”, ale możesz uzyskać inny wynik, jeśli pominiesz rozszerzenie which. Jeśli zarówno V1, jak i V2 są NA, otrzymasz rząd NA na tej pozycji, jeśli pominiesz which. Pracuję z dużymi zbiorami danych i nawet stosunkowo niewielki procent NA naprawdę wypełni mój ekran niepotrzebnymi danymi. Niektórzy myślą, że to funkcja. Ja nie.
IRTFM
Jak dołączyć wywołanie do grepllub grepz tym, aby oprócz tych warunków warunkowych również dopasować wzorce dla żądanych wierszy?
user5359531
31

Szukasz „|”. Zobacz http://cran.r-project.org/doc/manuals/R-intro.html#Logical-vectors

my.data.frame <- data[(data$V1 > 2) | (data$V2 < 4), ]
ncray
źródło
NIE jest to odporne na istnienie NAsw ramce danych: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

Dla ścisłości możemy użyć operatorów [i [[:

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

Kilka opcji

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 $ nazwa jest odpowiednikiem df [["nazwa", exact = FALSE]]

Używając dplyr:

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

Za pomocą sqldf:

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

Dane wyjściowe dla powyższych opcji:

          v1 v2
1 0.26550866  a
2 0.37212390  b
3 0.20168193  e
4 0.94467527  g
5 0.06178627  j
mpalanco
źródło
1
jak byś to zrobił dla warunku 1 AND i 3 warunków OR, na przykład: my.data.frame <- data [data $ V3> 10 & ((data $ V1> 2) | (data $ V2 <4) | (dane $ V4 <5),]. Kiedy to robię, nie działa
R Guru
1
Łał! sqldfPakiet jest zbyt dobra. Bardzo przydatne, zwłaszcza gdy subset()robi się trochę bolesne :)
Dawny33