假设我有以下数据dt
和列名称的向量cols
dt <- data.table(id = letters[1:10], amount = 1:10, id2 = c(rep('a',5),rep('b',5)))
cols <- 'id'
谁能帮我理解为什么这个方法不起作用
dt[cols=='a']
但是这个可以吗?
dt[get(cols)=='a']
两种方法不应该在vec
中返回相同的东西?
Akrun已经提供了一个有用的解决方案,所以我将提供诊断.
过滤data.table
按照您的意愿过滤dt
,data.table
需要一个整个向量十的logical
值,对应于dt
中的10行,用于指示保留哪些行(TRUE
)和丢弃哪些行(FALSE
)。因此,当您过滤dt
时,必须在[
括号中包含这样一个逻辑向量(或求值为它的东西)。下面是一个人为的例子:
dt[c(TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE)]
这将为我们提供以下data.table
中的过滤结果:
id amount id2
1: a 1 a
2: d 4 a
3: e 5 a
4: g 7 b
cols
为什么失败
由于cols
的character
值为'id'
cols <- 'id'
那么比较cols == 'a'
和比较'id' == 'a'
是一样的,显然是FALSE
:
dt[cols == 'a']
# ...is the same as...
dt['id' == 'a']
# ...is the same as...
dt[FALSE]
这只提供了一个单个 。结果是 与 当你使用 R将根据给定名称在 现在我们把它们放在一起: 这给了我们以下logical
值(FALSE
),而不是data.table
真正需要的十个logical
值的向量data.table
省略了所有Empty data.table (0 rows and 3 cols): id,amount,id2
dt[TRUE]
相反,包含所有内容:id amount id2
1: a 1 a
2: b 2 a
3: c 3 a
4: d 4 a
5: e 5 a
6: f 6 b
7: g 7 b
8: h 8 b
9: i 9 b
10: j 10 b
get(cols)
为什么有效get('my_variable')
时,你告诉R "get"从周围环境中获取my_variable
的值。如果在dt
上的[
操作中运行get()
dt[get(# ...
]
dt
中搜索列,并返回该列(一个向量)作为get()
的值。因此,在此上下文中使用get('id')
将在dt
中得到id
列,这是向量c('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j')
# [1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j"
dt[get(cols) == 'a')
# ...is the same as...
dt[get('id') == 'a')
# ...is the same as...
dt[c('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j') == 'a']
# ...is the same as...
dt[c(TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE)]
data.table
中过滤的结果:id amount id2
1: a 1 a
我们可以在sym
bol上使用eval
dt[eval(as.name(cols)) == 'a']
id amount id2
1: a 1 a
或者指定.SDcols
dt[dt[, .SD[[1]] == 'a', .SDcols = cols]]
id amount id2
1: a 1 a
或直接子集.SD
,如果只有一个列
dt[dt[, .SD[[cols]] == 'a']]
id amount id2
1: a 1 a
首选的方法是通过.SDcols
,因为get
有时会有环境问题,而eval
(不被社区推荐)