Filtra le righe di data.frame in base a una condizione logica


155

Voglio filtrare le righe in data.framebase a una condizione logica. Supponiamo che io abbia un frame di dati simile

   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

Quello che voglio è ottenere un nuovo frame di dati che assomigli allo stesso, ma abbia solo i dati per un cell_type. Ad esempio sottoinsieme / selezionare righe che contengono il tipo di cella "hesc":

   expr_value     cell_type
1    5.929771          hesc
2    5.873096          hesc
3    5.665857          hesc

O tipo di cellula "bj fibroblast" o "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

C'è un modo semplice per farlo?

Ho provato:

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

se il frame di dati originale si chiama "expr", ma fornisce i risultati in un formato errato, come puoi vedere.

Risposte:


210

Per selezionare le righe in base a un 'tipo_cella' (ad esempio 'hesc'), utilizzare ==:

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

Per selezionare le righe in base a due o più "cell_type" diversi (ad esempio "hesc" o "bj fibroblast"), utilizzare %in%:

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

28
Essere consapevoli del fatto che la ==funzione raccoglierà tutti i record NA e "hesc", mentre %in%non lo farà.
Matt Parker,

Mi chiedo se ora funziona? In questo modo non sono stato in grado di sotto-impostare il dataframe in base alle condizioni.
Sumanth Lazzaro,

85

Usa subset(per uso interattivo)

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

o meglio dplyr::filter()

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

37
! attento La documentazione di subsetha un grande AVVISO: "Questa è una funzione di convenienza destinata all'uso interattivo. Per la programmazione è meglio usare le funzioni di sottoinsieme standard come [, e in particolare la valutazione non standardizzata del sottoinsieme di argomenti può avere imprevisti conseguenti ces ".
Aleksandar Dimitrov

33

Il motivo expr[expr[2] == 'hesc']non funziona è che per un frame di dati, x[y]seleziona colonne, non righe. Se si desidera selezionare le righe, passare x[y,]invece alla sintassi :

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

Questo raccoglierà anche tutti i NArecord! Quindi, non applicabile. Il motivo per cui sembrava essere vero è risultato dal fatto che expr dataframe non ha NAnella colonna filtrata. Se c'è NA, la tua strada non è applicabile come ho detto prima.
Erdogan CEVHER,

26

È possibile utilizzare il dplyrpacchetto:

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

5

Nessuno sembra aver incluso la funzione. Può anche rivelarsi utile per il filtraggio.

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

Questo gestirà anche i NA e li eliminerà dal frame di dati risultante.

Eseguendolo su un dataframe 9840 per 24 50000 volte, sembra che il metodo abbia un tempo di esecuzione del 60% più veloce rispetto al metodo% in%.


4

Stavo lavorando su un frame di dati e non ho avuto fortuna con le risposte fornite, ha sempre restituito 0 righe, quindi ho trovato e usato grepl:

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

Che sostanzialmente ha ridotto il mio frame di dati solo alle righe che contenevano "downlink" nella colonna Direzione di trasmissione. PS Se qualcuno può indovinare il motivo per cui non vedo il comportamento previsto, si prega di lasciare un commento.

In particolare alla domanda originale:

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

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

3

A volte la colonna che si desidera filtrare può apparire in una posizione diversa rispetto all'indice di colonna 2 o avere un nome variabile.

In questo caso, puoi semplicemente fare riferimento al nome della colonna che desideri filtrare come:

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

Questo raccoglierà anche tutti i NArecord! Quindi, non applicabile.
Erdogan CEVHER,

0

possiamo usare la libreria data.table

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

o filtrare usando l' %like%operatore per la corrispondenza del modello

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

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.