【问题标题】:Adding to columns the correct way以正确的方式添加到列
【发布时间】:2019-04-19 14:27:53
【问题描述】:

我有一个简单的 DT,我想在其余部分添加一列。代码如下:(有效)

x <- data.table(a=1:5,b=5:1,c=rep(999,5))
for(k in c("a","b")){x[,k] <- x[,..k]+x[,.(c)]}

现在的问题是:为什么我必须使用.. 进行分配?此外,如果我尝试在第一种情况下使用 ..,即

for(k in c("a","b")){x[,..k] <- x[,..k]+x[,.(c)]}

有一个错误:“[...]object '..k' not found”。这似乎很奇怪,我必须在范围内更改语法。

现在在dataframe,等价的表述很清楚了:

for(k in c("a","b")){x[,k] <- x[,k]+x[,c]} # error with DT
x <- data.frame(a=1:5,b=5:1,c=rep(999,5))
for(k in c("a","b")){x[,k] <- x[,k]+x[,"c"]} # works with dataframe

所以我想知道(1)上述代码是否是在datatable 中执行此操作的正确方法(请解释.. 运算符,数据表FAQ 1.1 没有特别解决这个问题);如果(2)有其他方法可以以更简洁的方式编写它。感谢您的任何提示。

【问题讨论】:

  • data.table 中,x[,k] 查找名为k 的列,无论k 是否在调用范围内都是变量。如果您定义 k&lt;-"a" 并使用 x[,k] 您真的想要 x[,"a"](如 data.frame),您需要 data.table 中的 x[,..k]x[,k,with=FALSE] 也可以在 data.table 中使用。
  • 感谢@nicola 的解释。然而,这似乎只适用于循环中赋值的右侧,而不适用于左侧。
  • data.table 中,您不会使用&lt;- 修改列,因此分配是data.frame 方法。你使用:=(见?set)。例如在这里,你应该使用for(k in c("a","b")) x[,(k):=get(k)+c]

标签: r datatable


【解决方案1】:

来自官方introducion(为您的示例稍作编辑):

对于那些熟悉 Unix 终端的人来说,.. 前缀应该是 让人想起“up-one-level”命令,类似于 这里发生了什么 - .. 向 data.table 发出信号以查找 k 变量“上一级”,即在循环环境中 在这种情况下。

所以这个操作符会转义数据框并在更高级别中查找 k 变量,获取值并返回。不知道他们为什么这样做,但也许变量没有被转移。

你也可以使用 with 参数:

x[,k,with=FALSE]


编辑:

我刚刚查看了data.table的源代码。他们从parent.frame() 获取被调用的变量,因此是调用函数的环境。这是由..with 参数触发的。所以如果你不使用它,该函数是无法获取环境的参数的。

一个关于parent.frame()的问题被发现here

【讨论】:

  • 谢谢,它清楚地说明了它是如何工作的。只有一件事:您知道为什么以下内容:for(k in c("a","b")){x[,..k] &lt;- x[,..k]+x[,.(c)]} 不适用于数据表吗?也就是说,在分配的左侧也使用..。这是上述问题的一部分。
  • @Talik3233 不抱歉。源代码中的注释暗示开发人员知道这一点。以下也可能是完全错误的:我认为不同之处在于编写变量。当您将变量分配给数据框时,您必须以某种方式保存它。我认为临时空间内部发生了一些事情。但我不能确切地告诉你是什么。这只是我从线索和错误消息中想到的。结论:如果你想读或写你的数据表是不同的
  • 谢谢,所以这个问题是有道理的。毕竟很高兴知道:)
  • 它不适用于左侧,因为这是data.frame 方法,在data.table 中,您可以通过:= 引用更改列。
猜你喜欢
  • 2014-01-19
  • 1970-01-01
  • 2020-09-01
  • 1970-01-01
  • 2020-03-31
  • 1970-01-01
  • 2023-03-07
  • 2019-11-08
  • 2015-09-23
相关资源
最近更新 更多