指定了:= from within函数的数据表对象未打印

bfhwhh0e  于 2023-05-11  发布在  其他
关注(0)|答案(2)|浏览(96)

我想在一个函数中修改一个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

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

fdbelqdn

fdbelqdn1#

在版本1.9.6中修复了一个错误,该错误引入了此缺点(请参阅新闻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工作的一个不幸的缺点。如果:=在函数内使用,而在函数结束之前没有DT[],则下次在提示符下键入DT时,将不会打印任何内容。将打印重复的DT。要避免这种情况:在函数中的最后一个:=之后包含DT[]。如果这是不可能的(例如,它不是一个你可以改变的函数),那么print(DT)DT[]在提示符下保证打印。和前面一样,在:=查询的末尾添加一个额外的[]是一个推荐的更新然后打印的习惯用法;例如> DT[,foo:=3L][]

nvbavucw

nvbavucw2#

我很抱歉,如果我不应该在这里张贴的东西,这不是一个答案,但我的职位是太长的评论。
我想指出的是,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

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  # Content printed as desired
##    x y z
## 1: 1 5 4
## 2: 2 6 4
## 3: 3 7 4

相关问题