Wie wird der Quellcode der Funktion R .Internal oder .Primitive angezeigt?


80

Keiner von diesen zeigt den Quellcode der pnormFunktion,

stats:::pnorm
getAnywhere(pnorm)  

Wie kann ich den Quellcode von sehen pnorm?

sum
 (..., na.rm = FALSE)  .Primitive("sum")
.Primitive("sum")
function (..., na.rm = FALSE)  .Primitive("sum")
methods(sum)
no methods were found

und wie kann ich den Quellcode der sumFunktion sehen?

Antworten:


95

Der R-Quellcode von pnormlautet:

function (q, mean = 0, sd = 1, lower.tail = TRUE, log.p = FALSE) 
.Call(C_pnorm, q, mean, sd, lower.tail, log.p)

Also, technisch gesehen, die Eingabe von „Pnorm“ tut zeigen Sie den Quellcode. Nützlicher jedoch: Die Eingeweide von pnormsind in C codiert, sodass der Hinweis im Quellcode der vorherigen Frage in R nur am Rande nützlich ist (der größte Teil konzentriert sich auf Funktionen, die in Namespaces usw. verborgen sind).

Der Artikel von Uwe Ligges in den R-Nachrichten (S. 43) ist eine gute allgemeine Referenz. Aus diesem Dokument:

Beim Betrachten des R-Quellcodes werden manchmal Aufrufe einer der folgenden Funktionen angezeigt: .C (), .Call (), .Fortran (), .External () oder .Internal () und .Primitive (). Diese Funktionen rufen Einstiegspunkte in kompilierten Code auf, z. B. gemeinsam genutzte Objekte, statische Bibliotheken oder dynamische Linkbibliotheken. Daher ist es notwendig, die Quellen des kompilierten Codes zu untersuchen, wenn ein vollständiges Verständnis des Codes erforderlich ist. ... Der erste Schritt besteht darin, den Einstiegspunkt in der Datei '$ R HOME / src / main / names.c' nachzuschlagen, wenn die aufrufende R-Funktion entweder .Primitive () oder .Internal () ist. Dies geschieht im folgenden Beispiel für den Code, der die 'einfache' R-Funktionssumme () implementiert.

(Hervorhebung hinzugefügt, da die genaue Funktion, nach der Sie gefragt haben ( sum), in Ligges 'Artikel behandelt wird.)

Je nachdem, wie ernst Sie sich mit dem Code befassen möchten, kann es sich lohnen, den Quellcode herunterzuladen und zu entpacken, wie es Ligges vorschlägt (dann können Sie beispielsweise Befehlszeilentools verwenden, um beispielsweise grepden Quellcode zu durchsuchen). Für eine ungezwungenere Überprüfung können Sie die Quellen online über den R Subversion-Server oder den Github-Spiegel von Winston Chang anzeigen (Links hier sind speziell zu src/nmath/pnorm.c). (Um den richtigen Ort zu finden, src/nmath/pnorm.cmuss man sich mit der Struktur des R-Quellcodes vertraut machen.)

meanund sumsind beide in summary.c implementiert .


1
Es ist in einer anderen Kategorie als pnorm. Versuchen Sie es mean.defaultmit dem R-Code und github.com/wch/r-source/blob/trunk/src/main/summary.c für den C-Code. Und lesen Sie den oben verlinkten Artikel von Uwe Ligges!
Ben Bolker

1
Nur um dieser Antwort nachzugehen: Möglicherweise müssen Sie auch in C oder Fortran auf den genauen Funktionsnamen achten. Beispiel: Ich habe versucht, nach der Quelle zu suchen stl, die diese Zeile aufruft : z <- .Fortran(C_stl, x, n, as.integer(period), as.integer(s.window). Also suchte ich vergeblich im Github-Spiegel, der oben mit dem Schlüsselwort verknüpft war C_stl. Wenn ich jedoch suche, stlgibt es eine Datei namens, stl.fdie ich finden möchte. Das Mitnehmen ist, dass der Dateiname .c oder .f möglicherweise nicht genau mit dem aufgerufenen Funktionsnamen übereinstimmt.
Yuqli

35

Ich weiß, dass dieser Beitrag älter als 2 Jahre ist, aber ich dachte, dass dies für einige Benutzer nützlich sein könnte, die diese Frage durchsuchen.

Ich kopiere im Grunde nur meine Antwort auf diese andere ähnliche Frage, damit sie sich für einige R-Benutzer, die die C-Quelldateien untersuchen möchten, als nützlich erweisen kann.

  1. Erstens können Sie mit pryr die show_c_sourceFunktion verwenden, die auf GitHub den relevanten Code in den C-Quelldateien sucht. Funktioniert für interne und primäre Funktionen.

    body(match.call)
    
    # .Internal(match.call(definition, call, expand.dots))
    
    pryr::show_c_source(.Internal(match.call(definition, call, expand.dots)))
    

    Damit gelangen Sie zu dieser Seite , die unique.cdie Funktion do_matchcall enthält .

  2. Ich habe diese tabulatorgetrennte Datei zusammengestellt , auf der names.cDatei aufgebaut und mithilfe von Find-in-Dateien den Speicherort des Quellcodes ermittelt. Es gibt einige Funktionen mit plattformspezifischen Dateien und einige andere, für die es mehr als eine Datei mit relevantem Quellcode gibt. Im Übrigen ist das Mapping zumindest für die aktuelle Version (3.1.2) ziemlich gut etabliert.


Pryr funktioniert nicht, als ich versuchte, C-Codes zu finden für system: pryr::show_c_source(.Internal(system(x))), Ich bekamError: Could not find entry for system
Zhanxw

7
> methods(mean)
[1] mean.data.frame mean.Date       mean.default    mean.difftime   mean.IDate*    
[6] mean.POSIXct    mean.POSIXlt    mean.yearmon*   mean.yearqtr*  

   Non-visible functions are asterisked
> mean.default
function (x, trim = 0, na.rm = FALSE, ...) 
{
    if (!is.numeric(x) && !is.complex(x) && !is.logical(x)) {
        warning("argument is not numeric or logical: returning NA")
        return(NA_real_)
    }
    if (na.rm) 
        x <- x[!is.na(x)]
    if (!is.numeric(trim) || length(trim) != 1L) 
        stop("'trim' must be numeric of length one")
    n <- length(x)
    if (trim > 0 && n) {
        if (is.complex(x)) 
            stop("trimmed means are not defined for complex data")
        if (any(is.na(x))) 
            return(NA_real_)
        if (trim >= 0.5) 
            return(stats::median(x, na.rm = FALSE))
        lo <- floor(n * trim) + 1
        hi <- n + 1 - lo
        x <- sort.int(x, partial = unique(c(lo, hi)))[lo:hi]
    }
    .Internal(mean(x))
}
<bytecode: 0x155ef58>
<environment: namespace:base>

Dies scheint nicht die ursprüngliche Frage des OP (über pnorm) zu beantworten , sondern deren Kommentar unten über mean- und beachten Sie, dass dies auch unten in C-Code fällt (siehe meinen Kommentar unten).
Ben Bolker

2
Tatsächlich. Und die "richtige Antwort" ist die, die Sie zuvor gegeben haben ... lesen Sie den Artikel von Uwe Ligges in RNews.
IRTFM
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.