我希望通过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 notes in an answer您可以使用此构造,但必须将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]
答案 0 :(得分:3)
虽然@Ricardo是正确的,在包装器中包装依赖于方法分派的原语或函数更安全,但我们可以通过为environment
设置正确的get
来避免这种情况。使用lapply
的诀窍是使用sys.parent(n)
(在这种情况下n = 0
将起作用)以获得适当的调用环境。
test.table[,lapply(grep('a',names(test.table),value=TRUE),
get, envir = sys.parent(0))]
(更多信息可在此处找到Using get inside lapply, inside a function)
答案 1 :(得分: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的方法分派。
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>
答案 2 :(得分:-1)
这只是因为data.table评估j() expression
(简单来说,DT[,...])
中第一个逗号之后的所有内容都是实际表达式。所以DT[,"Column1"]
返回"Column1"
,就像with(DT, "Column1")
返回"Column1"
一样。它位于数据表常见问题中。
如果您愿意,可以这样做:
DT[,names(test.table),with=F]