基于regex选择data.table的列

基于regex选择data.table的列,regex,r,data.table,Regex,R,Data.table,如何基于正则表达式选择data.table的列? 考虑一个简单的例子如下: 库(data.table) mydt大卫的答案会奏效。但是,如果您的正则表达式很长,并且希望先完成,请尝试: cols <- grep("<regex pattern>", names(mydt), value=T) mydt[, cols, with=FALSE] cols还有一个用于“data.table”的subset方法,因此您可以始终使用如下内容: subset(mydt, select =

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

库(data.table)

mydt大卫的答案会奏效。但是,如果您的正则表达式很长,并且希望先完成,请尝试:

cols <- grep("<regex pattern>", names(mydt), value=T)
mydt[, cols, with=FALSE]

cols还有一个用于“data.table”的
subset
方法,因此您可以始终使用如下内容:

subset(mydt, select = grep("bar|baz", names(mydt)))
#    bar baz
# 1:   2   3
# 2:   3   4

为“data.table”创建一个
startswith
类型的函数不是很简单。

您也可以尝试使用
%like%
from
data.table
包,这是一个“调用regexpr的方便函数”。但是,这会使代码更具可读性;)

在这种情况下,回答您的问题:

mydt[, .SD, .SDcols = names(mydt) %like% "bar|baz"]
由于
%like%
返回一个逻辑向量,因此除了包含“foo”的列外,我们可以使用以下内容获取每一列:


其中
否定逻辑向量。

更新:我用@sindri_baldur的答案更新了比较-使用版本
1.12.6
。根据结果,
patterns()
是一个方便的快捷方式,但如果性能很重要,则应坚持使用
with=FALSE
解决方案(见下文)


显然,从版本1.10.2开始,有一种新的方法可以实现这一点

库(data.table)

cols由于
data.table v1.12.0
(2019年1月),您可以:

mydt[, .SD, .SDcols = patterns("bar|baz")]
从官方文件
?数据表

[…]您可以根据规则筛选要包含在.SD中的列 表达式via.SDcols=patterns(regex1,regex2,…)。包括 列将是每个列标识的列的交点 图案模式联合可以很容易地在正则表达式中用|指定。你 还可以使用.SDcols=,像往常一样反转模式!模式(…)


为了可读性和性能,我建议使用这种单行代码

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

你可以用=FALSE做
mydt[,grep(c(“bar”)和names(mydt))
但我认为
with
创建了一个副本。可能会有帮助:@DavidArenburg不认为它创建了副本。@nicola我记得Arun多次提到它,但从未检查过really@DavidArenburg,那将是非常奇怪的行为,没有?嗯,我想知道为什么OP更喜欢这个而不是
mydt[,grep(c(“bar | baz”),names(mydt)),with=FALSE]
@DavidArenburg,它稍微快一点?你测试过吗?这将是一个有趣的发现。我一生中从未使用过
subset
,但如果速度更快,我可能会给它一个机会。@Davidernburg,
traceem
不会用
显示任何副本。那么为什么它会比
subset
慢呢?从数据表:“当j是前缀为
的符号时。
将在调用范围中查找,其值将作为列名或数字。(…)想想上面的目录
在所有操作系统中,这意味着父目录(…)是实验性的。“Fwiw,我认为如果速度对这一点很重要,那么代码一定有一些组织问题。在我的系统上,一种糟糕但更快的方法:
微基准(bad=`noquote`(big_dt,names(big_dt)%like%“bar|baz”),good=big_dt[,.SD,.SDcols=name(big_dt)%like%“bar | baz”])
Similar
setDT(as.list(big_dt)[name(big_dt)%like%“bar | baz”])
你忘记了最后一个,在微基准测试中使用模式:)谢谢@emilBeBri,它只包含在结果中。我更新了代码。谢谢,这确实是data.table期待已久的功能。我用它更新了我的基准测试。它似乎工作较慢,但在许多情况下,它根本不重要。这与使用W的
相同ith
解决方案-对于问题,如果使用
%like%
grep()选择
col
,则与此无关
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