基于regex选择data.table的列
如何基于正则表达式选择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)
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%
fromdata.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”])
SimilarsetDT(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