如何根据正则表达式选择data.table的列? 考虑一个简单的例子如下:
library(data.table)
mydt <- data.table(foo=c(1,2), bar=c(2,3), baz=c(3,4))
有没有办法根据正则表达式使用数据表中的bar
和baz
列?我知道以下解决方案有效,但如果表格更大,我想选择更多变量,这很容易变得麻烦。
mydt[, .(bar, baz)]
我希望matches()
中有dplyr::select()
之类的内容,但仅供参考。
答案 0 :(得分:23)
您还可以尝试使用%like%
包中的data.table
,这是一个“调用regexpr的便捷函数”。但是,使代码更具可读性;)
在这种情况下,回答你的问题:
mydt[, .SD, .SDcols = names(mydt) %like% "bar|baz"]
当%like%
返回逻辑向量时,whe可以使用以下内容获取除“foo”之外的每一列:
mydt[, .SD, .SDcols = ! names(mydt) %like% "foo"]
其中!
否定逻辑向量。
答案 1 :(得分:12)
cols <- grep("<regex pattern>", names(mydt), value=T)
mydt[, cols, with=FALSE]
这取决于您的喜好和需求。如果您需要原始的原始数据,也可以将子集化表格分配给选定的变量。
答案 2 :(得分:11)
显然,从版本1.10.2开始,有一种新的方法可以实现这一点。
library(data.table)
cols <- grep("bar|baz", names(mydt), value = TRUE)
mydt[, ..cols]
似乎在发布的解决方案中运行速度最快。
# Creating a large data.table with 100k rows, 32 columns
n <- 100000
foo_cols <- paste0("foo", 1:30)
big_dt <- data.table(bar = rnorm(n), baz = rnorm(n))
big_dt[, (foo_cols) := rnorm(n)]
# Methods
subsetting <- function(dt) {
subset(dt, select = grep("bar|baz", names(dt)))
}
usingSD <- function(dt) {
dt[, .SD, .SDcols = names(dt) %like% "bar|baz"]
}
usingWith <- function(dt) {
cols <- grep("bar|baz", names(dt), value = TRUE)
dt[, cols, with = FALSE]
}
usingDotDot <- function(dt) {
cols <- grep("bar|baz", names(dt), value = TRUE)
dt[, ..cols]
}
# Benchmark
microbenchmark(
subsetting(big_dt), usingSD(big_dt), usingWith(big_dt), usingDotDot(big_dt),
times = 5000
)
#Unit: microseconds
# expr min lq mean median uq max neval
# subsetting(big_dt) 462.2 596.2 1383 680.0 1176.8 62292 5000
# usingSD(big_dt) 459.8 583.7 1279 669.5 1172.7 57934 5000
# usingWith(big_dt) 386.6 493.6 1209 572.6 1039.0 61313 5000
# usingDotDot(big_dt) 364.1 464.6 1063 538.1 945.5 67741 5000
答案 3 :(得分:6)
&#34; data.table&#34;还有一个subset
方法,因此您可以随时使用以下内容:
subset(mydt, select = grep("bar|baz", names(mydt)))
# bar baz
# 1: 2 3
# 2: 3 4
turns out为&#34; data.table&#34;创建startswith
类型的函数不是很直白。
答案 4 :(得分:2)
自brew upgrade php
(2019年1月)以来,您可以执行以下操作:
data.table v1.12.0
摘自官方文档mydt[, .SD, .SDcols = patterns("bar|baz")]
:
[...]您可以根据常规过滤列以包含在.SD中 通过.SDcols = patterns(regex1,regex2,...)的表达式。包含 列将是每个列所标识的列的交集 图案;模式联合可以很容易地用|指定在正则表达式中。您 也可以使用.SDcols =!patterns(...)像往常一样反转模式。
答案 5 :(得分:0)
我建议使用这种单行代码来提高可读性和性能。
mydt[,names(mydt) %like% "bar|baz", with=F]
@Janosdivenji的回答如下:
请参阅usingLike
在最后一行
Unit: microseconds
expr min lq mean median uq max neval
subsetting(big_dt) 370.582 977.2760 1194.875 1016.4340 1096.9285 25750.94 5000
usingSD(big_dt) 554.330 1084.8530 1352.039 1133.4575 1226.9060 189905.39 5000
usingWith(big_dt) 238.481 832.7505 1017.051 866.6515 927.8460 22717.83 5000
usingDotDot(big_dt) 256.005 844.8770 1101.543 878.9935 936.6040 181855.43 5000
usingPatterns(big_dt) 569.787 1128.0970 1411.510 1178.2895 1282.2265 177415.23 5000
usingLike(big_dt) 262.868 852.5805 1059.466 887.3455 948.6665 23971.70 5000