当x也是数据表中的列时,get(x)在R data.table中不起作用

use*_*742 6 r data.table

我注意到当x也是同一数据表中的一列时,get(x)在R数据表中不起作用.请参阅下面的代码段.在编写以数据表作为输入的R函数时,这很难完全避免.这是R data.table包中的错误吗?谢谢!

library(data.table)

dt = data.table(x=1:3, y=2:4)

var = 'y'
x = 'y'

dt[, 3*get(var)]      # [1] 6 9 12
dt[, 3*get(x)]        # Error in get(x): invalid first argument
Run Code Online (Sandbox Code Playgroud)

Bob*_*Bob 7

一般情况下,当列和变量之间存在命名冲突时,列优先。从 data.table 的 v1.10.2(2017 年 1 月 31 日)开始,澄清名称不是列名的首选方法是使用..前缀 [ 1 ]:

当 j 是一个以..它为前缀的符号时,将在调用范围内查找,其值被视为列名或数字。当您看到..前缀时,请认为上一级,就像..所有操作系统中的目录都表示父目录一样。将来,..可以使前缀适用于在 内部任何地方出现的所有符号DT[...]。...

我们认为我们在这里..实现的主要重点是解决var在调用范围内并且var也是列名时更常见的歧义。此外,我们没有忘记,过去我们建议在调用范围时为变量加上..你自己的前缀。如果您这样做并且..var存在于调用范围中,那么它仍然有效,前提是既不var存在于调用范围中也不..var作为列名存在。现在请删除调用范围中的..前缀..var以进行整理。将来 data.table 将开始对此类使用发出警告/错误。

在您的情况下,您可以get(..x)强制x在调用范围内而不是在 data.table 环境中解析名称:

library(data.table)

dt = data.table(x=1:3, y=2:4)

var = 'y'
x = 'y'

dt[, 3*get(var)]      # [1] 6 9 12
dt[, 3*get(x)]        # Error in get(x): invalid first argument
dt[, 3*get(..x)]      # [1]  6  9 12
Run Code Online (Sandbox Code Playgroud)

该..前缀仍处于试验阶段,因此文档有限,但在帮助页面上简要提到了以下内容data.table:

默认情况下with=TRUE,j在x;的框架内进行评估。列名可以用作变量。如果数据集和父范围内的变量名称重叠,您可以使用双点前缀..cols显式引用 'cols变量父范围,而不是来自您的数据集。

这不是一个错误,而是with = T允许在数据环境中使用列作为变量的不幸但自然的结果。实际上,您可以通过使用 的posorenvir参数以更基本的 R 方式避免此问题get()。


小智 -2

这是来自函数中第一个参数的 R 文档get:“对象名称(以字符串形式给出)”。

所以dt[, 3*get("x")]应该有效。

  • 我认为重点是 OP 定义了 `x = 'y'` 就像他定义了 `var = 'y'` 一样。他期望与“dt[, 3*get(var)]”得到相同的结果,但这个建议给出了不同的答案。 (4认同)