按逻辑条件过滤 data.frame 行
Posted
技术标签:
【中文标题】按逻辑条件过滤 data.frame 行【英文标题】:Filter data.frame rows by a logical condition 【发布时间】:2022-01-10 23:17:25 【问题描述】:我想根据逻辑条件过滤来自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”,但它给出的结果格式错误,如您所见。
【问题讨论】:
【参考方案1】:这对我来说就像魔术一样。
celltype_hesc_bool = expr['cell_type'] == 'hesc'
expr_celltype_hesc = expr[celltype_hesc]
Check this blog post
【讨论】:
【参考方案2】:要根据一个 'cell_type'(例如'hesc')选择行,请使用==
:
expr[expr$cell_type == "hesc", ]
要根据两个或多个不同的“cell_type”(例如“hesc”或“bj fibroblast”)选择行,请使用%in%
:
expr[expr$cell_type %in% c("hesc", "bj fibroblast"), ]
【讨论】:
请注意,==
函数会拾取任何 NA 记录以及“hesc”,而 %in%
不会。
我想知道这是否有效?我无法以这种方式根据条件对数据框进行子集化。【参考方案3】:
我们可以使用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"]
【讨论】:
【参考方案4】:似乎没有人包含 which 功能。它也可以证明对过滤很有用。
expr[which(expr$cell == 'hesc'),]
这还将处理 NA 并将它们从结果数据帧中删除。
在 9840 x 24 数据帧上运行 50000 次,看起来 which 方法的运行时间比 %in% 方法快 60%。
【讨论】:
【参考方案5】:我正在处理一个数据框并且对提供的答案没有运气,它总是返回 0 行,所以我找到并使用了 grepl:
df = df[grepl("downlink",df$Transmit.direction),]
这基本上将我的数据框修剪为仅在传输方向列中包含“下行链路”的行。附:如果有人能猜到为什么我没有看到预期的行为,请发表评论。
具体到原来的问题:
expr[grepl("hesc",expr$cell_type),]
expr[grepl("bj fibroblast|hesc",expr$cell_type),]
【讨论】:
【参考方案6】:有时,您要过滤的列可能出现在与列索引 2 不同的位置或具有变量名称。
在这种情况下,您可以简单地将要过滤的列名引用为:
columnNameToFilter = "cell_type"
expr[expr[[columnNameToFilter]] == "hesc", ]
【讨论】:
这也会获取任何NA
记录!因此,不适用。【参考方案7】:
使用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"))
【讨论】:
小心!subset
的文档有一个很大的警告:“这是一个旨在以交互方式使用的便利函数。对于编程,最好使用标准子集函数,例如 [,特别是参数 的非标准评估子集可能会产生意想不到的后果。”【参考方案8】:
您可以使用dplyr
包:
library(dplyr)
filter(expr, cell_type == "hesc")
filter(expr, cell_type == "hesc" | cell_type == "bj fibroblast")
【讨论】:
【参考方案9】: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
,那么你的方式不适用我之前说的。
感谢您解释如何使用列和行。以上是关于按逻辑条件过滤 data.frame 行的主要内容,如果未能解决你的问题,请参考以下文章