Wie kombiniere ich mehrere Bedingungen, um einen Datenrahmen mit "ODER" zu unterteilen?

174

Ich habe einen data.frame in R. Ich möchte zwei verschiedene Bedingungen in zwei verschiedenen Spalten ausprobieren, aber ich möchte, dass diese Bedingungen inklusive sind. Daher möchte ich "ODER" verwenden, um die Bedingungen zu kombinieren. Ich habe die folgende Syntax bereits mit großem Erfolg verwendet, als ich die "AND" -Bedingung verwenden wollte.

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

Aber ich weiß nicht, wie ich oben ein 'ODER' verwenden soll.

Sam
quelle

Antworten:

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

Eine alternative Lösung, die das Verhalten dieser Funktion nachahmt und für die Aufnahme in einen Funktionskörper besser geeignet wäre:

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

Einige Leute kritisieren die Verwendung von whichals nicht erforderlich, aber es verhindert, dass die NAWerte unerwünschte Ergebnisse zurückwerfen. Das Äquivalent (dh keine NA-Zeilen für NAs in V1 oder V2 zurückgeben) zu den beiden oben gezeigten Optionen ohne das whichwäre:

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

Hinweis: Ich möchte mich bei dem anonymen Mitwirkenden bedanken, der versucht hat, den Fehler im Code direkt darüber zu beheben. Dieser Fehler wurde von den Moderatoren abgelehnt. Es gab tatsächlich einen zusätzlichen Fehler, den ich bemerkte, als ich den ersten korrigierte. Die Bedingungsklausel, die nach NA-Werten sucht, muss an erster Stelle stehen, wenn sie wie beabsichtigt behandelt werden soll, da ...

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

Die Reihenfolge der Argumente kann bei der Verwendung von '& "von Bedeutung sein.

IRTFM
quelle
1
Dies ist die am höchsten bewertete
PatrickT
1
Der Vorteil ist Kompaktheit und leicht verständlich. Der Nachteil ist die mangelnde Nützlichkeit bei Aufgaben zum Aufbau von Funktionen. Wenn man dies mit replizieren möchte, [muss whichman zusätzliche !is.naEinschränkungen einschließen oder verwenden .
IRTFM
Ist das "was" erforderlich und wenn nicht, warum verwenden Sie es?
Cleb
1
Es ist nicht "erforderlich", aber Sie können ein anderes Ergebnis erhalten, wenn Sie das weglassen which. Wenn sowohl V1 als auch V2 NA sind, würden Sie eine Reihe von NAs an dieser Position erhalten, wenn Sie die weglassen which. Ich arbeite mit großen Datenmengen und selbst ein relativ kleiner Prozentsatz der NAs füllt meinen Bildschirm wirklich mit Junk-Ausgabe. Einige Leute denken, dass dies eine Funktion ist. Ich nicht.
IRTFM
Wie fügen Sie einen Aufruf an greploder grepmit diesem hinzu, um zusätzlich zu diesen Bedingungen auch einen Mustervergleich für die gewünschten Zeilen durchzuführen?
user5359531
31

Sie suchen nach "|." Siehe http://cran.r-project.org/doc/manuals/R-intro.html#Logical-vectors

my.data.frame <- data[(data$V1 > 2) | (data$V2 < 4), ]
ncray
quelle
Dies ist NICHT robust für die Existenz von NAs in einem Datenrahmen: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

Der Vollständigkeit halber können wir die Operatoren verwenden [und [[:

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

Mehrere Möglichkeiten

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 entspricht df [["name", genau = FALSE]]

Verwenden von dplyr:

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

Verwenden von sqldf:

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

Ausgabe für die oben genannten Optionen:

          v1 v2
1 0.26550866  a
2 0.37212390  b
3 0.20168193  e
4 0.94467527  g
5 0.06178627  j
mpalanco
quelle
1
Wie würden Sie dies für 1 UND-Bedingung und 3 ODER-Bedingungen tun, die so abhängig sind, zum Beispiel: my.data.frame <- Daten [Daten $ V3> 10 & ((Daten $ V1> 2) | (Daten $ V2 <4) | (Daten $ V4 <5),]. Wenn ich das mache, funktioniert es nicht
R Guru
1
Beeindruckend! Das sqldfPaket ist zu gut. Sehr praktisch, besonders wenn es subset()etwas schmerzhaft wird :)
Dawny33