Filtern Sie data.frame-Zeilen nach einer logischen Bedingung


155

Ich möchte Zeilen aus einer data.framebasierend auf einer logischen Bedingung filtern . Nehmen wir an, ich habe einen Datenrahmen wie

   expr_value     cell_type
1    5.345618 bj fibroblast
2    5.195871 bj fibroblast
3    5.247274 bj fibroblast
4    5.929771          hesc
5    5.873096          hesc
6    5.665857          hesc
7    6.791656          hips
8    7.133673          hips
9    7.574058          hips
10   7.208041          hips
11   7.402100          hips
12   7.167792          hips
13   7.156971          hips
14   7.197543          hips
15   7.035404          hips
16   7.269474          hips
17   6.715059          hips
18   7.434339          hips
19   6.997586          hips
20   7.619770          hips
21   7.490749          hips

Ich möchte einen neuen Datenrahmen erhalten, der gleich aussieht, aber nur die Daten für einen Zelltyp enthält. ZB Teilmenge / Auswahlzeilen, die den Zelltyp "hesc" enthalten:

   expr_value     cell_type
1    5.929771          hesc
2    5.873096          hesc
3    5.665857          hesc

Oder entweder Zelltyp "bj Fibroblast" oder "hesc":

   expr_value     cell_type
1    5.345618 bj fibroblast
2    5.195871 bj fibroblast
3    5.247274 bj fibroblast
4    5.929771          hesc
5    5.873096          hesc
6    5.665857          hesc

Gibt es eine einfache Möglichkeit, dies zu tun?

Ich habe es versucht:

expr[expr[2] == 'hesc']
# [1] "5.929771" "5.873096" "5.665857" "hesc"     "hesc"     "hesc"    

Wenn der ursprüngliche Datenrahmen "Ausdruck" heißt, die Ergebnisse jedoch im falschen Format angezeigt werden, wie Sie sehen können.

Antworten:


210

Verwenden Sie Folgendes, um Zeilen nach einem 'Zelltyp' (z. B. 'hesc') auszuwählen ==:

expr[expr$cell_type == "hesc", ]

Verwenden Sie Folgendes, um Zeilen nach zwei oder mehr verschiedenen 'cell_type' auszuwählen (z. B. entweder 'hesc' oder 'bj fibroblast') %in%:

expr[expr$cell_type %in% c("hesc", "bj fibroblast"), ]

28
==Beachten Sie, dass die Funktion alle NA-Datensätze sowie "hesc" aufnimmt, während dies %in%nicht der Fall ist .
Matt Parker

Ich frage mich, ob das jetzt funktioniert? Auf diese Weise konnte ich den Datenrahmen basierend auf der Bedingung nicht unterteilen.
Sumanth Lazarus

85

Verwendung subset(zur interaktiven Verwendung)

subset(expr, cell_type == "hesc")
subset(expr, cell_type %in% c("bj fibroblast", "hesc"))

oder besser dplyr::filter()

filter(expr, cell_type %in% c("bj fibroblast", "hesc"))

37
Vorsichtig! Die Dokumentation von subsethat eine große WARNUNG: "Dies ist eine Komfortfunktion, die für die interaktive Verwendung vorgesehen ist. Für die Programmierung ist es besser, die Standard-Teilmengenfunktionen wie [zu verwenden, und insbesondere die nicht standardisierte Bewertung der Argument- Teilmenge kann unerwartete Folgen haben . "
Aleksandar Dimitrov

33

Der Grund, warum expr[expr[2] == 'hesc']dies nicht funktioniert, ist, dass für einen x[y]Datenrahmen Spalten und keine Zeilen ausgewählt werden. Wenn Sie Zeilen auswählen möchten, ändern Sie x[y,]stattdessen die Syntax :

> expr[expr[2] == 'hesc',]
  expr_value cell_type
4   5.929771      hesc
5   5.873096      hesc
6   5.665857      hesc

Dadurch werden auch alle NADatensätze erfasst! Daher nicht anwendbar. Der Grund dafür schien darin zu liegen, dass der expr-Datenrahmen NAin der gefilterten Spalte keine enthält . Wenn es dort ist NA, ist Ihr Weg nicht anwendbar, wie ich zuvor sagte.
Erdogan CEVHER

26

Sie könnten das dplyrPaket verwenden:

library(dplyr)
filter(expr, cell_type == "hesc")
filter(expr, cell_type == "hesc" | cell_type == "bj fibroblast")

5

Niemand scheint die welche Funktion aufgenommen zu haben. Es kann sich auch zum Filtern als nützlich erweisen.

expr[which(expr$cell == 'hesc'),]

Dadurch werden auch NAs behandelt und aus dem resultierenden Datenrahmen entfernt.

Wenn dies 50000 Mal auf einem 9840 x 24-Datenrahmen ausgeführt wird, scheint die Methode 60% schneller zu laufen als die Methode% in%.


4

Ich habe an einem Datenrahmen gearbeitet und hatte kein Glück mit den bereitgestellten Antworten. Er gab immer 0 Zeilen zurück, also habe ich grepl gefunden und verwendet:

df = df[grepl("downlink",df$Transmit.direction),]

Dadurch wurde mein Datenrahmen im Grunde nur auf die Zeilen gekürzt, die "Downlink" in der Spalte "Übertragungsrichtung" enthielten. PS Wenn jemand erraten kann, warum ich das erwartete Verhalten nicht sehe, hinterlasse bitte einen Kommentar.

Speziell zur ursprünglichen Frage:

expr[grepl("hesc",expr$cell_type),]

expr[grepl("bj fibroblast|hesc",expr$cell_type),]

3

Manchmal wird die zu filternde Spalte an einer anderen Position als der Spaltenindex 2 angezeigt oder hat einen Variablennamen.

In diesem Fall können Sie den zu filternden Spaltennamen einfach wie folgt referenzieren :

columnNameToFilter = "cell_type"
expr[expr[[columnNameToFilter]] == "hesc", ]

Dadurch werden auch alle NADatensätze erfasst! Daher nicht anwendbar.
Erdogan CEVHER

0

Wir können die Bibliothek data.table verwenden

  library(data.table)
  expr <- data.table(expr)
  expr[cell_type == "hesc"]
  expr[cell_type %in% c("hesc","fibroblast")]

oder filtern Sie mit dem %like%Operator für den Mustervergleich

 expr[cell_type %like% "hesc"|cell_type %like% "fibroblast"]

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.