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.

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 „&”.


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), ]

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

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
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.