我想创建一个函数“ startswith”,该函数将在data.table的方括号内使用。它应返回一个字符向量,该向量包含以提供的字符开头的列名。例如
DT <- data.table(x=1, y=2, z1=1, z2=2)
# the syntax DT[, startswith("z")] is equivalent to
DT[, .(z1, z2)]
# returns
z1 z2
1: 1 2
我熟悉grep来搜索文本表达式,但是很难找到一种方法来从方括号内引用DT的列名。我尝试的一种解决方案是使用ls()和与DT相关的环境来列出DT中的所有列,但是我还没有找到一种方法来从方括号内引用此环境。
目标是为grep创建一个包装程序,以用作便利功能。我不想在括号内指定DT。
最佳答案
当然,还有一种更惯用的方法,但这就是我想出的:
startswith <- function(pattern = "z") {
re <- paste0("^", pattern)
call_info <- deparse(sys.calls()[[1]])
if (grepl("(^.+\\()(.+)(\\)$)",call_info)) {
this_name <- sub("(^.+\\()(.+)(\\)$)","\\2",call_info)
} else {
this_name <- strsplit(call_info,"\\[")[[1]][1]
}
this <- copy(get(this_name))
this_names <- names(this)
eval.parent(grep(re,this_names))
}
library(data.table)
DT <- data.table(x=1, y=2, z1=1, z2=2)
##
R> DT[,.(z1, z2)]
z1 z2
1: 1 2
##
R> DT[,startswith(), with=F]
z1 z2
1: 1 2
我必须添加该
if () {} else {}
块,以便可以在函数内部使用,例如Foo <- function(gt) {
f <- gt[,startswith(),with=F]
# {do something interesting with f}
f
}
##
R> Foo(DT)
z1 z2
1: 1 2
我认为这是一个有趣的问题-就我所知,R没有类似the
this
pointer in C++这样的概念,但是在这样的情况下它肯定会有用。本质上,我所有带有sys.call
,get
等的黑客程序都是为了让我可以检索调用对象的名称。关于regex - 从括号内引用data.table列名,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/29435337/