假设我有以下数据dt和列名向量cols
dt <- data.table(id = letters[1:10], amount = 1:10, id2 = c(rep('a',5),rep('b',5)))
cols <- 'id'
Run Code Online (Sandbox Code Playgroud)
有人可以帮助我理解为什么这种方法不起作用
dt[cols=='a']
Run Code Online (Sandbox Code Playgroud)
但这有效吗?
dt[get(cols)=='a']
Run Code Online (Sandbox Code Playgroud)
两种方法不应在vec?中返回相同的内容。
Akrun已经为您的问题提供了有用的解决方案,因此我将提供诊断。
data.tabledt要按照您的意图进行过滤,data.table需要一个由十个值组成的完整向量,对应于 中的十行,以指示要保留哪些行 ( ) 以及要丢弃哪些行 ( )。因此,当您过滤 时,您必须在括号内包含这样一个逻辑向量(或对其求值的东西)。这是一个人为的例子: logicaldtTRUEFALSEdt[
dt[c(TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE)]
Run Code Online (Sandbox Code Playgroud)
这将为我们提供以下过滤结果data.table:
id amount id2
1: a 1 a
2: d 4 a
3: e 5 a
4: g 7 b
Run Code Online (Sandbox Code Playgroud)
cols失败由于cols有一个character值为'id'
cols <- 'id'
Run Code Online (Sandbox Code Playgroud)
那么比较cols == 'a'与比较是一样的'id' == 'a',这显然是FALSE:
dt[cols == 'a']
# ...is the same as...
dt['id' == 'a']
# ...is the same as...
dt[FALSE]
Run Code Online (Sandbox Code Playgroud)
这仅提供单个 logical值 ( FALSE),而不是过滤真正需要的十个值的向量。 logicaldata.table
结果是data.table省略了所有内容
Empty data.table (0 rows and 3 cols): id,amount,id2
Run Code Online (Sandbox Code Playgroud)
与 相比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
Run Code Online (Sandbox Code Playgroud)
get(cols)有效当您使用 时,您是在告诉 R从周围环境中get('my_variable')“获取” 的值。my_variable如果您get()在[以下操作中运行dt
dt[get(# ...
]
Run Code Online (Sandbox Code Playgroud)
R 将按dt给定名称在其中搜索列,并将返回该列(向量)作为 的值get()。因此,在这种情况下使用将为您提供中get('id')的列,它是向量iddt
c('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j')
# [1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j"
Run Code Online (Sandbox Code Playgroud)
现在我们把它们放在一起:
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)]
Run Code Online (Sandbox Code Playgroud)
这为我们提供了以下过滤结果data.table:
id amount id2
1: a 1 a
Run Code Online (Sandbox Code Playgroud)