data.table 未打印在函数内分配了 := 的对象

data.table objects assigned with := from within function not printed

我想在函数中修改 data.table。如果我在函数中使用 := 功能,结果只会在第二次调用时打印出来。

看下图:

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

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

当我只调用该函数时,不会打印 table(这是标准行为。但是,如果我将返回的 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 

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

作为David Arenburg mentions in a , the answer can be found 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 

对不起,如果我不应该post这里不是 回答,但是我的 post 太长了,无法发表评论。

我想指出 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