根据vector中的值从数据框中select行
我有类似这样的数据:
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
variables中的值从这个数据框中select行。 例如,如果我想select包含“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
如预期。 但是,我的实际数据更加复杂,我实际上想根据向量中的值来select行
vc <- c('a', 'c')
所以我试了
dt[dt$fct == vc, ]
但当然这是行不通的。 我知道我可以编写一些东西来循环遍历vector,并将所需的行拖出来,并将它们附加到一个新的数据框中,但是我希望有一个更优雅的方法。
那么如何根据vectorvc
的内容过滤/分类我的数据呢?
看看?"%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),]
与上面类似,使用来自dplyr
filter
:
filter(df, fct %in% vc)
另一个select是使用一个键控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.table
的增强forms),fct
列设置为key。 - 接下来,您可以使用
[J(vc)]
与vc
vector进行子集合。
注意:当键是因子/字符variables时,还可以使用setDT(dt, key = 'fct')[vc]
但在vc
是数字向量时不起作用。 当vc
是一个数字向量,并且不包含在J()
或.()
, vc
将作为一个rowindex工作。
关于密钥和子集的概念的更详细的解释可以在vignette Keys和基于快速二分search的子集中find 。
@Frank在评论中提出了另一种select:
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]