成语用于有条件地从data.table中选择列

Jth*_*rpe 9 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
:> 3 3 c
Run Code Online (Sandbox Code Playgroud)

但是等价物不适用于data.table的b/c NULL值不会从列表中删除,就像它们从连接中删除一样:

DT = as.data.table(DF)
DT[,.(a,b,if(someCondition)c)]
:> Error in setnames(jval, jvnames) : 
:>   Can't assign 3 names to a 2 column data.table
Run Code Online (Sandbox Code Playgroud)

我已经定义了一个函数..,它是一个解决方法:

.. <- 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
Run Code Online (Sandbox Code Playgroud)

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

lmo*_*lmo 4

我认为这个.SDcols论点符合你的要求。在上面的 data.table DF 示例中,

DF[, .SD, .SDcols= c("a","b", if(someCondition) "c")]
Run Code Online (Sandbox Code Playgroud)

其行为方式与您的 data.frame 中的行为方式相同。您也可以按照下面的示例来实现。

DF[, .SD, .SDcols=if(someCondition) c("a","b","c") else c("a","b")]
Run Code Online (Sandbox Code Playgroud)

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