通过逻辑条件过滤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成纤维细胞”或“ 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”,但您看到的格式错误。

Answers:


210

要根据一种 “ cell_type”(例如“ hesc”)选择行,请使用==

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

要根据两个或多个不同的“ cell_type”(例如“ hesc” “ bj成纤维细胞”)选择行,请使用%in%

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

28
请注意,该==函数将拾取所有NA记录以及“ hesc”,而%in%不会。
马特·帕克

我想知道现在是否行得通吗?我无法以这种方式根据条件对数据框进行子集化。
Sumanth Lazarus

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有很大的警告:“这是一个方便使用的功能,旨在交互使用。对于编程,最好使用标准的子设置功能,例如[,尤其是参数子集的非标准评估可能会带来意料之外的后果。 ”。
Aleksandar Dimitrov

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记录!因此,不适用。之所以如此,是因为expr数据帧NA在过滤的列中没有。如果有的NA话,您的方式将不适用我之前所说的方法。
Erdogan CEVHER

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 x 24数据帧上运行50000次,似乎哪种方法比%in%方法快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记录!因此,不适用。
Erdogan CEVHER

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"]

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.