Filtruj wiersze data.frame według warunku logicznego

155

Chcę odfiltrować wiersze z na data.framepodstawie warunku logicznego. Załóżmy, że mam taką ramkę danych

   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

To, czego chcę, to uzyskać nową ramkę danych, która wygląda tak samo, ale ma dane tylko dla jednego typu cell_type. Np. Podzbiór / wybierz wiersze zawierające typ komórki „hesc”:

   expr_value     cell_type
1    5.929771          hesc
2    5.873096          hesc
3    5.665857          hesc

Lub typ komórki „bj fibroblast” lub „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

Czy jest na to łatwy sposób?

Próbowałem:

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

jeśli oryginalna ramka danych nosi nazwę „wyrażenie”, ale daje wyniki w złym formacie, jak widać.

lhahne
źródło

Odpowiedzi:

210

Aby wybrać wiersze według jednego „cell_type” (np. „Hesc”), użyj ==:

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

Aby wybrać wiersze według dwóch lub więcej różnych „cell_type” (np. „Hesc” lub „bj fibroblast”), użyj %in%:

expr[expr$cell_type %in% c("hesc", "bj fibroblast"), ]
Learnr
źródło
28
Należy pamiętać, że ==funkcja będzie pobierać wszystkie rekordy NA, a także „hesc”, ale %in%nie.
Matt Parker
Zastanawiam się, czy to teraz działa? Nie mogłem w ten sposób podzestawić ramki danych na podstawie stanu.
Sumanth Lazarus
85

Użyj subset(do użytku interaktywnego)

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

albo lepiej dplyr::filter()

filter(expr, cell_type %in% c("bj fibroblast", "hesc"))
rcs
źródło
37
Ostrożny! Dokumentacja subsetma duże OSTRZEŻENIE: "Jest to wygodna funkcja przeznaczona do użytku interaktywnego. Do programowania lepiej jest używać standardowych funkcji podzbiorów, takich jak [, a w szczególności niestandarowa ocena podzbioru argumentów może mieć nieoczekiwane konsekwencje ”.
Aleksandar Dimitrov
33

Przyczyną expr[expr[2] == 'hesc']nie jest to, że w przypadku ramki danych x[y]wybiera kolumny, a nie wiersze. Jeśli chcesz wybrać wiersze, x[y,]zamiast tego zmień składnię :

> expr[expr[2] == 'hesc',]
  expr_value cell_type
4   5.929771      hesc
5   5.873096      hesc
6   5.665857      hesc
Ken Williams
źródło
To również podniesie wszelkie NArekordy! W związku z tym nie dotyczy. Powód, dla którego wydawało się to prawdą, wynikał z faktu, że ramka danych wyrażenia nie ma NAw filtrowanej kolumnie. Jeśli istnieje NA, twoja droga nie ma zastosowania, jak powiedziałem wcześniej.
Erdogan CEVHER
26

Możesz użyć dplyrpakietu:

library(dplyr)
filter(expr, cell_type == "hesc")
filter(expr, cell_type == "hesc" | cell_type == "bj fibroblast")
nathaneastwood
źródło
5

Wydaje się, że nikt nie uwzględnił funkcji która. Może się również przydać do filtrowania.

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

Spowoduje to również obsługę NA i usunięcie ich z wynikowej ramki danych.

Po uruchomieniu tego na ramce danych 9840 na 24 50000 razy wydaje się, że ta metoda ma 60% szybszy czas działania niż metoda% w%.

eigenfoo
źródło
4

Pracowałem na ramce danych i nie miałem szczęścia z udzielonymi odpowiedziami, zawsze zwracała 0 wierszy, więc znalazłem i użyłem grepl:

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

Co w zasadzie przycięło moją ramkę danych tylko do wierszy zawierających „łącze w dół” w kolumnie Kierunek transmisji. PS Jeśli ktoś może odgadnąć, dlaczego nie widzę oczekiwanego zachowania, zostaw komentarz.

W szczególności do pierwotnego pytania:

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

expr[grepl("bj fibroblast|hesc",expr$cell_type),]
Justin Harbour
źródło
3

Czasami kolumna, którą chcesz filtrować, może pojawić się na innej pozycji niż indeks kolumny 2 lub mieć nazwę zmiennej.

W takim przypadku możesz po prostu odnieść nazwę kolumny, którą chcesz filtrować, jako:

columnNameToFilter = "cell_type"
expr[expr[[columnNameToFilter]] == "hesc", ]
Daniel Bonetti
źródło
To również podniesie wszelkie NArekordy! W związku z tym nie dotyczy.
Erdogan CEVHER
0

możemy skorzystać z biblioteki data.table

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

lub filtruj używając %like%operatora do dopasowania wzorca

 expr[cell_type %like% "hesc"|cell_type %like% "fibroblast"]
Varn K
źródło