data.table对象分配有:=来自未打印的函数内

时间:2015-10-07 09:05:30

标签: r function data.table assignment-operator

我想在函数中修改data.table。如果我在函数中使用:=功能,则仅为第二次调用打印结果。

请看下图:

library(data.table)
mydt <- data.table(x = 1:3, y = 5:7)

myfunction <- function(dt) {
    dt[, z := y - x]
    dt
}

当我只调用该函数时,不打印该表(这是标准行为。但是,如果我将返回的data.table保存到新对象中,则不会在第一次调用时打印它,仅用于第二个。

myfunction(mydt)  # nothing is printed   
result <- myfunction(mydt) 
result  # nothing is printed
result  # for the second time, the result is printed
mydt                                                                     
#    x y z
# 1: 1 5 4
# 2: 2 6 4
# 3: 3 7 4 

你能解释为什么会发生这种情况以及如何预防吗?

2 个答案:

答案 0 :(得分:37)

David Arenburg中提及comment时,可以找到答案here。版本1.9.6中修复了一个错误,但修复程序引入了这个缺点。

应该在函数末尾调用DT[]以防止此行为。

myfunction <- function(dt) {
    dt[, z := y - x][]
}
myfunction(mydt)  # prints immediately
#    x y z
# 1: 1 5 4
# 2: 2 6 4
# 3: 3 7 4 

答案 1 :(得分:0)

对不起,如果我不想在这里发帖,那不是 回答,但我的帖子太长了,无法发表评论。

我想指出janosdivenyi添加的解决方案 尾随[]dt并不总能给出预期的结果(甚至 当我使用data.table 1.9.6或1.10.4时,如下所示。

以下示例显示如果dt是函数中的最后一行 一个人在没有存在的情况下获得所需的行为 尾随[],但如果dt不在函数的最后一行 需要尾随[]才能获得所需的行为。

第一个示例显示,[]上没有尾随dt,我们得到了 当dt位于函数的最后一行时的预期行为

mydt <- data.table(x = 1:3, y = 5:7)

myfunction <- function(dt) {
  df <- 1
  dt[, z := y - x]
}

myfunction(mydt)  # Nothing printed as expected

mydt  # Content printed as desired
##    x y z
## 1: 1 5 4
## 2: 2 6 4
## 3: 3 7 4

[]上添加尾随dt会产生意外行为

mydt <- data.table(x = 1:3, y = 5:7)

myfunction <- function(dt) {
  df <- 1
  dt[, z := y - x][]
}

myfunction(mydt)  # Content printed unexpectedly
##    x y z
## 1: 1 5 4
## 2: 2 6 4
## 3: 3 7 4

mydt  # Content printed as desired
##    x y z
## 1: 1 5 4
## 2: 2 6 4
## 3: 3 7 4

df <- 1移至dt后没有尾随[]会产生意外情况 行为

mydt <- data.table(x = 1:3, y = 5:7)

myfunction <- function(dt) {
  dt[, z := y - x]
  df <- 1
}

myfunction(mydt)  # Nothing printed as expected

mydt  # Nothing printed unexpectedly

在dt之后移动df <- 1并使用尾随[]给出预期值 行为

mydt <- data.table(x = 1:3, y = 5:7)

myfunction <- function(dt) {
  dt[, z := y - x][]
  df <- 1
}

myfunction(mydt)  # Nothing printed as expected

mydt  # Content printed as desired
##    x y z
## 1: 1 5 4
## 2: 2 6 4
## 3: 3 7 4