Phương thức của S3 S3 có nghĩa là gì trong R?


124

Vì tôi khá mới với R, tôi không biết các phương thức và đối tượng S3 là gì. Tôi thấy rằng có các hệ thống đối tượng S3 và S4 và một số khuyến nghị nên sử dụng S3 trên S4 nếu có thể (Xem Hướng dẫn về Phong cách R của Google tại http://google-styleguide.googlecode.com/svn/trunk/google-r-style. html ) *. Tuy nhiên, tôi không biết định nghĩa chính xác của các phương thức / đối tượng S3.

Cập nhật: Kể từ năm 2019, siêu liên kết Hướng dẫn Phong cách R của Google hiện đã có tại đây .

Câu trả lời:


85

Hầu hết các thông tin liên quan có thể được tìm thấy bằng cách xem ?S3hoặc ?UseMethod, nhưng tóm lại:

S3 đề cập đến một sơ đồ gửi phương thức. Nếu bạn đã sử dụng R cho một thời gian, bạn sẽ nhận thấy rằng có print, predictsummaryphương pháp cho rất nhiều loại khác nhau của các đối tượng.

Trong S3, điều này hoạt động bằng cách:

  • thiết lập lớp đối tượng quan tâm (ví dụ: giá trị trả về của lệnh gọi phương thức glmcó lớp glm)
  • cung cấp một phương thức với tên chung (ví dụ print), sau đó là dấu chấm và sau đó là tên lớp (vd print.glm:)
  • một số sự chuẩn bị đã được thực hiện với tên chung này ( print) để nó hoạt động, nhưng nếu bạn chỉ đơn giản là muốn tuân thủ các tên phương thức hiện có, bạn không cần điều này (xem trợ giúp tôi đã giới thiệu trước đó nếu bạn làm ).

Đối với người theo dõi, và đặc biệt, người dùng gói phù hợp mô hình mới được tạo ra của bạn, sẽ thuận tiện hơn nhiều để có thể gõ predict(myfit, type="class")hơn predict.mykindoffit(myfit, type="class").

Có khá nhiều hơn một chút về nó, nhưng điều này sẽ giúp bạn bắt đầu. Có khá nhiều nhược điểm đối với cách gửi phương thức này dựa trên một thuộc tính (lớp) của các đối tượng (và những người theo chủ nghĩa thuần túy C có thể thức trắng đêm trong nỗi kinh hoàng của nó), nhưng trong nhiều tình huống, nó hoạt động rất tốt. Với phiên bản R hiện tại, các cách mới hơn đã được triển khai (S4 và các lớp tham chiếu), nhưng hầu hết mọi người vẫn (chỉ) sử dụng S3.


54

Để giúp bạn bắt đầu với S3, hãy xem mã cho medianchức năng. Nhập medianvào dấu nhắc lệnh cho thấy nó có một dòng trong cơ thể, cụ thể là

UseMethod("median")

Điều đó có nghĩa là nó là một phương thức S3. Nói cách khác, bạn có thể có một medianchức năng khác nhau cho các lớp S3 khác nhau. Để liệt kê tất cả các phương thức trung bình có thể, gõ

methods(median) #actually not that interesting.  

Trong trường hợp này, chỉ có một phương thức, mặc định, được gọi cho bất cứ điều gì. Bạn có thể xem mã cho điều đó bằng cách gõ

median.default

Một ví dụ thú vị hơn nhiều là printhàm, có nhiều phương thức khác nhau.

methods(print)  #very exciting

Lưu ý rằng một số phương thức có *s bên cạnh tên của chúng. Điều đó có nghĩa là chúng được ẩn bên trong không gian tên của một số gói. Sử dụng findđể tìm hiểu xem họ đang ở trong gói nào. Ví dụ:

find("acf")  #it's in the stats package
stats:::print.acf

39

Từ http://adv-r.had.co.nz/OO-essentials.html :

Ba hệ thống OO của R khác nhau về cách các lớp và phương thức được định nghĩa:

  • S3 thực hiện một kiểu lập trình OO gọi là OO chức năng chung. Điều này khác với hầu hết các ngôn ngữ lập trình, như Java, C ++ và C #, thực hiện OO truyền thông điệp. Với việc truyền tin nhắn, tin nhắn (phương thức) được gửi đến các đối tượng và đối tượng xác định hàm nào sẽ gọi. Thông thường, đối tượng này có sự xuất hiện đặc biệt trong lệnh gọi phương thức, thường xuất hiện trước tên của phương thức / thông báo: vd: canvas.drawRect ("blue"). S3 thì khác. Trong khi việc tính toán vẫn được thực hiện thông qua các phương thức, một loại hàm đặc biệt gọi là hàm chung quyết định phương thức nào sẽ gọi, ví dụ: drawRect (canvas, "blue"). S3 là một hệ thống rất giản dị. Nó không có định nghĩa chính thức của các lớp.

  • S4 hoạt động tương tự S3, nhưng trang trọng hơn. Có hai điểm khác biệt chính so với S3. S4 có các định nghĩa lớp chính thức, mô tả biểu diễn và kế thừa cho mỗi lớp và có các hàm trợ giúp đặc biệt để xác định các tổng quát và phương thức. S4 cũng có nhiều công văn, có nghĩa là các hàm chung có thể chọn các phương thức dựa trên lớp của bất kỳ số lượng đối số nào, không chỉ một.

  • Các lớp tham chiếu, gọi tắt là RC, khá khác so với S3 và S4. RC thực hiện OO truyền thông điệp, vì vậy các phương thức thuộc về các lớp, không phải các hàm. $ được sử dụng để phân tách các đối tượng và phương thức, vì vậy các lệnh gọi phương thức trông giống như canvas $ drawRect ("blue"). Các đối tượng RC cũng có thể thay đổi: chúng không sử dụng ngữ nghĩa sao chép khi sửa đổi thông thường của R, nhưng được sửa đổi tại chỗ. Điều này khiến họ khó lý luận hơn, nhưng cho phép họ giải quyết các vấn đề khó giải quyết với S3 hoặc S4.

Ngoài ra còn có một hệ thống khác không hoàn toàn OO, nhưng điều quan trọng cần đề cập ở đây:

  • các loại cơ sở, các loại cấp độ C nội bộ làm nền tảng cho các hệ thống OO khác. Các loại cơ sở chủ yếu được xử lý bằng mã C, nhưng chúng quan trọng cần biết vì chúng cung cấp các khối xây dựng cho các hệ thống OO khác.

11

Tôi đến với câu hỏi này chủ yếu là tự hỏi những cái tên đến từ đâu. Nó xuất hiện từ bài viết trên wikipedia này rằng tên đề cập đến phiên bản của Ngôn ngữ lập trình S mà R dựa trên. Các phương thức gửi phương thức được mô tả trong các câu trả lời khác đến từ S và được dán nhãn thích hợp theo phiên bản.


10

Thử

methods(residuals)

trong đó liệt kê, trong số những người khác, "Residuals.lm" và "Residuals.glm". Điều này có nghĩa là khi bạn đã trang bị một mô hình tuyến tính, m và loạiresiduals(m), phần dư.lm sẽ được gọi. Khi bạn đã trang bị một mô hình tuyến tính tổng quát, phần dư.glm sẽ được gọi. Đó là kiểu mô hình đối tượng C ++ bị đảo lộn. Trong C ++, bạn định nghĩa một lớp cơ sở có các hàm ảo, được ghi đè bằng lớp dẫn xuất. Trong R, bạn định nghĩa một hàm ảo (còn gọi là chung) và sau đó bạn quyết định lớp nào sẽ ghi đè hàm này (hay còn gọi là định nghĩa một phương thức). Lưu ý rằng các lớp làm điều này không cần phải xuất phát từ một siêu lớp thông thường. Tôi thường không đồng ý thích S3 hơn S4. S4 có tính hình thức hơn (= gõ nhiều hơn) và điều này có thể là quá nhiều đối với một số ứng dụng. Các lớp S4, tuy nhiên, có thể được định nghĩa như một lớp hoặc struct trong C ++. Bạn có thể chỉ định rằng một đối tượng của một lớp nhất định được tạo thành từ một chuỗi và hai số chẳng hạn:

setClass("myClass", representation(label = "character", x = "numeric", y = "numeric"))

Các phương thức được gọi với một đối tượng của lớp đó có thể dựa vào đối tượng có các thành viên đó. Điều đó rất khác với các lớp S3, vốn chỉ là một danh sách các yếu tố.

Với S3 và S4, bạn gọi hàm thành viên bằng fun(object, args)và không phải bằng object$fun(args). Nếu bạn đang tìm kiếm một cái gì đó như sau này, hãy xem gói proto.


Tôi khá chắc chắn rằng ý tưởng về các hàm thành viên và các phương thức thuộc về các đối tượng không có ý nghĩa nhiều trong R. Các phương thức không thuộc về các đối tượng (cũng là các hàm cũng là các đối tượng) mà thuộc về hàm.
petermeissner

3

Dưới đây là bản cập nhật nhanh của nhiều hệ thống đối tượng R theo "Advanced R, phiên bản 2" (CRC Press, 2019) của Hadley Wickham (Nhà khoa học trưởng tại RStudio), có đại diện web ở đây , dựa trên chương về Đối tượng Lập trình -Irient .

Bìa sách R nâng cao

Phiên bản đầu tiên từ năm 2015 có một đại diện web ở đây , với chương tương ứng về OO ở đây .

Phương pháp tiếp cận hệ thống OO

Hadley định nghĩa như sau để phân biệt hai cách tiếp cận khác nhau đối với lập trình OO:

Hàm OOP : các phương thức (các đoạn mã có thể gọi được) thuộc về các hàm chung (không bị nhầm lẫn với các phương thức chung Java / C # ). Hãy nghĩ về các phương pháp như được đặt trong một bảng tra cứu toàn cầu. Phương thức để thực thi được tìm thấy bởi hệ thống thời gian chạy dựa trên tên của hàm và loại (hoặc lớp đối tượng) của một hoặc nhiều đối số được truyền cho hàm đó (đây được gọi là "phương thức gửi"). Cú pháp khôn ngoan, các cuộc gọi phương thức có thể trông giống như các cuộc gọi hàm thông thường : myfunc(object, arg1, arg2). Cuộc gọi này sẽ dẫn đến thời gian chạy để tìm phương thức được liên kết với cặp ("myfunc", typeof (object)) hoặc có thể ("myfunc", typeof (object), typeof (arg1), typeof (arg2))nếu ngôn ngữ hỗ trợ điều đó. Trong R's S3, tên đầy đủ của hàm chung cung cấp cặp (tên hàm, lớp)đôi. Ví dụ: mean.Datelà phương pháp tính giá trị trung bình của Ngày. Cố gắng methods("mean")liệt kê các phương thức chung với tên hàm mean. Cách tiếp cận OOP chức năng được tìm thấy ví dụ trong Smalltalk tiên phong của OO , Hệ thống đối tượng Lisp chungJulia . Hadley lưu ý rằng "So với R, việc triển khai của Julia được phát triển đầy đủ và cực kỳ hiệu quả."

OOP đóng gói : các phương thức thuộc về các đối tượng hoặc các lớp và các cuộc gọi phương thức thường trông như thế nào object.method(arg1, arg2). Điều này được gọi là đóng gói vì đối tượng đóng gói cả dữ liệu (trường) và hành vi (phương thức). Hãy nghĩ về phương thức như được đặt trong một bảng tra cứu được gắn vào đối tượng hoặc mô tả lớp của đối tượng. Thời gian chạy trông phương thức dựa trên tên phương thức và có thể là loại của một hoặc nhiều đối số. Đây là cách tiếp cận được tìm thấy trong các ngôn ngữ OO "phổ biến" như C ++, Java, C #.

Trong cả hai trường hợp, nếu tính kế thừa được hỗ trợ (có thể là vậy), thời gian chạy có thể đi qua hệ thống phân cấp lớp lên trên cho đến khi tìm thấy sự trùng khớp cho khóa tra cứu cuộc gọi.

Làm thế nào để tìm ra hệ thống mà một đối tượng R thuộc về

library(sloop) # formerly, "pryr"
otype(mtcars)
#> [1] "S3"

Các hệ thống đối tượng R

S3

  • Phương pháp OOP chức năng.
  • Hệ thống quan trọng nhất theo Hadley.
  • Đơn giản nhất, phổ biến nhất. Hệ thống OO đầu tiên được sử dụng bởi R.
  • Đi kèm với cơ sở R, được sử dụng trong suốt cơ sở R.
  • Dựa vào các công ước hơn là bảo đảm thi hành.
  • Xem Chambers, John M và Trevor J Hastie. 1992. "Các mô hình thống kê ở S." Phần mềm và sách nâng cao của Wadsworth & Brooks / Cole.
  • Chi tiết trong "Advanced R, phiên bản 2" tại đây .

S4

  • Phương pháp OOP chức năng.
  • Hệ thống quan trọng thứ ba theo Hadley.
  • Viết lại của S3, do đó tương tự như S3, nhưng trang trọng hơn và nghiêm ngặt hơn: nó buộc bạn phải suy nghĩ cẩn thận về thiết kế chương trình. Thích hợp để xây dựng các hệ thống lớn (ví dụ dự án Bioconductor ).
  • Thực hiện trong gói "phương pháp" cơ sở.
  • Xem: Chambers, John M. 1998. "Lập trình với dữ liệu: Hướng dẫn về ngôn ngữ S." Mùa xuân.
  • Chi tiết trong "Advanced R, phiên bản 2" tại đây .

RC hay còn gọi là "Lớp tham khảo"

  • Phương pháp OOP đóng gói.
  • Đi kèm với cơ sở R.
  • Dựa trên S4.
  • Đối tượng RC là loại đối tượng S4 đặc biệt cũng "có thể thay đổi". tức là thay vì sử dụng ngữ nghĩa sao chép khi sửa đổi thông thường của R, chúng có thể được sửa đổi tại chỗ. Lưu ý rằng trạng thái có thể thay đổi là khó lý do và là nguồn gây ra lỗi xấu nhưng có thể dẫn đến mã hiệu quả hơn trong các ứng dụng nhất định.

R6

  • Phương pháp OOP đóng gói.
  • Hệ thống quan trọng thứ hai theo Hadley.
  • Có thể tìm thấy trong gói R6 (cài đặt với library(R6))
  • Tương tự như RC, nhưng nhẹ hơn & nhanh hơn nhiều: nó không phụ thuộc vào S4 hoặc các phương thức gói . Được xây dựng trên môi trường R. Cũng có:
    • phương pháp công cộng và tư nhân
    • các ràng buộc hoạt động (các trường, khi được truy cập, thực sự gọi một phương thức)
    • lớp học không hoạt động trên các gói
    • cả hai phương pháp lớp (mã thuộc về lớp và có thể truy cập vào một thể hiện qua self, private, super) và các hàm thành viên (chức năng giao cho các lĩnh vực, nhưng đó không phải là phương pháp, chỉ cần các chức năng)
  • Cung cấp một cách chuẩn hóa để thoát khỏi ngữ nghĩa "sao chép khi sửa đổi" của R
  • Xem trang gói: "R6: Lập trình hướng đối tượng được đóng gói cho R" .
  • Chi tiết trong "Advanced R, phiên bản 2" tại đây .

Khác

Có những cái khác, như R.oo (tương tự RC), proto (dựa trên nguyên mẫu, nghĩ JavaScript) và Mutatr . Tuy nhiên, "Advanced R" nói:

Ngoài R6, được sử dụng rộng rãi, các hệ thống này chủ yếu được quan tâm về mặt lý thuyết. Họ có những điểm mạnh, nhưng rất ít người dùng R biết và hiểu họ, vì vậy thật khó để người khác đọc và đóng góp cho mã của bạn.

Hãy nhớ đọc chương về sự đánh đổi trong "Advanced R, phiên bản 2" .

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.