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?


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

26

Ähnlich wie oben, unter Verwendung filtervon dplyr:

filter(df, fct %in% vc)

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]

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
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.