【问题标题】:how to suppress output when using `:=` in R {data.table}, prior to v1.8.3?在 v1.8.3 之前,在 R {data.table} 中使用 `:=` 时如何抑制输出?
【发布时间】:2012-07-06 18:08:48
【问题描述】:

有没有办法防止data.table在通过引用分配新列后打印新的data.table?我收集的标准行为是

library(data.table)
example(data.table)
DT
#    x y  v
# 1: a 1 42
# 2: a 3 42
# 3: a 6 42
# 4: b 1 11
# 5: b 3 11
# 6: b 6 11
# 7: c 1  7
# 8: c 3  8
# 9: c 6  9

DT[,z:=1:nrow(DT)]

#    x y  v z
# 1: a 1 42 1
# 2: a 3 42 2
# 3: a 6 42 3
# 4: b 1 11 4
# 5: b 3 11 5
# 6: b 6 11 6
# 7: c 1  7 7
# 8: c 3  8 8
# 9: c 6  9 9

即分配后表格打印到屏幕上。有没有办法在分配新列 z 后阻止 data.table 显示新表?我知道我可以通过说来阻止这种行为

DT <- copy(DT[,z:=1:nrow(DT)])

但这违背了:= 的目的(旨在避免复制)。

【问题讨论】:

    标签: r data.table


    【解决方案1】:

    由于&lt;-.data.table不会复制,你可以使用&lt;-

    创建一个data.table对象:

    library(data.table)
    di <- data.table(iris)
    

    创建一个新列:

    di <- di[, z:=1:nrow(di)]
    di
    
    #       Sepal.Length Sepal.Width Petal.Length Petal.Width Species  z
    #  [1,]          5.1         3.5          1.4         0.2  setosa  1
    #  [2,]          4.9         3.0          1.4         0.2  setosa  2
    #  [3,]          4.7         3.2          1.3         0.2  setosa  3
    #  [4,]          4.6         3.1          1.5         0.2  setosa  4
    #  [5,]          5.0         3.6          1.4         0.2  setosa  5
    #  [6,]          5.4         3.9          1.7         0.4  setosa  6
    #  [7,]          4.6         3.4          1.4         0.3  setosa  7
    #  [8,]          5.0         3.4          1.5         0.2  setosa  8
    #  [9,]          4.4         2.9          1.4         0.2  setosa  9
    # [10,]          4.9         3.1          1.5         0.1  setosa 10
    # First 10 rows of 150 printed. 
    

    还值得记住的是,R 仅在交互模式下打印对象的值。

    因此,在批处理模式下,您可以简单地使用:

    di[, z:=1:nrow(di)]
    

    这在批处理模式下作为脚本运行时不会产生任何输出。


    来自 Matthew Dowle 的更多信息:

    另请参阅常见问题解答 2.21 和 2.22:

    2.21 为什么DT[i,col:=value] 会返回整个DT?我期望要么没有可见值(与&lt;- 一致),要么期望包含更新的行数的消息或返回值。数据确实被引用更新并不明显。

    这样复合语法就可以工作了;例如,DT[i,done:=TRUE][,sum(done)]。当详细程度打开时,将返回更新的行数,无论是基于每个查询还是全局使用options(datatable.verbose=TRUE)

    2.22 好的,但是DT[i,col:=value]的返回值就不能隐形返回了吗?

    • 我们尝试过,但 R 在内部强制启用 [ 的可见性。的价值 [ 的 FunTab 的 eval 列(参见 src/main/names.c)是 0 表示力 R_Visible on(参见 R-Internals 部分 1.6)。因此,当我们尝试 invisible() 或直接将R_Visible 设置为0 我们自己,eval in src/main/eval.c 会再次强制它打开。
    • 在习惯了这种行为之后,您可能会越来越喜欢它(我们有)。毕竟,我们使用&lt;- 进行子赋值多少次,然后立即查看数据检查是否正常?
    • 我们可以将:= 混合到同样返回数据的j 中;混合更新并在一个查询中选择。检测 j 是否单独更新(然后行为不同)可能会令人困惑。

    Matthew Dowle 的第二次更新:

    我们现在找到了解决方案,当使用:= 时,v1.8.3 不再打印结果。我们将更新 FAQ 2.21 和 2.22。

    【讨论】:

    • 谢谢!在这种情况下,我将使用&lt;-
    • +10 我没想过要尝试DT&lt;-DT[i,col:=value]。变量名的重复不是很好,但有效。这让我知道如何让DT[i,col:=value] 隐形返回:现在提升为FR#2128,谢谢!
    • +1 为强大的聪明黑客 + 来自常见问题解答的有趣的 sn-p。
    • 是否有可能让黑客来处理赋值发生在括号内的表达式(例如循环或 if 语句)的情况?它似乎仍然发生在 R 3.0.0 的 1.8.8 中。
    • 我注意到:= 在 RStudio 中使用 Knit HTML 时会产生输出。这是出乎意料的。当没有发送到控制台时,为什么 knitr 在生成的 HTML 文件中产生输出?在这种情况下有没有办法抑制输出?这是一个新问题吗?
    【解决方案2】:

    对于一个很长的数据表名,似乎以下在性能上是等效的并且可以更短(我更喜欢短名称,但有时需要更长的名称来记住对象真正包含的内容):

    invisible(Very.Long.Data.Table[i,col:=value])

    比较:

    Very.Long.Data.Table&lt;-Very.Long.Data.Table[i,col:=value]

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-06-02
      • 1970-01-01
      • 2018-08-23
      相关资源
      最近更新 更多