32

我想打印数据表的所有列,dt除了其中一个被命名V3但不想按数字而是按名称引用它。这是我拥有的代码:

  dt = data.table(matrix(sample(c(0,1),5,rep=T),50,10))
  dt[,-3,with=FALSE]   #  Is this the only way to not print column "V3"? 

使用这种data frame方式,可以通过代码做到这一点:

  df = data.frame(matrix(sample(c(0,1),5,rep=T),50,10))
  df[,!(colnames(df)%in% c("X3"))]

所以,我的问题是:是否有另一种方法可以不打印数据表中的一列而无需按数字引用它?我想找到类似于我上面使用的数据框语法但使用数据表的东西。

4

5 回答 5

48

使用与 a 非常相似的语法data.frame,但添加参数with=FALSE

dt[, setdiff(colnames(dt),"V9"), with=FALSE]
    V1 V2 V3 V4 V5 V6 V7 V8 V10
 1:  1  1  1  1  1  1  1  1   1
 2:  0  0  0  0  0  0  0  0   0
 3:  1  1  1  1  1  1  1  1   1
 4:  0  0  0  0  0  0  0  0   0
 5:  0  0  0  0  0  0  0  0   0
 6:  1  1  1  1  1  1  1  1   1

的使用在参数with=FALSE的文档中得到了很好的解释:j?data.table

j:单个列名、单个列名list()表达式、列名表达式、计算结果为 list 的表达式或函数调用(也包括列表data.framedata.table列表),或with=FALSE与 j in 相同的(何时)[.data.frame


v1.10.2开始,也可以按如下方式执行此操作:

keep <- setdiff(names(dt), "V9")
dt[, ..keep]

前缀符号..将在调用范围(即全局环境)中查找,其值被视为列名或数字(source)。

于 2012-08-13T19:09:20.830 回答
14

使用更现代的方法编辑 2019-09-27

您可以patterns按照上述方法执行此操作;或者,!如果已经有名称向量,您可以这样做:

dt[ , !'V3']
# or
drop_cols = 'V3'
dt[ , !..drop_cols]

..意思是“向上一层”


旧版本使用with=FALSE(data.table正在稳步远离这个论点)

这是一种grep用于转换为数字并允许负列索引的方法:

dt[, -grep("^V3$", names(dt)), with=FALSE]

您确实说过要排除“ V3”,对吗?

于 2012-08-13T19:30:30.627 回答
13

也许它只在最新版本的 data.table 中(我使用的是 1.9.6),但你可以这样做:

dt[, -'V3']

对于几列:

dt[, -c('V3', 'V9')]

请注意,变量名称周围的引号是必要的。此外,如果您的列名存储在变量中,例如cols,您需要执行dt[, -cols, with=FALSE].

于 2016-02-11T22:25:23.260 回答
5

从 1.12.0 版本开始,还可以在名称上使用正则表达式来选择列:

iris_DT <- as.data.table(iris)

iris_DT[, .SD, .SDcols = patterns(".e.al")]
于 2019-01-17T07:23:00.907 回答
-1

总结这个问题的答案,并使其
a)否定友好(这样您也可以通过否定选择列),
b)管道友好(以便您可以在具有 %>% 运算符的管道中使用) 和
c) 以便您可以同时使用列号和列名进行选择,这些是可用选项:

library(data.table);

select1 <- function (dt, range)  dt[, range, with=F]
select2 <- function (dt, range)  dt[, ..range]
select3 <- function (dt, range)  dt[, .SD, .SDcols=range] 

dt <- ggplot2::diamonds

range <- 1:3 # or 
range <- dt %>% names %>% .[1:3]

dt %>% select1(range);
dt %>% select2(range); 
dt %>% select3(range); 

dt %>% select1(-range);
dt %>% select2(-range); 
dt %>% select3(-range); # DOES NOT WORK

Also we note that this
dt %>% .[, ..(names(dt)[1:3])] # DOES NOT WORK

因此,选择多个列的最佳(最通用和快速)方法data.table如下:

# columns are selected using column numbers:
range <- 1:3
dt %>% select1(range); 
dt %>% .[, range, with=F]

# The same works if columns are selected using column names:
range <- names(dt) [1:3]
dt %>% select1(range); 
dt %>% .[, range, with=F]

PS。如果不是选择多个列,而是希望通过引用有效地从 data.table 中删除多个列(即,而不是复制整个 data.table),那么您可以使用 data.table 的:=运算符。但我不知道如何对一行中的多个列执行此操作

于 2021-12-04T17:10:34.127 回答