通过存储在向量中的数字索引从数据 table 中提取列

Extract columns from data table by numeric indices stored in a vector

我想从名为 dt

的数据 table 中提取第 4、5 和 6 列

以下方法有效:

    dt[, c(4,5,6)]

但以下不是:

    a = c(4,5,6)
    dt[, a]

事实上,第二种方法给我的结果是:

    4 5 6

谁能告诉我为什么会这样?这两种方法看起来和我一样。

我们可以在对象'a'前使用双点(..)来提取列

dt[, ..a]
#   col4 col5 col6
#1:    4    5    6
#2:    5    6    7
#3:    6    7    8
#4:    7    8    9

或者另一种选择是with = FALSE

dt[, a, with = FALSE]

数据

dt <- data.table(col1 = 1:4, col2 = 2:5, col3 = 3:6, col4 = 4:7, col5 = 5:8, col6 = 6:9)

@akrun 的回答为您提供了正确的选择。如果你想知道为什么需要它,这里有更详细的解释:

data.table 子集运算的工作方式,在大多数情况下,dt[i, j, by] 中没有 ibyj 表达式在中求值数据 table 的框架,并原样返回,无论它是否与括号外的数据 table 有任何关系。在 1.9.8 之前的版本中,您的第一个代码片段:dt[,c(4, 5, 6)] 的计算结果为数值向量 c(4, 5, 6),而不是第 4、5 和 6 列。这从 data.table v1.9.8 (released November 2016) 开始改变(向下滚动到 v.1.9.8 可能会破坏更改),因为不出所料,人们期望 dt[,c(4, 5, 6)] 给出第 4、5 和 6 列。现在,如果 j 表达式是变量名或数字,with 会自动设置为 FALSE。这有效地产生了类似于子集数据框的行为(不完全相同,但相似)。

所以你的第二个代码片段(其中 dt[, a] 计算为 a,而不是使用 a 对列进行子集化)实际上是默认的,第一个是特例.

为了说明此处奇怪但标准的行为,请尝试:

dt[, diag(5)]
#      [,1] [,2] [,3] [,4] [,5]
# [1,]    1    0    0    0    0
# [2,]    0    1    0    0    0
# [3,]    0    0    1    0    0
# [4,]    0    0    0    1    0
# [5,]    0    0    0    0    1

不管你的dt是什么,只要是data.table,它都会求值到5*5单位矩阵