根据正则表达式选择data.table列

时间:2015-05-12 11:48:26

标签: regex r data.table

如何根据正则表达式选择data.table的列? 考虑一个简单的例子如下:

library(data.table)
mydt <- data.table(foo=c(1,2), bar=c(2,3), baz=c(3,4))

有没有办法根据正则表达式使用数据表中的barbaz列?我知道以下解决方案有效,但如果表格更大,我想选择更多变量,这很容易变得麻烦。

mydt[, .(bar, baz)]

我希望matches()中有dplyr::select()之类的内容,但仅供参考。

6 个答案:

答案 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