Filter data.frame baris dengan kondisi logis

155

Saya ingin memfilter baris dari data.frameberdasarkan kondisi logis. Anggap saja saya memiliki bingkai data seperti

   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

Yang saya inginkan adalah mendapatkan bingkai data baru yang terlihat sama tetapi hanya memiliki data untuk satu cell_type. Misalnya, subset / pilih baris yang berisi tipe sel "hesc":

   expr_value     cell_type
1    5.929771          hesc
2    5.873096          hesc
3    5.665857          hesc

Atau tipe sel "bj fibroblast" atau "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

Apakah ada cara mudah untuk melakukan ini?

Saya sudah mencoba:

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

jika bingkai data asli disebut "expr", tetapi memberikan hasil dalam format yang salah seperti yang Anda lihat.

lhahne
sumber

Jawaban:

210

Untuk memilih baris menurut satu 'cell_type' (mis. 'Hesc'), gunakan ==:

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

Untuk memilih baris menurut dua atau lebih 'cell_type' yang berbeda, (misalnya 'hesc' atau 'bj fibroblast'), gunakan %in%:

expr[expr$cell_type %in% c("hesc", "bj fibroblast"), ]
belajar
sumber
28
Sadarilah bahwa ==fungsi ini akan mengambil catatan NA apa pun serta "hesc", sedangkan %in%tidak akan.
Matt Parker
Saya ingin tahu apakah ini berfungsi sekarang? Saya tidak dapat mengatur ulang kerangka data berdasarkan kondisi dengan cara ini.
Sumanth Lazarus
85

Gunakan subset(untuk penggunaan interaktif)

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

atau lebih baik dplyr::filter()

filter(expr, cell_type %in% c("bj fibroblast", "hesc"))
rcs
sumber
37
Cermat! Dokumentasi subsetmemiliki PERINGATAN besar: "Ini adalah fungsi kenyamanan yang dimaksudkan untuk digunakan secara interaktif. Untuk pemrograman lebih baik menggunakan fungsi standar subset seperti [, dan khususnya evaluasi subset argumen non-standar dapat memiliki konsekuensi yang tidak terduga. . "
Aleksandar Dimitrov
33

Alasannya expr[expr[2] == 'hesc']tidak berfungsi adalah untuk frame data, x[y]memilih kolom, bukan baris. Jika Anda ingin memilih baris, ganti sintaksnya x[y,]sebagai gantinya:

> expr[expr[2] == 'hesc',]
  expr_value cell_type
4   5.929771      hesc
5   5.873096      hesc
6   5.665857      hesc
Ken Williams
sumber
Ini akan mengambil semua NAcatatan juga! Karenanya, tidak berlaku. Alasan itu tampaknya benar dihasilkan dari kenyataan bahwa expr dataframe tidak ada NAdi kolom yang difilter. Jika ada di NAsana, cara Anda tidak berlaku seperti yang saya katakan sebelumnya.
Erdogan CEVHER
26

Anda bisa menggunakan dplyrpaket:

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

Sepertinya tidak ada yang memasukkan fungsi yang mana. Itu juga bisa terbukti bermanfaat untuk penyaringan.

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

Ini juga akan menangani NAS dan menjatuhkannya dari kerangka data yang dihasilkan.

Menjalankan ini pada 9840 dengan 24frame data 50.000 kali, sepertinya metode mana yang memiliki 60% waktu berjalan lebih cepat daripada metode% dalam%.

eigenfoo
sumber
4

Saya sedang mengerjakan dataframe dan tidak beruntung dengan jawaban yang diberikan, selalu mengembalikan 0 baris, jadi saya menemukan dan menggunakan grepl:

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

Yang pada dasarnya memangkas dataframe saya menjadi hanya baris yang berisi "downlink" di kolom Arah pengiriman. NB Jika ada yang bisa menebak mengapa saya tidak melihat perilaku yang diharapkan, silakan tinggalkan komentar.

Khusus untuk pertanyaan awal:

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

expr[grepl("bj fibroblast|hesc",expr$cell_type),]
Justin Harbour
sumber
3

Terkadang kolom yang ingin Anda filter dapat muncul di posisi yang berbeda dari indeks kolom 2 atau memiliki nama variabel.

Dalam hal ini, Anda cukup merujuk nama kolom yang ingin Anda filter sebagai:

columnNameToFilter = "cell_type"
expr[expr[[columnNameToFilter]] == "hesc", ]
Daniel Bonetti
sumber
Ini akan mengambil semua NAcatatan juga! Karenanya, tidak berlaku.
Erdogan CEVHER
0

kita bisa menggunakan perpustakaan data.table

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

atau filter menggunakan %like%operator untuk pencocokan pola

 expr[cell_type %like% "hesc"|cell_type %like% "fibroblast"]
Varn K
sumber
0

Ini bekerja seperti sulap bagi saya.

celltype_hesc_bool = expr['cell_type'] == 'hesc'

expr_celltype_hesc = expr[celltype_hesc]

Periksa posting blog ini

DKMDebugin
sumber