ฉันจะดูซอร์สโค้ดของฟังก์ชั่นได้อย่างไร


551

ฉันต้องการดูซอร์สโค้ดสำหรับฟังก์ชั่นเพื่อดูว่ามันทำงานอย่างไร ฉันรู้ว่าฉันสามารถพิมพ์ฟังก์ชั่นได้โดยพิมพ์ชื่อที่พรอมต์:

> t
function (x) 
UseMethod("t")
<bytecode: 0x2332948>
<environment: namespace:base>

ในกรณีนี้UseMethod("t")หมายความว่าอย่างไร ฉันจะค้นหาซอร์สโค้ดที่ใช้งานจริงได้t(1:10)อย่างไรตัวอย่างเช่น:

มีความแตกต่างระหว่างเมื่อฉันเห็นUseMethodและเมื่อฉันเห็นstandardGenericและshowMethodsเช่นเดียวกับwith?

> with
standardGeneric for "with" defined from package "base"

function (data, expr, ...) 
standardGeneric("with")
<bytecode: 0x102fb3fc0>
<environment: 0x102fab988>
Methods may be defined for arguments: data
Use  showMethods("with")  for currently available ones.

ในกรณีอื่น ๆ ฉันเห็นว่ามีการเรียกใช้ฟังก์ชัน R แต่ฉันไม่สามารถหารหัสแหล่งที่มาสำหรับฟังก์ชั่นเหล่านั้นได้

> ts.union
function (..., dframe = FALSE) 
.cbind.ts(list(...), .makeNamesTs(...), dframe = dframe, union = TRUE)
<bytecode: 0x36fbf88>
<environment: namespace:stats>
> .cbindts
Error: object '.cbindts' not found
> .makeNamesTs
Error: object '.makeNamesTs' not found

ฉันจะค้นหาฟังก์ชันเช่น.cbindtsและได้.makeNamesTsอย่างไร

ในกรณีอื่น ๆ ยังมีรหัส R เล็กน้อย แต่งานส่วนใหญ่ดูเหมือนว่าจะทำที่อื่น

> matrix
function (data = NA, nrow = 1, ncol = 1, byrow = FALSE, dimnames = NULL) 
{
    if (is.object(data) || !is.atomic(data)) 
        data <- as.vector(data)
    .Internal(matrix(data, nrow, ncol, byrow, dimnames, missing(nrow), 
        missing(ncol)))
}
<bytecode: 0x134bd10>
<environment: namespace:base>
> .Internal
function (call)  .Primitive(".Internal")
> .Primitive
function (name)  .Primitive(".Primitive")

ฉันจะรู้ได้อย่างไรว่า.Primitiveฟังก์ชั่นนี้ทำงานอย่างไร? ในทำนองเดียวกันฟังก์ชั่นบางคนเรียก.C, .Call, .Fortran, หรือ.External .Internalฉันจะค้นหาซอร์สโค้ดสำหรับสิ่งเหล่านั้นได้อย่างไร




คำตอบ:


518

UseMethod("t")จะบอกคุณว่าt()เป็นฟังก์ชั่นทั่วไป( S3 ) ที่มีวิธีการเรียนวัตถุที่แตกต่างกัน

ระบบ S3 วิธีการจัดส่ง

สำหรับคลาส S3 คุณสามารถใช้methodsฟังก์ชันเพื่อแสดงรายการเมธอดสำหรับฟังก์ชันทั่วไปหรือคลาสเฉพาะ

> methods(t)
[1] t.data.frame t.default    t.ts*       

   Non-visible functions are asterisked
> methods(class="ts")
 [1] aggregate.ts     as.data.frame.ts cbind.ts*        cycle.ts*       
 [5] diffinv.ts*      diff.ts          kernapply.ts*    lines.ts        
 [9] monthplot.ts*    na.omit.ts*      Ops.ts*          plot.ts         
