“ วิธี S3” หมายถึงอะไรใน R?


125

เนื่องจากฉันค่อนข้างใหม่กับ R ฉันจึงไม่รู้ว่าวิธี S3 และวัตถุคืออะไร ฉันพบว่ามีระบบอ็อบเจ็กต์ S3 และ S4 และบางส่วนแนะนำให้ใช้ S3 มากกว่า S4 หากเป็นไปได้ (ดูคู่มือสไตล์ R ของ Google ที่http://google-styleguide.googlecode.com/svn/trunk/google-r-style html ) *. อย่างไรก็ตามฉันไม่ทราบคำจำกัดความที่แน่นอนของวิธี / วัตถุ S3

อัปเดต: ในปี 2019 ไฮเปอร์ลิงก์ R Style Guide ของ Google อยู่ที่นี่แล้ว

คำตอบ:


85

ข้อมูลที่เกี่ยวข้องส่วนใหญ่สามารถพบได้โดยการดู?S3หรือ?UseMethodแต่โดยสรุป:

S3 หมายถึงรูปแบบของการจัดส่งวิธีการ หากคุณเคยใช้ R ในขณะที่คุณจะสังเกตเห็นว่ามีprint, predictและsummaryวิธีการมากชนิดที่แตกต่างกันของวัตถุ

ใน S3 สิ่งนี้ทำงานโดย:

  • การตั้งค่าคลาสของอ็อบเจ็กต์ที่สนใจ (เช่น: ค่าส่งคืนของการเรียกใช้เมธอดglmมีคลาสglm)
  • ให้วิธีการที่มีชื่อทั่วไป (เช่นprint) แล้วจุดแล้ว ClassName (เช่น: print.glm)
  • ต้องมีการเตรียมการบางอย่างกับชื่อทั่วไปนี้ ( print) เพื่อให้สามารถใช้งานได้ แต่ถ้าคุณเพียงแค่ต้องการให้สอดคล้องกับชื่อวิธีการที่มีอยู่คุณไม่จำเป็นต้องใช้สิ่งนี้ (ดูความช่วยเหลือที่ฉันอ้างถึงก่อนหน้านี้หากคุณทำ )

ตาของคนดูและโดยเฉพาะอย่างยิ่งการใช้งานของแพคเกจรูปแบบที่เหมาะสมของคุณขี้ขลาดที่สร้างขึ้นใหม่ก็เป็นที่สะดวกสบายมากขึ้นเพื่อให้สามารถพิมพ์กว่าpredict(myfit, type="class")predict.mykindoffit(myfit, type="class")

ยังมีอีกเล็กน้อย แต่สิ่งนี้ควรช่วยให้คุณเริ่มต้นได้ วิธีการจัดส่งตามคุณลักษณะ (คลาส) ของวัตถุมีข้อเสียอยู่ไม่น้อย (และ C purists อาจจะนอนหลับตอนกลางคืนด้วยความหวาดกลัวของมัน) แต่สำหรับหลาย ๆ สถานการณ์มันก็ใช้ได้ดี ด้วยเวอร์ชันปัจจุบันของ R ได้มีการนำวิธีการใหม่ ๆ มาใช้ (S4 และคลาสอ้างอิง) แต่คนส่วนใหญ่ยังคง (เท่านั้น) ใช้ S3


55

ในการเริ่มต้นใช้งาน S3 ให้ดูที่รหัสสำหรับmedianฟังก์ชัน การพิมพ์medianที่พรอมต์คำสั่งแสดงให้เห็นว่ามีหนึ่งบรรทัดในตัวคือ

UseMethod("median")

นั่นหมายความว่าเป็นวิธี S3 กล่าวอีกนัยหนึ่งคุณสามารถมีmedianฟังก์ชันที่แตกต่างกันสำหรับคลาส S3 ที่แตกต่างกัน หากต้องการแสดงวิธีการหาค่ามัธยฐานที่เป็นไปได้ทั้งหมดให้พิมพ์

methods(median) #actually not that interesting.  

ในกรณีนี้มีเพียงวิธีเดียวคือค่าเริ่มต้นซึ่งเรียกว่าอะไรก็ได้ คุณสามารถดูรหัสนั้นได้โดยพิมพ์

median.default

ตัวอย่างที่น่าสนใจกว่านั้นคือprintฟังก์ชันซึ่งมีวิธีการต่างๆมากมาย

methods(print)  #very exciting

สังเกตว่าวิธีการบางอย่างจะ*อยู่ถัดจากชื่อ นั่นหมายความว่าพวกมันซ่อนอยู่ในเนมสเปซของแพ็คเกจ ใช้findเพื่อค้นหาว่าอยู่ในแพ็คเกจใดตัวอย่างเช่น

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

39

จากhttp://adv-r.had.co.nz/OO-essentials.html :

ระบบ OO ทั้งสามของ R แตกต่างกันในการกำหนดคลาสและวิธีการ:

  • S3 ใช้รูปแบบของการเขียนโปรแกรม OO ที่เรียกว่า generic-function OO ซึ่งแตกต่างจากภาษาโปรแกรมส่วนใหญ่เช่น Java, C ++ และ C # ซึ่งใช้ OO ส่งข้อความ ด้วยการส่งข้อความข้อความ (วิธีการ) จะถูกส่งไปยังวัตถุและวัตถุจะกำหนดฟังก์ชันที่จะเรียกใช้ โดยปกติแล้ววัตถุนี้จะมีลักษณะพิเศษในการเรียกใช้เมธอดซึ่งมักจะปรากฏก่อนชื่อของวิธีการ / ข้อความ: เช่น canvas.drawRect ("blue") S3 แตกต่างกัน ในขณะที่การคำนวณยังคงดำเนินการผ่านเมธอดประเภทของฟังก์ชันพิเศษที่เรียกว่าฟังก์ชันทั่วไปจะตัดสินใจว่าจะเรียกใช้เมธอดใดเช่น drawRect (canvas, "blue") S3 เป็นระบบที่ไม่เป็นทางการมาก ไม่มีคำจำกัดความอย่างเป็นทางการของคลาส

  • S4 ทำงานคล้ายกับ S3 แต่เป็นทางการมากกว่า มีความแตกต่างที่สำคัญสองประการสำหรับ S3 S4 มีคำจำกัดความของคลาสที่เป็นทางการซึ่งอธิบายถึงการเป็นตัวแทนและการสืบทอดสำหรับแต่ละคลาสและมีฟังก์ชันตัวช่วยพิเศษสำหรับการกำหนดชื่อสามัญและวิธีการ S4 ยังมีการจัดส่งหลายรายการซึ่งหมายความว่าฟังก์ชันทั่วไปสามารถเลือกวิธีการตามคลาสของอาร์กิวเมนต์จำนวนเท่าใดก็ได้ไม่ใช่เพียงข้อเดียว

  • คลาสอ้างอิงที่เรียกสั้น ๆ ว่า RC นั้นแตกต่างจาก S3 และ S4 ค่อนข้างมาก RC ใช้ OO ที่ส่งผ่านข้อความดังนั้นเมธอดจึงเป็นของคลาสไม่ใช่ฟังก์ชัน $ ใช้เพื่อแยกอ็อบเจ็กต์และเมธอดดังนั้นการเรียกเมธอดจึงดูเหมือนผ้าใบ $ drawRect ("blue") อ็อบเจ็กต์ RC สามารถเปลี่ยนแปลงได้เช่นกัน: พวกเขาไม่ได้ใช้ความหมายตามปกติ copy-on-modified ของ R แต่มีการแก้ไขในสถานที่ สิ่งนี้ทำให้พวกเขาหาเหตุผลได้ยากขึ้น แต่ช่วยให้พวกเขาแก้ปัญหาที่แก้ได้ยากด้วย S3 หรือ S4

นอกจากนี้ยังมีอีกระบบหนึ่งที่ไม่ค่อย OO แต่สิ่งสำคัญคือต้องพูดถึงที่นี่:

  • ประเภทพื้นฐานประเภทระดับ C ภายในที่รองรับระบบ OO อื่น ๆ ประเภทฐานส่วนใหญ่จะถูกจัดการโดยใช้รหัส C แต่สิ่งสำคัญที่ต้องรู้เนื่องจากมีการสร้างแบบสำเร็จรูปสำหรับระบบ OO อื่น ๆ

12

ฉันมาถึงคำถามนี้โดยส่วนใหญ่สงสัยว่าชื่อมาจากไหน ปรากฏจากบทความวิกิพีเดียนี้ว่าชื่อนี้หมายถึงเวอร์ชันของภาษาโปรแกรม S ที่ใช้ R รูปแบบการจัดส่งวิธีการที่อธิบายไว้ในคำตอบอื่น ๆ มาจาก S และมีป้ายกำกับอย่างเหมาะสมตามเวอร์ชัน


10

ลอง

methods(residuals)

ซึ่งแสดงรายการอื่น ๆ ได้แก่ "residuals.lm" และ "residuals.glm" ซึ่งหมายความว่าเมื่อคุณติดตั้งแบบจำลองเชิงเส้น m และประเภทresiduals(m), residuals.lm จะถูกเรียก เมื่อคุณติดตั้งแบบจำลองเชิงเส้นทั่วไปแล้วระบบจะเรียก residuals.glm เป็นแบบจำลองวัตถุ C ++ ที่พลิกกลับด้าน ใน C ++ คุณกำหนดคลาสพื้นฐานที่มีฟังก์ชันเสมือนซึ่งถูกแทนที่ด้วยคลาสที่สืบทอดมา ใน R คุณกำหนดฟังก์ชันเสมือน (aka generic) จากนั้นคุณตัดสินใจว่าคลาสใดจะแทนที่ฟังก์ชันนี้ (aka กำหนดวิธีการ) โปรดทราบว่าคลาสที่ทำเช่นนี้ไม่จำเป็นต้องได้มาจากคลาสซุปเปอร์ทั่วไปเพียงคลาสเดียว ฉันไม่เห็นด้วยที่จะชอบ S3 มากกว่า S4 S4 มีความเป็นทางการมากกว่า (= พิมพ์มากขึ้น) และอาจมากเกินไปสำหรับบางแอปพลิเคชัน อย่างไรก็ตามคลาส S4 สามารถกำหนดได้เช่นคลาสหรือโครงสร้างใน C ++ คุณสามารถระบุว่าออบเจ็กต์ของคลาสหนึ่ง ๆ ประกอบด้วยสตริงและตัวเลขสองตัวเช่น:

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

เมธอดที่ถูกเรียกด้วยอ็อบเจ็กต์ของคลาสนั้นสามารถอาศัยอ็อบเจ็กต์ที่มีสมาชิกเหล่านั้น ซึ่งแตกต่างจากคลาส S3 มากซึ่งเป็นเพียงรายการขององค์ประกอบต่างๆ

ด้วย S3 และ S4 คุณจะเรียกใช้ฟังก์ชันสมาชิกโดยfun(object, args)หรือไม่object$fun(args)ใช้ หากคุณกำลังมองหาบางอย่างเช่นหลังลองดูที่แพคเกจโปรโต


ฉันค่อนข้างแน่ใจว่าแนวคิดของฟังก์ชันสมาชิกและเมธอดที่เป็นของอ็อบเจ็กต์นั้นไม่สมเหตุสมผลใน R วิธีการไม่ได้เป็นของอ็อบเจ็กต์ (รวมถึงฟังก์ชันก็คืออ็อบเจกต์ด้วยเช่นกัน) แต่เป็นของฟังก์ชัน
petermeissner

3

นี่คือบทสรุปอย่างรวดเร็วที่อัปเดตของระบบวัตถุ Rจำนวนมากตาม"Advanced R, 2nd edition" (CRC Press, 2019) โดย Hadley Wickham (Chief Scientist ที่ RStudio) ซึ่งมีการแสดงเว็บที่นี่โดยอ้างอิงจากบทเกี่ยวกับObject การเขียนโปรแกรมเชิง

ปกหนังสือ Advanced R

ฉบับพิมพ์ครั้งแรกจาก 2015 มีตัวแทนเว็บที่นี่ด้วยบทที่สอดคล้องกันใน OO นี่

แนวทางของระบบ OO

Hadley กำหนดสิ่งต่อไปนี้เพื่อแยกความแตกต่างสองแนวทางในการเขียนโปรแกรม OO:

OOP ที่ใช้งานได้ : วิธีการ (ส่วนรหัสที่เรียกได้) เป็นของฟังก์ชันทั่วไป (เพื่อไม่ให้สับสนกับวิธีการทั่วไปของ Java / C # ) ลองนึกถึงวิธีการที่อยู่ในตารางการค้นหาส่วนกลาง ระบบรันไทม์จะพบวิธีการดำเนินการตามชื่อของฟังก์ชันและประเภท (หรือคลาสอ็อบเจ็กต์) ของอาร์กิวเมนต์อย่างน้อยหนึ่งอาร์กิวเมนต์ที่ส่งผ่านไปยังฟังก์ชันนั้น (เรียกว่า "วิธีการจัดส่ง") myfunc(object, arg1, arg2)ไวยากรณ์ฉลาดวิธีการโทรอาจมีลักษณะเหมือนการเรียกฟังก์ชันสามัญ: การเรียกนี้จะทำให้รันไทม์ค้นหาเมธอดที่เกี่ยวข้องกับคู่("myfunc", typeof (object))หรืออาจเป็น("myfunc", typeof (object), typeof (arg1), typeof (arg2))หากภาษานั้นรองรับ ในการวิจัยของ S3, ชื่อเต็มของฟังก์ชั่นทั่วไปให้(ฟังก์ชั่นชื่อชั้น)คู่ ตัวอย่างเช่น: mean.Dateเป็นวิธีการคำนวณค่าเฉลี่ยของวันที่ ลองไปที่รายการวิธีการทั่วไปที่มีชื่อฟังก์ชั่นmethods("mean") meanวิธี OOP ฟังก์ชั่นที่พบเช่นในผู้บุกเบิก OO สมอลล์ทอล์คที่Common เสียงกระเพื่อมวัตถุระบบและจูเลีย Hadley ตั้งข้อสังเกตว่า"เมื่อเทียบกับ R การใช้งานของ Julia ได้รับการพัฒนาอย่างเต็มที่และมีประสิทธิภาพสูงมาก"

OOP ที่ห่อหุ้ม : เมธอดเป็นของอ็อบเจ็กต์หรือคลาสและโดยทั่วไปการเรียกเมธอดจะมีลักษณะobject.method(arg1, arg2)ดังนี้ สิ่งนี้เรียกว่าการห่อหุ้มเนื่องจากวัตถุห่อหุ้มทั้งข้อมูล (ฟิลด์) และพฤติกรรม (วิธีการ) คิดว่าเมธอดอยู่ในตารางการค้นหาที่แนบกับอ็อบเจ็กต์หรือคำอธิบายคลาสของอ็อบเจ็กต์ รันไทม์จะค้นหาเมธอดตามชื่อเมธอดและอาจเป็นประเภทของอาร์กิวเมนต์ตั้งแต่หนึ่งตัวขึ้นไป นี่คือแนวทางที่พบในภาษา OO "ยอดนิยม" เช่น C ++, Java, C #

ในทั้งสองกรณีหากรองรับการสืบทอด (อาจเป็น) รันไทม์อาจข้ามลำดับชั้นของคลาสขึ้นไปจนกว่าจะพบคีย์การค้นหาการโทรที่ตรงกัน

วิธีค้นหาว่าวัตถุ R เป็นของระบบใด

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

ระบบวัตถุ R

S3

  • แนวทาง OOP ที่ใช้งานได้
  • ระบบที่สำคัญที่สุดตาม Hadley
  • ง่ายที่สุดที่พบบ่อยที่สุด ระบบ OO แรกที่ใช้โดย R.
  • มาพร้อมกับฐาน R ใช้ตลอดฐาน R
  • ขึ้นอยู่กับอนุสัญญามากกว่าการค้ำประกันที่บังคับใช้
  • ดูChambers, John M และ Trevor J Hastie 2535. "แบบจำลองทางสถิติใน S. " Wadsworth & Brooks / Cole Advanced Books & Software
  • รายละเอียดใน"ขั้นสูง R, พิมพ์ครั้งที่ 2" ที่นี่

S4

  • แนวทาง OOP ที่ใช้งานได้
  • ระบบที่สำคัญที่สุดอันดับสามตาม Hadley
  • การเขียน S3 ใหม่จึงคล้ายกับ S3 แต่เป็นทางการและเข้มงวดกว่า: บังคับให้คุณคิดอย่างรอบคอบเกี่ยวกับการออกแบบโปรแกรม เหมาะสำหรับการสร้างระบบขนาดใหญ่ (เช่นโครงการBioconductor )
  • ดำเนินการในแพ็คเกจ "วิธีการ" พื้นฐาน
  • โปรดดู: Chambers, John M. 1998. "Programming with Data: A Guide to the S Language." สปริงเกอร์
  • รายละเอียดใน"ขั้นสูง R, พิมพ์ครั้งที่ 2" ที่นี่

RC aka "คลาสอ้างอิง"

  • วิธีการห่อหุ้ม OOP
  • มาพร้อมฐาน R
  • ขึ้นอยู่กับ S4
  • วัตถุ RC เป็นวัตถุ S4 ประเภทพิเศษที่ "เปลี่ยนแปลงได้" เช่นกัน กล่าวคือแทนที่จะใช้ความหมายตามปกติ copy-on-modified ของ R สามารถแก้ไขได้ในสถานที่ โปรดทราบว่าสถานะที่เปลี่ยนแปลงได้นั้นยากที่จะให้เหตุผลและเป็นแหล่งที่มาของข้อบกพร่องที่น่าเกลียด แต่อาจทำให้โค้ดมีประสิทธิภาพมากขึ้นในบางแอปพลิเคชัน

R6

  • วิธีการห่อหุ้ม OOP
  • ระบบที่สำคัญอันดับสองตาม Hadley
  • สามารถพบได้ในแพ็คเกจR6 (ติดตั้งด้วยlibrary(R6))
  • คล้ายกับ RC แต่เบากว่าและเร็วกว่ามาก: ไม่ได้ขึ้นอยู่กับ S4 หรือแพ็คเกจวิธีการ สร้างขึ้นจากสภาพแวดล้อม R ยังมี:
    • วิธีการสาธารณะและส่วนตัว
    • การผูกที่ใช้งานอยู่ (ฟิลด์ที่เมื่อเข้าถึงแล้วจะเรียกวิธีการ)
    • การสืบทอดคลาสซึ่งทำงานข้ามแพ็คเกจ
    • ทั้งวิธีการเรียน (รหัสที่อยู่ในชั้นเรียนและสามารถเข้าถึงได้ผ่านทางอินสแตนซ์self, private, super) และฟังก์ชั่นสมาชิก (ฟังก์ชั่นได้รับมอบหมายให้สาขา แต่ที่ไม่ได้เป็นวิธีการทำงานเพียง)
  • เป็นวิธีมาตรฐานในการหลีกเลี่ยงความหมาย "copy-on-modified" ของ R
  • ดูเว็บไซต์ของแพคเกจ: "R6: เขียนโปรแกรมเชิงวัตถุ Encapsulated สำหรับ R"
  • รายละเอียดใน"ขั้นสูง R, พิมพ์ครั้งที่ 2" ที่นี่

คนอื่น ๆ

มีคนอื่น ๆ เช่นมีR.oo (คล้ายกับ RC) โปรโต (ต้นแบบตามคิดจาวาสคริปต์) และMutatr อย่างไรก็ตาม "Advanced R" กล่าวว่า:

นอกเหนือจาก R6 ซึ่งใช้กันอย่างแพร่หลายระบบเหล่านี้ยังให้ความสนใจในเชิงทฤษฎีเป็นหลัก พวกเขามีจุดแข็ง แต่มีผู้ใช้ R เพียงไม่กี่คนที่รู้จักและเข้าใจพวกเขาดังนั้นจึงเป็นเรื่องยากที่คนอื่นจะอ่านและมีส่วนร่วมในโค้ดของคุณ

อย่าลืมอ่านบทการแลกเปลี่ยนใน"Advanced R, 2nd edition"ด้วย

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.