Khi nhận xét chỉ ra, một số gói đã được xây dựng dựa trên ý tưởng này (hoặc tương tự).
data.table
và dplyr
đặc biệt tốt trong việc xử lý dữ liệu rất lớn và truy vấn chúng. Nếu data.frame thực sự là> 100GB, tôi muốn khuyên bạn nên data.table mà dường như tốt hơn dplyr trong giới hạn nrow-> Inf. Cả hai đều có hỗ trợ tuyệt vời trên stackoverflow nếu bạn cần nó.
Tuy nhiên, để thực sự trả lời câu hỏi của bạn (và hữu ích cho độc giả tương lai của câu hỏi này): có, bạn có thể tính thêm một hàm với R để cung cấp hành vi thay thế. Nó thực sự rất dễ dàng với hệ thống gửi S3. Tôi khuyên bạn nên this ressource để tìm hiểu thêm.
Tôi sẽ cung cấp cho bạn phiên bản ngưng: Nếu bạn có đối tượng lớp "myclass", bạn có thể viết hàm f.myclass để làm những gì bạn muốn.
Sau đó, bạn xác định một hàm tổng quát f:
f <- function(obj, ...) UseMethod("f", obj, ...)
Khi bạn gọi f(obj)
, chức năng mà UseMethod
sẽ gọi phụ thuộc vào lớp của obj.
Nếu obj thuộc lớp "myclass", thì f.myclass sẽ được gọi trên obj.
Nếu chức năng bạn muốn xác định lại đã tồn tại, hãy nói plot
, thì bạn có thể chỉ cần xác định plot.myclass
sẽ được sử dụng khi bạn gọi plot
trên đối tượng "myclass". Chức năng chung đã tồn tại, không cần phải xác định lại nó.
Để thay đổi lớp của đối tượng (hoặc thêm lớp mới vào các lớp hiện có, thường không phá vỡ hành vi bạn không muốn thay đổi), bạn có thể sử dụng class<-
.
Đây là ví dụ ngớ ngẩn.
> 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"
Có một số sự tinh tế, như chức năng được gọi nếu có nhiều lớp, theo thứ tự nào, v.v .. Tôi giới thiệu cho bạn giải thích kỹ lưỡng về hệ thống S3.
Đó là cách bạn sẽ xác định lại hành vi của các hàm. Viết lại chúng thành f.myclass
và sau đó tạo đối tượng của lớp "myclass".
Hoặc, bạn có thể xác định lại f.targetclass.Ví dụ, một lần nữa với print
và 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"
Hãy thử gói 'sqldf' cho vấn đề thực tế của bạn, nhưng tôi nghĩ rằng những gì bạn đang đề xuất là cơ chế lớp S3. – James
kiểm tra các gói 'ff' và' ffbase', chúng được xây dựng trên nguyên tắc chính xác đó. –
'data.table' và' dplyr' mới 'tbl_ *' – hrbrmstr