根据向量中的值从数据框中选择行
Posted
技术标签:
【中文标题】根据向量中的值从数据框中选择行【英文标题】:Select rows from a data frame based on values in a vector 【发布时间】:2012-07-21 16:06:46 【问题描述】:我有类似这样的数据:
dt <- structure(list(fct = structure(c(1L, 2L, 3L, 4L, 3L, 4L, 1L, 2L, 3L, 1L, 2L, 3L, 2L, 3L, 4L), .Label = c("a", "b", "c", "d"), class = "factor"), X = c(2L, 4L, 3L, 2L, 5L, 4L, 7L, 2L, 9L, 1L, 4L, 2L, 5L, 4L, 2L)), .Names = c("fct", "X"), class = "data.frame", row.names = c(NA, -15L))
我想根据fct
变量中的值从此数据框中选择行。例如,如果我希望选择包含“a”或“c”的行,我可以这样做:
dt[dt$fct == 'a' | dt$fct == 'c', ]
产生
1 a 2
3 c 3
5 c 5
7 a 7
9 c 9
10 a 1
12 c 2
14 c 4
正如预期的那样。但我的实际数据更复杂,我实际上想根据向量中的值选择行,例如
vc <- c('a', 'c')
所以我尝试了
dt[dt$fct == vc, ]
但这当然行不通。我知道我可以编写一些代码来循环遍历向量并提取所需的行并将它们附加到新的数据帧中,但我希望有一种更优雅的方式。
那么如何根据向量vc
的内容过滤/子集我的数据?
【问题讨论】:
尝试:dt[dt$fct %in% vc,]
基本上==
用于一项,%in%
用于向量比较。
【参考方案1】:
看看?"%in%"
。
dt[dt$fct %in% vc,]
fct X
1 a 2
3 c 3
5 c 5
7 a 7
9 c 9
10 a 1
12 c 2
14 c 4
你也可以使用?is.element
:
dt[is.element(dt$fct, vc),]
【讨论】:
【参考方案2】:与上述类似,使用来自dplyr
的filter
:
filter(df, fct %in% vc)
【讨论】:
【参考方案3】:另一种选择是使用带键的data.table
:
library(data.table)
setDT(dt, key = 'fct')[J(vc)] # or: setDT(dt, key = 'fct')[.(vc)]
导致:
fct X
1: a 2
2: a 7
3: a 1
4: c 3
5: c 5
6: c 9
7: c 2
8: c 4
这是做什么的:
setDT(dt, key = 'fct')
将 data.frame
转换为 data.table
(这是 data.frame
的增强形式),并将 fct
列设置为键。
接下来,您可以使用vc
向量和[J(vc)]
进行子集化。
注意:当键是因子/字符变量时,您也可以使用setDT(dt, key = 'fct')[vc]
,但当vc
是数字向量时,这将不起作用。当vc
是一个数字向量并且没有包裹在J()
或.()
中时,vc
将用作行索引。
keys 和子集的概念更详细的解释可以在 vignette Keys and fast binary search based subset 中找到。
@Frank 在 cmets 中建议的替代方案:
setDT(dt)[J(vc), on=.(fct)]
当vc
包含dt
中不存在的值时,您需要添加nomatch = 0
:
setDT(dt, key = 'fct')[J(vc), nomatch = 0]
或:
setDT(dt)[J(vc), on=.(fct), nomatch = 0]
【讨论】:
当 data.table 中的向量和变量是数字时,我无法正常工作。有什么想法吗? @GauravSinghal 更新了答案,之前版本中的方法适用于字符/因子列;更新后的方法也适用于整数/数字列以上是关于根据向量中的值从数据框中选择行的主要内容,如果未能解决你的问题,请参考以下文章