Data.Table 对象在函数中分配了 := 未打印

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

提问人:janosdivenyi 提问时间:10/7/2015 最后编辑:smcijanosdivenyi 更新时间:5/7/2023 访问量:3305

问:

我想修改一个函数。如果我在函数中使用该功能,则仅在第二次调用时打印结果。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 

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

r 函数 data.table 赋值运算符

评论


答:

55赞 janosdivenyi 10/7/2015 #1

在 1.9.6 版本中修复了一个错误,该错误引入了此缺点(请参阅 NEWS 1.9.6,错误修复 #1)。

应该在函数末尾调用以防止这种行为。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 

这在 data.table FAQ 2.23 中有所描述:

为什么在使用后有时必须键入两次才能将结果打印到控制台?DT:=

这是让 #869 工作的一个不幸的缺点。如果在函数结束前在函数中使用 a,则在函数结束前没有,则下次在提示符下键入时,将不打印任何内容。重复将打印。为避免这种情况:在函数中包含 after the last。如果这是不可能的(例如,它不是您可以更改的功能),那么在提示符下保证打印。和以前一样,在查询末尾添加额外的是建议更新然后打印的习惯用语;例如> .:=DT[]DTDTDT[]:=print(DT)DT[][]:=DT[,foo:=3L][]

评论

9赞 jangorecki 10/7/2015
DT[]仅当 data.table 的打印被禁止时才需要,因此当使用 OR 函数时:=set*
-3赞 Paul 3/20/2017 #2

很抱歉,如果我不应该在这里发布一些不是 回答,但我的帖子太长了,无法发表评论。

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

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

第一个示例表明,在没有尾随的情况下,我们得到 在函数的最后一行时的预期行为[]dtdt

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

添加尾随 on 会产生意外行为[]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

移动到没有尾随的 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  # 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

评论

4赞 Frank 3/20/2017
我认为您在一定程度上混淆了函数的工作原理。所有函数都返回一个值。如果不编写显式语句,则返回函数中的最后一个值。 返回值 invisiblyDT[, x := y][]' 返回 , printed。return(x)df <- 11, while DT
2赞 Paul 3/22/2017
谢谢你的解释。我没有意识到。我想是“无形的回归”吸引了我。我也对数据表的“引用复制”方面感到困惑。我花了很长时间玩弄这些例子,试图理解它们。你现在明白为什么我不在这个论坛上回答问题了:-)