R 从data.table中有条件地选择列的习惯用法

R 从data.table中有条件地选择列的习惯用法,r,data.table,R,Data.table,我使用以下习惯用法有条件地从 data.frame: DF = data.frame(a = 1:3,b = letters[1:3],c = LETTERS[1:3]) someCondition <- FALSE # use `if(someCondition)` to conditionally include column 'c' DF[,c('a','b',if(someCondition)'c')] :> a b :> 1 1 a :> 2 2 b :

我使用以下习惯用法有条件地从 data.frame:

DF = data.frame(a = 1:3,b = letters[1:3],c = LETTERS[1:3])
someCondition <- FALSE

# use `if(someCondition)` to conditionally include column 'c'
DF[,c('a','b',if(someCondition)'c')] 
:>   a b
:> 1 1 a
:> 2 2 b
:> 3 3 c
我定义了一个名为
的函数,这是一个解决方法:

.. <- function(...){
    x = list(...)
    x= x[!sapply(x,is.null)]
    x
}
DT[,..(a,b,if(someCondition)c)]
:>    V1 V2
:> 1:  1  a
:> 2:  2  b
:> 3:  3  c
。。V1 V2
:>1:1 a
:>2:2b
:>3:3 c

但它寻求一种笨拙的方式,必须包括我自己的功能来完成一个如此常见的操作。是否有一种更惯用的方法可以有条件地从data.table中选择列?

我认为
.SDcols
参数可以满足您的需要。在上面的data.table DF示例中

DF[, .SD, .SDcols= c("a","b", if(someCondition) "c")]
将以与data.frame中相同的方式运行。您也可以在下面的示例中实现这一点

DF[, .SD, .SDcols=if(someCondition) c("a","b","c") else c("a","b")]

将执行所需的选择。在前一行中,您可以设置更精细的真向量和假向量构造(这可能会破坏保持事物简洁的目的)。

`[.noquote`(DT,c('a','b',if(someCondition)'c'))
DT[,c('a','b',if(someCondition)'c'),with=false]
如果您不能欣赏
[.noquote
。不确定为什么会标记为重复。。请提交一份错误报告。@Arun我不知道它是否应该工作。
j
中的列表是否会通过删除空元素而表现出与其他列表不同的行为?(我正在查看
列表(“a”,“b”,if(FALSE)“c”)
)似乎它可能会导致其他用例中的意外行为(我想不起来…)。无论如何,我看到Jason已经发布了错误报告,所以如果我想更多的话,我会在那里讨论。这里没有什么不同。空元素可以/应该被忽略。它已经发生在
DT[,if(condition).SD,by=。]
,例如。在意外情况下,我们有一些测试来捕捉这些情况。如果它们出现,我们会解决它。@Arun——这绝对是关键点。还值得提醒人们,
with=FALSE
替代方法确实不能替代
with=TRUE
。像这样简单的方法当然失败了:
DT[,c(3*'a',2*'b',if(someCondition)'c'),with=FALSE]
(为了记录在案,如果这对任何人都重要,我是撤销关闭的人。)
DF[, .SD, .SDcols=if(someCondition) c("a","b","c") else c("a","b")]