按逻辑条件筛选 data.frame 行

Filter data.frame rows by a logical condition

提问人:lhahne 提问时间:11/6/2009 最后编辑:Henriklhahne 更新时间:6/30/2020 访问量:399877

问:

我想根据逻辑条件从中过滤行。假设我有这样的数据帧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 fibrobot”或“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”,但它以错误的格式给出结果,如您所见。

数据帧 子集 R-FAQ

评论


答:

271赞 learnr 11/6/2009 #1

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

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

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

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

评论

36赞 Matt Parker 11/6/2009
请注意,该函数将拾取任何 NA 记录以及“hesc”,而不会。==%in%
1赞 Sumax 10/10/2019
我想知道现在是否有效?我无法以这种方式根据条件对数据帧进行子集。
97赞 rcs 11/6/2009 #2

用途(用于交互用途)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"))

评论

42赞 Aleksandar Dimitrov 3/9/2013
小心!的文档有一个很大的警告:“这是一个方便的功能,旨在以交互方式使用。对于编程,最好使用像 [ 这样的标准子集函数,特别是参数子集的非标准 d 计算可能会产生意想不到的后果。subset
40赞 Ken Williams 11/10/2009 #3

不起作用的原因是,对于数据框,选择的是列,而不是行。如果要选择行,请改为使用语法: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

评论

0赞 Erdogan CEVHER 7/31/2018
这也将拾取任何记录!因此,不适用。之所以看起来是正确的,是因为 expr dataframe 在过滤的列中没有。如果有,你的方式就不适用,就像我之前说的。NANANA
0赞 Zhivar Sourati 2/27/2021
感谢您对如何使用列和行的解释。
31赞 nathaneastwood 9/4/2014 #4

您可以使用以下软件包:dplyr

library(dplyr)
filter(expr, cell_type == "hesc")
filter(expr, cell_type == "hesc" | cell_type == "bj fibroblast")
2赞 Daniel Bonetti 8/10/2017 #5

有时,要筛选的列可能出现在与列索引 2 不同的位置,或者具有变量名称。

在这种情况下,您可以简单地将要筛选的列名称引用为:

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

评论

0赞 Erdogan CEVHER 7/31/2018
这也将拾取任何记录!因此,不适用。NA
7赞 Justin Harbour 7/7/2018 #6

我正在处理一个数据帧,但对提供的答案没有运气,它总是返回 0 行,所以我找到并使用了 grepl:

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

这基本上将我的数据帧修剪为仅在传输方向列中包含“下行链路”的行。P.S. 如果有人能猜到为什么我没有看到预期的行为,请发表评论。

具体到原来的问题:

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

expr[grepl("bj fibroblast|hesc",expr$cell_type),]
10赞 eigenfoo 7/18/2018 #7

似乎没有人包含哪个功能。它也可以证明对过滤有用。

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

这也将处理 NA 并将其从生成的数据帧中删除。

在 9840 x 24 个数据帧上运行 50000 次,似乎 which 方法的运行时间比 %in% 方法快 60%。

0赞 Varn K 10/25/2018 #8

我们可以使用 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"]
1赞 DKMDebugin 5/24/2020 #9

这对我来说就像魔术一样。

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

expr_celltype_hesc = expr[celltype_hesc]

查看此博客文章