为什么 `data.table::unique` 不起作用?

Why `data.table::unique` doesn't work?

help(unique) 表明 unique 函数存在于两个包中 - basedata.table。我想使用 data.table 包中的这个函数。我认为以下语法 - data <- data.table::unique(data) 表示要使用的包。但是我收到以下错误 -

'unique' is not an exported object from 'namespace:data.table'

但是data <- unique(data)效果很好。

这里有什么问题?

有问题的函数实际上是 unique.data.tabledata.table 包中定义的 S3 方法。该方法并非真正打算直接调用,因此不会导出。 S3 方法通常就是这种情况。相反,包将该方法注册为 S3 方法,然后允许 S3 泛型(在本例中为 base::unique)对其进行分派。所以函数的正确调用方式是:

library(data.table)
irisDT <- data.table(iris)
unique(irisDT)

我们使用导出的base::unique,调度不导出的data.table:::unique.data.table。函数 data.table:::unique 实际上并不存在(或者它需要存在)。

正如 eddi 指出的那样,base::unique 根据调用对象的 class 进行调度。所以 base::unique 只有当对象是 data.table 时才会调用 data.table:::unique.data.table。您可以使用 data.table:::unique.data.table(iris) 之类的方法直接强制调用该方法,但在内部这很可能会导致调用下一个方法,除非您的对象实际上是 data.table.

R 中实际上有两个中缀运算符,它们从特定的包名称空间中提取函数。您使用了 ::,但还有一个 ::: 可以检索 "unexported" 函数。 unique 函数实际上是一个函数族,其行为将取决于其参数的 class 和已加载的特定包。这个的R项是"generic"。尝试:

data <- data.table:::unique(data)  # assuming 'data' is a data.table

getAnywhere 功能是 getAnywhere 的另一个工具,可以让您一窥缺少 "exportation" 所造成的幕后情况。它可以让你在控制台看到代码:

> unique.data.table
Error: object 'unique.data.table' not found

> getAnywhere(unique.data.table)
A single object matching ‘unique.data.table’ was found
It was found in the following places
  registered S3 method for unique from namespace data.table
  namespace:data.table
with value

function (x, incomparables = FALSE, fromLast = FALSE, by = key(x), 
    ...) 
{
    if (!cedta()) 
        return(NextMethod("unique"))
    dups <- duplicated.data.table(x, incomparables, fromLast, 
        by, ...)
    .Call(CsubsetDT, x, which_(dups, FALSE), seq_len(ncol(x)))
}
<bytecode: 0x2ff645950>
<environment: namespace:data.table>