从括号内引用data.table列名

时间:2015-04-03 15:43:12

标签: regex r data.table

我想创建一个功能" startwith'在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。

2 个答案:

答案 0 :(得分:4)

当然有更惯用的方法,但这就是我提出的方法:

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.callget等的所有hackery都是如此......我只能检索调用对象的名称。

答案 1 :(得分:1)

你可以这样做,

> DT <- data.table(x=1, y=2, z1=1, z2=2)
> DT[, grepl("^z", colnames(DT)), with=FALSE]
   z1 z2
1:  1  2