Фільтруйте рядки data.frame за логічною умовою


155

Я хочу фільтрувати рядки з data.frameурахуванням логічної умови. Припустимо, що у мене є такий кадр даних

   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

Мені хочеться отримати новий кадр даних, який виглядає однаково, але містить дані лише для одного типу Cell_type. Напр. Підмножина / вибір рядків, що містить тип комірки "hesc":

   expr_value     cell_type
1    5.929771          hesc
2    5.873096          hesc
3    5.665857          hesc

Або клітинку типу "bj fibroblast" або "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

Чи є якийсь простий спосіб зробити це?

Я спробував:

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

якщо вихідний кадр даних називається "expr", але він дає результати в неправильному форматі, як ви бачите.

Відповіді:


210

Щоб вибрати рядки відповідно до одного типу "cell_type" (наприклад, "hesc"), використовуйте ==:

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

Щоб вибрати рядки відповідно до двох або більше різних типів "cell_type" (наприклад, "hesc" або "bj fibroblast "), використовуйте %in%:

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

28
Майте на увазі, що ця ==функція буде збирати будь-які записи NA, а також "коливатися", тоді як %in%не буде.
Метт Паркер

Цікаво, чи працює це зараз? Я не зміг таким чином підмножити кадр даних на основі умови.
Сумант Лазар

85

Використання subset(для інтерактивного використання)

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

або краще dplyr::filter()

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

37
Обережно! Документація subsetмає велике ПОПЕРЕДЖЕННЯ: "Це функція зручності, призначена для інтерактивного використання. Для програмування краще використовувати стандартні функції підмножини на зразок [, і, зокрема, нестандартне оцінювання підмножини аргументів може мати непередбачувані наслідки . "
Олександр Димитров

33

Причина expr[expr[2] == 'hesc']не працює в тому, що для кадру даних x[y]вибираються стовпці, а не рядки. Якщо потрібно вибрати рядки, x[y,]замість цього перейдіть до синтаксису :

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

Це також підбере будь-які NAзаписи! Отже, не застосовується. Причина, яка, здавалося, є правдою, випливає з того, що NAу фільтруваному стовпці файлу expr немає . Якщо там є NA, ваш спосіб не застосовується, як я вже говорив.
Ердоган ЦЕВЕР

26

Ви можете використовувати dplyrпакет:

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

5

Здається, ніхто не включив, яку функцію. Це також може виявитися корисним для фільтрації.

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

Це також буде обробляти NA та видаляти їх із отриманого фрейму даних.

Запустивши це на кадрі даних 9840 по 2400 50000 разів, схоже, який метод має на 60% швидший час виконання, ніж метод% у%.


4

Я працював над фреймом даних і не маючи шансу надати відповіді, він завжди повертав 0 рядків, тому я знайшов і використав grepl:

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

Який в основному обрізав мій кадр даних лише до рядків, які містили "низхідну лінію" у стовпці "Передача". PS Якщо хтось може здогадатися, чому я не бачу очікуваної поведінки, будь ласка, залиште коментар.

Зокрема до оригінального питання:

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

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

3

Іноді стовпець, який ви хочете відфільтрувати, може відображатися в іншому положенні, ніж індекс 2 стовпця, або мати назву змінної.

У цьому випадку ви можете просто вказати ім'я стовпця, яке ви хочете відфільтрувати, як:

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

Це також підбере будь-які NAзаписи! Отже, не застосовується.
Ердоган ЦЕВЕР

0

ми можемо використовувати бібліотеку data.table

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

або фільтруйте за допомогою %like%оператора для відповідності шаблону

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.