Wählen Sie Zeilen aus einem Datenrahmen basierend auf Werten in einem Vektor aus

75

Ich habe ähnliche Daten:

dt <- structure(list(fct = structure(c(1L, 2L, 3L, 4L, 3L, 4L, 1L, 2L, 3L, 1L, 2L, 3L, 2L, 3L, 4L), .Label = c("a", "b", "c", "d"), class = "factor"), X = c(2L, 4L, 3L, 2L, 5L, 4L, 7L, 2L, 9L, 1L, 4L, 2L, 5L, 4L, 2L)), .Names = c("fct", "X"), class = "data.frame", row.names = c(NA, -15L))

Ich möchte Zeilen aus diesem Datenrahmen basierend auf den Werten in der fctVariablen auswählen . Wenn ich beispielsweise Zeilen auswählen möchte, die entweder "a" oder "c" enthalten, kann ich Folgendes tun:

dt[dt$fct == 'a' | dt$fct == 'c', ]

was ergibt

1    a 2
3    c 3
5    c 5
7    a 7
9    c 9
10   a 1
12   c 2
14   c 4

wie erwartet. Aber meine tatsächlichen Daten sind komplexer und ich möchte tatsächlich Zeilen basierend auf den Werten in einem Vektor wie z

vc <- c('a', 'c')

Also habe ich es versucht

dt[dt$fct == vc, ]

aber das funktioniert natürlich nicht. Ich wusste, dass ich etwas codieren konnte, um den Vektor zu durchlaufen, die benötigten Zeilen herauszuziehen und sie an einen neuen Datenrahmen anzuhängen, aber ich hatte gehofft, dass es einen eleganteren Weg gibt.

Wie kann ich meine Daten basierend auf dem Inhalt des Vektors filtern / unterteilen vc?

Joe King
quelle
12
try: dt[dt$fct %in% vc,] Grundsätzlich ==gilt dies für einen Artikel und %in%für einen Vektorvergleich.
Tyler Rinker

Antworten:

132

Schau es dir an ?"%in%".

dt[dt$fct %in% vc,]
   fct X
1    a 2
3    c 3
5    c 5
7    a 7
9    c 9
10   a 1
12   c 2
14   c 4

Sie könnten auch verwenden ?is.element:

dt[is.element(dt$fct, vc),]
johannes
quelle
26

Ähnlich wie oben, unter Verwendung filtervon dplyr:

filter(df, fct %in% vc)
Andrew Haynes
quelle
10

Eine andere Option wäre die Verwendung eines Schlüssels data.table:

library(data.table)
setDT(dt, key = 'fct')[J(vc)]  # or: setDT(dt, key = 'fct')[.(vc)]

was in ... endet:

   fct X
1:   a 2
2:   a 7
3:   a 1
4:   c 3
5:   c 5
6:   c 9
7:   c 2
8:   c 4

Was dies tut:

  • setDT(dt, key = 'fct')transformiert das data.framein a data.table(was eine erweiterte Form von a ist data.frame) mit der fctSpalte als Schlüssel.
  • Als nächstes können Sie einfach mit dem vcVektor mit unterteilen [J(vc)].

HINWEIS: Wenn der Schlüssel eine Faktor- / Zeichenvariable ist, können Sie ihn auch verwenden setDT(dt, key = 'fct')[vc], dies funktioniert jedoch nicht, wenn vces sich um einen numerischen Vektor handelt. Wann vcist ein numerischer Vektor und wird nicht in J()oder eingeschlossen .(), vcfunktioniert als Zeilenindex.

Eine detailliertere Erläuterung des Konzepts der Schlüssel und der Teilmenge finden Sie in den Vignettenschlüsseln und der auf der schnellen binären Suche basierenden Teilmenge .

Eine Alternative, wie von @Frank in den Kommentaren vorgeschlagen:

setDT(dt)[J(vc), on=.(fct)]

Wenn vcWerte enthalten sind, die in nicht vorhanden sind dt, müssen Sie Folgendes hinzufügen nomatch = 0:

setDT(dt, key = 'fct')[J(vc), nomatch = 0]

oder:

setDT(dt)[J(vc), on=.(fct), nomatch = 0]
Jaap
quelle
Ich kann es nicht zum Laufen bringen, wenn der Vektor und die Variable in data.table numerisch sind. Irgendwelche Ideen?
Gaurav Singhal
@GauravSinghal hat die Antwort aktualisiert. Die Methode in der vorherigen Version wurde für Zeichen- / Faktorspalten bearbeitet. Die aktualisierte Methode funktioniert auch für ganzzahlige / numerische Spalten
Jaap