3

我希望通过类或常见模式匹配等标准来处理列grep

我的第一次尝试没有奏效:

require(data.table)
test.table <- data.table(a=1:10,ab=1:10,b=101:110)
##this does not work and hangs on my machine
test.table[,lapply(names(test.table)[grep("a",names(test.table))], get)]

Ricardo Saporta 在回答中指出您可以使用此构造,但您必须包装get一个虚拟函数:

##this works
test.table[,lapply(names(test.table)[grep("a",names(test.table))], function(x) get(x))]

为什么需要匿名函数?

(首选/更清洁的方法是通过.SDcols:)

test.table[,.SD,.SDcols=grep("a",names(test.table))]
test.table[, grep("a", names(test.table), with = FALSE]
4

3 回答 3

3

虽然@Ricardo 是正确的,将依赖于方法分派的原语或函数包装在包装器中更安全,但在这里我们可以通过设置正确environmentget搜索对象来避免这种情况。诀窍lapply 是使用sys.parent(n)(在这种情况下n = 0会起作用)来获得适当的调用环境。

test.table[,lapply(grep('a',names(test.table),value=TRUE), 
                    get, envir = sys.parent(0))]

(更多信息可以在这里找到使用 get inside lapply, inside a function

于 2013-08-05T23:31:42.607 回答
2

这是 的功能lapply,不是真的data.table 来自lapply文档:

由于历史原因,由 lapply 创建的调用未被评估,并且已经编写了依赖于此的代码(例如 bquote)。这意味着录制的呼叫始终采用 FUN(X[[0L]], ...) 的形式,其中 0L 替换为当前整数索引。这通常不是问题,但如果 FUN 使用 sys.call 或 match.call 或者它是使用调用的原始函数,则可能会出现问题。这意味着使用包装器调用原始函数通常更安全,因此在 R 2.7.1 中需要例如 lapply(ll, function(x) is.numeric(x)) 以确保 is.numeric 的方法调度发生正确。

更新@Hadley 和@DWin 的评论:

EE <- new.env()
EE$var1 <- "I am var1 in EE"
EE$var2 <- "I am var2 in EE"

## Calling get directly
with(EE, lapply(c("var1", "var2"), get))
Error in FUN(c("var1", "var2")[[1L]], ...) : object 'var1' not found

## Calling get via an anonymous function
with(EE, lapply(c("var1", "var2"), function(x) get(x)))
[[1]]
[1] "I am var1 in EE"

[[2]]
[1] "I am var2 in EE"

with(EE, lapply(c("var1", "var2"), rm))
Error in FUN(c("var1", "var2")[[1L]], ...) : 
  ... must contain names or character strings

with(EE, lapply(c("var1", "var2"), function(x) rm(x)))
[[1]]
NULL

[[2]]
NULL

# var1 & var2 have now been removed
EE
<environment: 0x1154d0060>
于 2013-08-05T18:42:26.983 回答
-1

只是因为 data.table 计算j() expression(简单来说,第一个逗号后面的所有内容都是DT[,...])一个实际的表达式。所以DT[,"Column1"]返回"Column1",就像with(DT, "Column1")返回一样"Column1"。它在数据表常见问题解答中。

如果你愿意,你可以这样做:

DT[,names(test.table),with=F]
于 2013-08-05T18:05:42.360 回答