我使用以下习惯来有条件地从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中有条件地选择列?
我认为这个.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)
将执行所需的选择。在上一行中,您可以设置真向量和假向量的更复杂的构造(这可能会破坏保持简洁的目的)。