[13] print.ts         time.ts*         [<-.ts*          [.ts*           
[17] t.ts*            window<-.ts*     window.ts*      

   Non-visible functions are asterisked

"ฟังก์ชั่นที่ไม่สามารถมองเห็นได้จะถูกใส่เครื่องหมายดอกจัน" หมายความว่าฟังก์ชั่นจะไม่ถูกส่งออกจากเนมสเปซของแพ็คเกจ คุณยังสามารถดูรหัสต้นฉบับผ่าน:::ฟังก์ชั่น (คือstats:::t.ts) getAnywhere()หรือโดยการใช้ getAnywhere()มีประโยชน์เพราะคุณไม่จำเป็นต้องรู้ว่าฟังก์ชั่นนั้นมาจากไหน

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

function (x) 
{
    cl <- oldClass(x)
    other <- !(cl %in% c("ts", "mts"))
    class(x) <- if (any(other)) 
        cl[other]
    attr(x, "tsp") <- NULL
    t(x)
}
<bytecode: 0x294e410>
<environment: namespace:stats>

ระบบวิธีการจัดส่ง S4

ระบบ S4 เป็นวิธีการจัดส่งระบบที่ใหม่กว่าและเป็นทางเลือกสำหรับระบบ S3 นี่คือตัวอย่างของฟังก์ชั่น S4:

> library(Matrix)
Loading required package: lattice
> chol2inv
standardGeneric for "chol2inv" defined from package "base"

function (x, ...) 
standardGeneric("chol2inv")
<bytecode: 0x000000000eafd790>
<environment: 0x000000000eb06f10>
Methods may be defined for arguments: x
Use  showMethods("chol2inv")  for currently available ones.

เอาต์พุตมีข้อมูลจำนวนมากอยู่แล้ว standardGenericเป็นตัวบ่งชี้ของฟังก์ชั่น S4 วิธีการดูวิธี S4 ที่กำหนดไว้นั้นมีประโยชน์:

> showMethods(chol2inv)
Function: chol2inv (package base)
x="ANY"
x="CHMfactor"
x="denseMatrix"
x="diagonalMatrix"
x="dtrMatrix"
x="sparseMatrix"

getMethod สามารถใช้เพื่อดูซอร์สโค้ดของวิธีใดวิธีหนึ่ง:

> getMethod("chol2inv", "diagonalMatrix")
Method Definition:

function (x, ...) 
{
    chk.s(...)
    tcrossprod(solve(x))
}
<bytecode: 0x000000000ea2cc70>
<environment: namespace:Matrix>

Signatures:
        x               
target  "diagonalMatrix"
defined "diagonalMatrix"

นอกจากนี้ยังมีวิธีที่มีลายเซ็นที่ซับซ้อนมากขึ้นสำหรับแต่ละวิธีเช่น

require(raster)
showMethods(extract)
Function: extract (package raster)
x="Raster", y="data.frame"
x="Raster", y="Extent"
x="Raster", y="matrix"
x="Raster", y="SpatialLines"
x="Raster", y="SpatialPoints"
x="Raster", y="SpatialPolygons"
x="Raster", y="vector"

หากต้องการดูซอร์สโค้ดสำหรับวิธีใดวิธีหนึ่งเหล่านี้จะต้องระบุลายเซ็นทั้งหมดเช่น

getMethod("extract" , signature = c( x = "Raster" , y = "SpatialPolygons") )

มันจะไม่เพียงพอที่จะให้ลายเซ็นบางส่วน

getMethod("extract",signature="SpatialPolygons")
#Error in getMethod("extract", signature = "SpatialPolygons") : 
#  No method found for function "extract" and signature SpatialPolygons

ฟังก์ชันที่เรียกใช้ฟังก์ชันที่ไม่ได้เอ็กซ์พอร์ต

ในกรณีของts.union, .cbindtsและ.makeNamesTsมีฟังก์ชั่น unexported จากstatsnamespace คุณสามารถดูรหัสที่มาของฟังก์ชั่น unexported โดยใช้ผู้ประกอบการหรือ:::getAnywhere

> stats:::.makeNamesTs
function (...) 
{
    l <- as.list(substitute(list(...)))[-1L]
    nm <- names(l)
    fixup <- if (is.null(nm)) 
        seq_along(l)
    else nm == ""
    dep <- sapply(l[fixup], function(x) deparse(x)[1L])
    if (is.null(nm)) 
        return(dep)
    if (any(fixup)) 
        nm[fixup] <- dep
    nm
}
<bytecode: 0x38140d0>
<environment: namespace:stats>

ฟังก์ชันที่เรียกใช้โค้ดที่คอมไพล์แล้ว

โปรดทราบว่า "คอมไพล์" ไม่ได้อ้างถึงรหัส R ที่คอมไพล์ด้วยไบต์ที่สร้างขึ้นโดยแพ็คเกจคอมไพเลอร์ <bytecode: 0x294e410>สายในการส่งออกดังกล่าวข้างต้นแสดงให้เห็นว่าฟังก์ชั่นเป็นไบต์รวบรวมและคุณยังสามารถดูแหล่งที่มาจากบรรทัดคำสั่ง R ที่

ฟังก์ชั่นที่โทร.C, .Call, .Fortran, .External, .Internalหรือ.Primitiveจะเรียกจุดรายการในรหัสเรียบเรียงดังนั้นคุณจะต้องมองไปที่แหล่งที่มาของรหัสเรียบเรียงถ้าคุณต้องการที่จะเข้าใจการทำงาน นี้กระจก GitHub ของรหัส R แหล่งที่มาเป็นสถานที่ที่ดีที่จะเริ่มต้น ฟังก์ชั่นpryr::show_c_sourceนี้เป็นเครื่องมือที่มีประโยชน์เพราะจะพาคุณไปยังหน้า GitHub โดยตรง.Internalและ.Primitiveโทรออก แพคเกจอาจจะใช้.C, .Call, .Fortranและ.External; แต่ไม่ใช่.Internalหรือ.Primitiveเพราะสิ่งเหล่านี้ถูกใช้เพื่อเรียกใช้ฟังก์ชั่นที่สร้างไว้ในล่าม R

การเรียกใช้ฟังก์ชันข้างต้นบางอย่างอาจใช้วัตถุแทนสตริงอักขระเพื่ออ้างอิงฟังก์ชันที่รวบรวม ในกรณีที่วัตถุเป็นของชั้น"NativeSymbolInfo", "RegisteredNativeSymbol"หรือ"NativeSymbol"; และการพิมพ์วัตถุให้ข้อมูลที่เป็นประโยชน์ ตัวอย่างเช่นการoptimโทร.External2(C_optimhess, res$par, fn1, gr1, con)(โปรดทราบว่าC_optimhessไม่ใช่"C_optimhess") optimอยู่ในแพคเกจสถิติเพื่อให้คุณสามารถพิมพ์stats:::C_optimhessเพื่อดูข้อมูลเกี่ยวกับฟังก์ชั่นที่รวบรวมได้ที่ถูกเรียก

คอมไพล์รหัสในแพ็คเกจ

หากคุณต้องการดูโค้ดที่คอมไพล์แล้วในแพ็คเกจคุณจะต้องดาวน์โหลด / คลายรหัสแพ็กเกจ ไบนารีที่ติดตั้งไม่เพียงพอ ซอร์สโค้ดของแพ็คเกจนั้นมีอยู่ในที่เก็บ CRAN (หรือที่ใช้ร่วมกันได้กับ CRAN) ที่แพคเกจติดตั้งไว้ตั้งแต่แรก download.packages()ฟังก์ชั่นจะได้รับแพคเกจที่มาสำหรับคุณ

download.packages(pkgs = "Matrix", 
                  destdir = ".",
                  type = "source")

สิ่งนี้จะดาวน์โหลดเวอร์ชั่นต้นฉบับของแพ็คเกจ Matrix และบันทึก.tar.gzไฟล์ที่เกี่ยวข้องในไดเรกทอรีปัจจุบัน ซอร์สโค้ดสำหรับฟังก์ชั่นที่คอมไพล์สามารถพบได้ในsrcไดเรกทอรีของไฟล์ที่ไม่มีการบีบอัดและไม่ได้ทำการทดสอบ ขั้นตอนที่ไม่บีบอัดและไม่เปิดเผยสามารถทำได้นอกRหรือจากภายในRโดยใช้untar()ฟังก์ชั่น เป็นไปได้ที่จะรวมขั้นตอนการดาวน์โหลดและการขยายเข้าไปในการโทรครั้งเดียว (โปรดทราบว่าสามารถดาวน์โหลดและคลายแพ็กเกจได้ครั้งละหนึ่งแพ็คเกจเท่านั้น):

untar(download.packages(pkgs = "Matrix",
                        destdir = ".",
                        type = "source")[,2])

อีกทางหนึ่งหากการพัฒนาแพคเกจโฮสต์สาธารณะ (เช่นผ่านGitHub , R-ForgeหรือRForge.net ) คุณอาจเรียกดูซอร์สโค้ดออนไลน์ได้

คอมไพล์รหัสในแพ็คเกจพื้นฐาน

แพคเกจบางอย่างถือว่าเป็นแพคเกจ "ฐาน" แพคเกจเหล่านี้มาพร้อมกับ R และรุ่นของพวกเขาจะถูกขังอยู่กับรุ่นของอาร์ตัวอย่าง ได้แก่base, compiler, และstats utilsดังนั้นจึงไม่มีอยู่ในแพ็คเกจดาวน์โหลดแยกต่างหากบน CRAN ดังที่อธิบายไว้ข้างต้น แต่พวกเขาเป็นส่วนหนึ่งของต้นไม้ R /src/library/แหล่งที่มาในแพคเกจไดเรกทอรีของแต่ละบุคคลภายใต้ วิธีการเข้าถึงแหล่ง R ได้อธิบายไว้ในส่วนถัดไป

โค้ดที่คอมไพล์แล้วที่สร้างไว้ในตัวแปล R

หากคุณต้องการดูรหัสในตัวล่าม R คุณจะต้องดาวน์โหลด / แกะแหล่ง R; หรือคุณสามารถดูแหล่งที่มาออนไลน์ผ่านการวิจัยเก็บข้อมูลการโค่นล้มหรือกระจก GitHub วินสตันช้าง

บทความข่าวของ Uwe Ligges (PDF) (หน้า 43) เป็นข้อมูลอ้างอิงทั่วไปที่ดีเกี่ยวกับวิธีการดูซอร์สโค้ด.Internalและ.Primitiveฟังก์ชัน ขั้นตอนพื้นฐานจะดูครั้งแรกสำหรับชื่อฟังก์ชันในsrc/main/names.cแล้วค้นหา "C-รายการ" src/main/*ชื่อในแฟ้มใน


71
หากคุณใช้RStudioมันจะพยายามดึงแหล่งที่มาสำหรับฟังก์ชั่นเคอร์เซอร์ข้อความของคุณมากกว่าถ้าคุณกดF2ปุ่ม
Ari B. Friedman

1
@Ari B. Friedman ขออภัยสำหรับคำถามปลายนี้ RStudio จะดึงรหัสต้นฉบับของ C สำหรับฟังก์ชั่นหรือสำหรับฟังก์ชั่นที่เขียนด้วย R หรือไม่? ขอบคุณ
Sunny

3
@ ซามีร์ฉันเชื่อว่ามันเป็นเพียงแหล่ง R
Ari B. Friedman

@ AriB.Friedman - ขอบคุณอารีย์สิ่งนี้มีประโยชน์ ในกรณีของฉันฉันยังต้องการความรู้ที่แสดงในคำตอบ ( scaleซึ่งก็คือ S3 - ฉันได้UseMethod("scale")และใช้ไปแล้วgetAnywhere(scale.default)) แต่ฟังก์ชั่นธรรมดาทำงานได้ดี
Tomasz Gandor

2
การเลียนแบบเป็นคำเยินยออย่างจริงใจที่สุดฉันคิดว่าคำตอบนี้ / wiki มาก่อน :) ก่อนหน้านี้rfaqs.com/source-code-of-r-method
JimLohse

94

นอกเหนือจากคำตอบอื่น ๆ สำหรับคำถามนี้และคำซ้ำซ้อนนี่เป็นวิธีที่ดีในการรับซอร์สโค้ดสำหรับฟังก์ชันแพ็คเกจโดยไม่จำเป็นต้องทราบว่าบรรจุภัณฑ์ใดเป็นระบบเช่นถ้าเราต้องการซอร์สสำหรับrandomForest::rfcv():

วิธีดู / แก้ไขในหน้าต่างป๊อปอัป:

edit(getAnywhere('rfcv'), file='source_rfcv.r')

หากต้องการเปลี่ยนเส้นทางไปยังไฟล์แยกต่างหาก :

capture.output(getAnywhere('rfcv'), file='source_rfcv.r')

ยอมรับgetAnywhereเป็นอีกหนึ่งทางเลือกที่แปลกประหลาด R ชื่อสำหรับบางสิ่งบางอย่างที่ควรได้รับการเรียกfindOnSearchPathหรือคล้ายกัน
smci

1
ฉันจะถอนคำตอบนี้เพราะทำให้ฉันใกล้เคียงกับสิ่งที่ฉันต้องการ สิ่งที่ฉันต้องการจริงใน RStudio เป็นView(foo); ที่fooเป็นหน้าที่จากแพคเกจที่โหลดแล้ว
Sigfried

1
@Sigfried: edit()เปิดโปรแกรมแก้ไขข้อความ (เป็นทางเลือกของผู้ใช้)ในขณะที่View()เปิดโปรแกรมดูสเปรดชีตชนิด Excel สำหรับข้อมูลส่วนหลังเหมาะสำหรับการเรียกดูข้อมูล (หลายคอลัมน์) แต่โดยทั่วไปแล้วน่ากลัวสำหรับรหัสอื่น ๆ ตัวอย่างเช่นที่ฉันบอกใบ้โดยทั่วไปสิ่งแรกที่ฉันต้องการจะทำเมื่อเรียกดูฟังก์ชั่นคือข้าม / ยุบ / จำลองออกจากตรรกะการแยกวิเคราะห์และตรรกะการกระทำเริ่มต้นทั้งหมดเพื่อดูว่าฟังก์ชันทำอะไร
smci

25

มันจะถูกเปิดเผยเมื่อคุณดีบักโดยใช้ฟังก์ชัน debug () สมมติว่าคุณต้องการดูโค้ดพื้นฐานในฟังก์ชัน t () การโอนย้าย เพียงพิมพ์ 't' ไม่เปิดเผยมาก

>t 
function (x) 
UseMethod("t")
<bytecode: 0x000000003085c010>
<environment: namespace:base>

แต่ด้วยการใช้ 'debug (functionName)' มันจะแสดงรหัสที่ซ่อนอยู่ภายใน

> debug(t)
> t(co2)
debugging in: t(co2)
debug: UseMethod("t")
Browse[2]> 
debugging in: t.ts(co2)
debug: {
    cl <- oldClass(x)
    other <- !(cl %in% c("ts", "mts"))
    class(x) <- if (any(other)) 
        cl[other]
    attr(x, "tsp") <- NULL
    t(x)
}
Browse[3]> 
debug: cl <- oldClass(x)
Browse[3]> 
debug: other <- !(cl %in% c("ts", "mts"))
Browse[3]> 
debug: class(x) <- if (any(other)) cl[other]
Browse[3]>  
debug: attr(x, "tsp") <- NULL
Browse[3]> 
debug: t(x)

แก้ไข: debugonce () สำเร็จเหมือนกันโดยไม่ต้องใช้ undebug ()


ข้อเสียของวิธีนี้เมื่อเปรียบเทียบกับที่ให้ไว้ในคำตอบที่ยอมรับคือคุณต้องมีการเรียกใช้ฟังก์ชันการทำงาน (พารามิเตอร์ที่จำเป็นทั้งหมดที่ระบุไว้ยอมรับได้); และนอกเหนือจากบล็อกเริ่มต้นของรหัสแล้วคุณยังได้รับแต่ละบล็อกในเวลาที่เรียกใช้ นี่เป็นวิธีที่ยอดเยี่ยมสำหรับการแก้ไขข้อบกพร่อง แต่ไม่เหมาะสำหรับการรับแหล่งที่มา
Brian Diggs

ใช่มันไม่ดีที่สุด แต่ถ้าคุณฉลาดคุณจะได้แหล่งที่มาที่รวดเร็วและสกปรกโดยเฉพาะอย่างยิ่งสำหรับฟังก์ชั่นที่สร้างขึ้น
Selva

2
ฉันขอแนะนำให้ใช้debugonceแทนdebugในกรณีนี้
Joshua Ulrich

20

สำหรับฟังก์ชั่นที่ไม่ใช่แบบดั้งเดิม R base จะมีฟังก์ชันที่เรียกbody()ว่าคืนเนื้อความของฟังก์ชัน ตัวอย่างเช่นแหล่งที่มาของprint.Date()ฟังก์ชั่นสามารถดูได้:

body(print.Date)

จะผลิตสิ่งนี้:

{
    if (is.null(max)) 
        max <- getOption("max.print", 9999L)
    if (max < length(x)) {
        print(format(x[seq_len(max)]), max = max, ...)
        cat(" [ reached getOption(\"max.print\") -- omitted", 
            length(x) - max, "entries ]\n")
    }
    else print(format(x), max = max, ...)
    invisible(x)
}

หากคุณกำลังทำงานในสคริปต์และต้องการรหัสฟังก์ชันเป็นแบบเวกเตอร์อักขระคุณสามารถรับได้

capture.output(print(body(print.Date)))

คุณจะได้รับ:

[1] "{"                                                                   
[2] "    if (is.null(max)) "                                              
[3] "        max <- getOption(\"max.print\", 9999L)"                      
[4] "    if (max < length(x)) {"                                          
[5] "        print(format(x[seq_len(max)]), max = max, ...)"              
[6] "        cat(\" [ reached getOption(\\\"max.print\\\") -- omitted\", "
[7] "            length(x) - max, \"entries ]\\n\")"                      
[8] "    }"                                                               
[9] "    else print(format(x), max = max, ...)"                           
[10] "    invisible(x)"                                                    
[11] "}"     

ทำไมฉันถึงต้องการทำสิ่งนั้น? ฉันสร้างวัตถุ S3 แบบกำหนดเอง ( xที่class(x) = "foo") ตามรายการ หนึ่งในสมาชิกรายการ (ชื่อ "สนุก") เป็นฟังก์ชั่นและฉันต้องการที่print.foo()จะแสดงรหัสที่มาของฟังก์ชั่นเยื้อง ดังนั้นฉันจึงลงเอยด้วยตัวอย่างต่อไปนี้ในprint.foo():

sourceVector = capture.output(print(body(x[["fun"]])))
cat(paste0("      ", sourceVector, "\n"))

x[["fun"]]ซึ่งเยื้องและแสดงรหัสที่เกี่ยวข้องกับ


18

ไม่เห็นว่าวิธีนี้สอดคล้องกับการไหลของคำตอบหลักได้อย่างไร แต่ทำให้ฉันชะงักไปชั่วขณะหนึ่งดังนั้นฉันจึงเพิ่มที่นี่:

ผู้ประกอบการมัด

หากต้องการดูรหัสที่มาของผู้ประกอบการบางฐานมัด (เช่น%%, %*%, %in%), การใช้งานgetAnywhereเช่น:

getAnywhere("%%")
# A single object matching ‘%%’ was found
# It was found in the following places
#   package:base
#   namespace:base
#  with value
#
# function (e1, e2)  .Primitive("%%")

คำตอบหลักครอบคลุมถึงวิธีใช้กระจกเพื่อขุดให้ลึกขึ้น


6
คำตอบ smci ของgetAnywhereแนะนำ หรือคุณก็สามารถใช้ backticks `%in%`ถ้าคุณรู้อยู่แล้วว่าชื่อของผู้ประกอบการ:
Joshua Ulrich

3
@JoshuaUlrich ไม่รู้ว่าคุณสามารถใช้ backticks ได้! ขอบคุณ getAnywhereมีการกล่าวถึงในคำตอบของคุณเช่นกัน แต่ฉันคิดว่าการอ้างอิงเฉพาะกับ infix นั้นมีประโยชน์สำหรับการอ้างอิงในอนาคตสำหรับคำตอบนี้ - ฉันได้อ่านหน้านี้หลายครั้งและยังคงสับสนเล็กน้อยที่พยายามค้นหารหัสสำหรับฟังก์ชันดังกล่าวสำหรับ ในขณะที่ - และฉันไม่คิดว่ามันเหมาะสมกับการไหลของคำตอบอื่น ๆ (ซึ่งทั้งคู่ใช้getAnywhereเพื่อจุดประสงค์อื่น)
MichaelChirico

10

มีฟังก์ชั่นที่ใช้งานง่ายมากใน R edit

new_optim <- edit(optim)

มันจะเปิดซอร์สโค้ดของoptimโดยใช้โปรแกรมแก้ไขที่ระบุไว้ในอาร์เอสและจากนั้นคุณสามารถแก้ไขได้และกำหนดฟังก์ชั่นการแก้ไขให้options new_optimฉันชอบฟังก์ชั่นนี้มากในการดูโค้ดหรือเพื่อแก้ไขข้อบกพร่องของโค้ดเช่นพิมพ์ข้อความหรือตัวแปรบางอย่างหรือแม้แต่กำหนดให้กับตัวแปรทั่วโลกสำหรับการตรวจสอบเพิ่มเติม (แน่นอนคุณสามารถใช้debug)

หากคุณเพียงแค่ต้องการดูซอร์สโค้ดและไม่ต้องการซอร์สโค้ดแบบยาวที่น่ารำคาญที่พิมพ์บนคอนโซลของคุณคุณสามารถใช้

invisible(edit(optim))

เห็นได้ชัดว่านี่ไม่สามารถใช้เพื่อดูซอร์สโค้ด C / C ++ หรือ Fortran

BTW editสามารถเปิดวัตถุอื่น ๆ เช่นรายการเมทริกซ์ ฯลฯ ซึ่งจะแสดงโครงสร้างข้อมูลที่มีแอตทริบิวต์เช่นกัน deสามารถใช้ฟังก์ชั่นเพื่อเปิดตัว excel อย่างเช่นตัวแก้ไข (ถ้า GUI รองรับ) เพื่อแก้ไขเมทริกซ์หรือเฟรมข้อมูลและส่งคืนอันใหม่ สิ่งนี้มีประโยชน์บางครั้ง แต่ควรหลีกเลี่ยงในกรณีปกติโดยเฉพาะอย่างยิ่งเมื่อเมทริกซ์ของคุณใหญ่


3
วิธีการนี้จะแสดงแหล่งที่มาของฟังก์ชั่นเดียวกับที่พิมพ์ฟังก์ชั่นที่ให้ (นั่นคือเหมือนกับในคำถาม) รับเพิ่มเติม / ลึกกว่านั้นคือสิ่งที่คำถามนี้เกี่ยวกับ
Brian Diggs

2
@BrianDiggs ใช่คุณพูดถูก ฉันไม่ได้ตั้งใจตอบคำถามเพราะโจชัวให้คำตอบที่สมบูรณ์ ฉันแค่พยายามเพิ่มสิ่งที่เกี่ยวข้องกับหัวข้อน่าสนใจและอาจเป็นประโยชน์ที่จะรู้
Eric

8

ตราบใดที่ฟังก์ชั่นนั้นเขียนด้วย pure R ไม่ใช่ C / C ++ / Fortran เราอาจใช้สิ่งต่อไปนี้ มิฉะนั้นวิธีที่ดีที่สุดคือการดีบั๊กและใช้ " กระโดด เข้า ":

> functionBody(functionName)

2
bodyนี้เป็นเช่นเดียวกับ เป็นidentical(functionBody, body) TRUE
Joshua Ulrich

1
base::bodyและmethods::functionBodyแม้ว่าพวกเขาจะไม่ชอบที่จะถูก detahed bodyอาจถูกแทนที่ด้วย: rdocumentation.org/search?q=body
Moody_Mudskipper

7

ใน RStudio มี (อย่างน้อย) 3 วิธี:

  1. กดปุ่ม F2 ในขณะที่เคอร์เซอร์อยู่บนฟังก์ชั่นใด ๆ
  2. คลิกที่ชื่อฟังก์ชั่นในขณะที่กดปุ่ม Ctrl หรือ Command
  3. View(function_name) (ตามที่ระบุข้างต้น)

บานหน้าต่างใหม่จะเปิดขึ้นพร้อมกับรหัสที่มา หากคุณไปถึง. แบบเร่งด่วนหรือ. C คุณจะต้องมีวิธีอื่นขออภัย


5

View([function_name])- เช่น. View(mean)ตรวจสอบให้แน่ใจว่าใช้ตัวพิมพ์ใหญ่ [V] รหัสอ่านอย่างเดียวจะเปิดในเครื่องมือแก้ไข


5

คุณยังสามารถลองใช้print.function()ซึ่งเป็น S3 ทั่วไปเพื่อรับฟังก์ชั่นการเขียนในคอนโซล


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