你可以在R中"绑定"或提供data.frame的替代实现吗?

use*_*135 12 sqlite r

在Perl(可能还有其他语言)中,您可以"绑定"变量以使用用户定义的行为替换它的内置行为.例如,哈希表可以与自定义"get"和"fetch"子例程绑定,例如,查询BerkeleyDB以使数据持久且不受RAM限制,但仍然看起来像Perl的常规哈希.

与R有类似的可能吗?特别是,我在思考,因为它data.frame看起来很像关系数据库中的一个表,如果data.frame它与SQLite这样的东西联系在一起,它会使R能够处理非常大的数据帧(我已经把100GB +填入了SQLite)而没有代码更改.

asa*_*ica 2

正如评论所指出的,一些软件包已经基于这个想法(或类似的想法)构建。

data.table并且dplyr非常擅长处理非常大的 data.frame 并查询它们。如果 data.frame 实际上 >100GB,我宁愿推荐 data.table,它在限制 nrow->Inf 中似乎优于 dplyr。如果您需要的话,两者在 stackoverflow 上都有出色的支持。

然而,要真正回答你的问题(并且对这个问题的未来读者有用):是的,可以用 R 附加函数来提供替代行为。使用S3调度系统实际上非常容易。我推荐此资源以了解更多信息。

我会给你一个精简版本:如果你有一个“myclass”类的对象,你可以编写一个函数 f.myclass 来执行你想要的操作。

然后定义通用函数 f:

f <- function(obj, ...) UseMethod("f", obj, ...)
Run Code Online (Sandbox Code Playgroud)

当您调用 时f(obj),将调用的函数UseMethod取决于 obj 的类。

如果 obj 属于“myclass”类,则将在 obj 上调用 f.myclass。

如果您要重新定义的函数已经存在,例如plot,那么您可以简单地定义在调用“myclass”对象plot.myclass时将使用哪个函数。plot通用函数已经存在,无需重新定义。

要更改对象的类(或将新类附加到现有类,这更常见,不会破坏您不想更改的行为),您可以使用class<-.

这是一个愚蠢的例子。

> print.myclass <- function(x) {
    print("Hello!")}

> df <- data.frame(a=1:3)
> class(df)
[1] "data.frame"
> df #equivalent to print(df)
  a
1 1
2 2
3 3

> class(df) <- append(class(df), "myclass")
> class(df)
[1] "data.frame" "myclass"   

> class(df) <- "myclass"
> class(df)
[1] "myclass"
> df
[1] "Hello!"
> str(df) # checking the structure of df: the data is still there of course
List of 1
 $ a: int [1:3] 1 2 3
 - attr(*, "row.names")= int [1:3] 1 2 3
 - attr(*, "class")= chr "myclass"
Run Code Online (Sandbox Code Playgroud)

有一些微妙之处,例如如果有多个类,则调用哪个函数,按什么顺序调用等。我建议您参阅 S3 系统的全面解释。

这就是重新定义函数行为的方式。将它们重写为f.myclass,然后创建类“myclass”的对象。

或者,您可以重新定义 f.targetclass。例如,再次使用printand data.frame

> print.data.frame <- function(x) {
         print(paste("data.frame with columns:", paste(names(x), collapse = ", ")))} # less silly example!
> df <- data.frame(a=1:3, b=4:6)
> df
[1] "data.frame with columns: a, b"
Run Code Online (Sandbox Code Playgroud)