【问题标题】:data.table does not play well with checkUsagedata.table 不能很好地与 checkUsage 配合使用
【发布时间】:2013-04-16 20:05:09
【问题描述】:

data.table 是一个很棒的包,唉,它会从checkUsage 生成无根据的警告(代码来自herehere):

> library(compiler)
> compiler::enableJIT(3)
> dt <- data.table(a = c(rep(3, 5), rep(4, 5)), b=1:10, c=11:20, d=21:30, key="a")
> my.func <- function (dt) {
  dt.out <- dt[, lapply(.SD, sum), by = a]
  dt.out[, count := dt[, .N, by=a]$N]
  dt.out
}
> checkUsage(my.func)
<anonymous>: no visible binding for global variable ‘.SD’ (:2)
<anonymous>: no visible binding for global variable ‘a’ (:2)
<anonymous>: no visible binding for global variable ‘count’ (:3)
<anonymous>: no visible binding for global variable ‘.N’ (:3)
<anonymous>: no visible binding for global variable ‘a’ (:3)
> my.func(dt)
Note: no visible binding for global variable '.SD' 
Note: no visible binding for global variable 'a' 
Note: no visible binding for global variable 'count' 
Note: no visible binding for global variable '.N' 
Note: no visible binding for global variable 'a' 
   a  b  c   d count
1: 3 15 65 115     5
2: 4 40 90 140     5

可以通过将by=a 替换为by="a" 来避免有关a 的警告,但是如何处理其他3 个警告?

这对我来说很重要,因为这些警告会使屏幕变得混乱并掩盖合法警告。由于警告是在 my.func 调用(启用 JIT 编译器时)发出的,而不仅仅是 checkUsage,我倾向于将其称为 bug

【问题讨论】:

  • 查询:那些是 my.func 内部的对象,那么为什么要把它们视为 global 变量呢?
  • thisthis
  • 我不知道checkUsage。如果我可以在data.table 中更改某些内容,请告诉我。或者也许可以选择checkUsage
  • 使用 data.table 的字节码编译代码似乎不太可能有任何好处,因为几乎所有的 data.table 代码都已经使用了编译后的 C 代码。
  • 单元测试与这个问题是正交的。我可以对某事进行单元测试,但仍然没有注意到它对全局命名空间造成了不利影响。

标签: r data.table


【解决方案1】:

更新:现已在 v1.8.11 中解决。来自NEWS

.SD,.N,.I,.GRP.BY 现在已导出(作为NULL)。这样R CMD checkcodetools::checkUsage 通过compiler::enableJIT() 就不会为它们生成注释。考虑了utils::globalVariables(),但选择了导出。 感谢 Sam Steingold 的资助,#2723

为了解析列名符号counta 的注释,它们都可以用引号括起来(即使在:= 的LHS 上)。使用新的 R 会话(因为注释只是第一次),以下现在不会产生注释。

$ R
R version 3.0.1 (2013-05-16) -- "Good Sport"
Copyright (C) 2013 The R Foundation for Statistical Computing
Platform: x86_64-pc-linux-gnu (64-bit)
> require(data.table)
Loading required package: data.table
data.table 1.8.11  For help type: help("data.table")
> library(compiler)
> compiler::enableJIT(3)
[1] 0
> dt <- data.table(a=c(rep(3,5),rep(4,5)), b=1:10, c=11:20, d=21:30, key="a")
> my.func <- function (dt) {
  dt.out <- dt[, lapply(.SD, sum), by = "a"]
  dt.out[, "count" := dt[, .N, by="a"]$N]
  dt.out
}
> my.func(dt)
   a  b  c   d count
1: 3 15 65 115     5
2: 4 40 90 140     5
> checkUsage(my.func)
> 

【讨论】:

    【解决方案2】:

    目前看来唯一的办法是

    my.func <- function (dt) {
      .SD <- .N <- count <- a <- NULL  # avoid inappropriate warnings
      dt.out <- dt[, lapply(.SD, sum), by = a]
      dt.out[, count := dt[, .N, by=a]$N]
      dt.out
    }
    

    即,在本地绑定报告为未绑定全局变量的变量。

    感谢@GSee 提供链接。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-04-25
      相关资源
      最近更新 更多