Wie sieht man den Quellcode von R .Internal oder .Primitive function?

Keiner von diesen zeigt den Quellcode der pnorm function,

 stats:::pnorm getAnywhere(pnorm) 

Wie kann ich den Quellcode von 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 Quellcode der sum ?

   

Der R-Quellcode von pnorm lautet:

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

Technisch gesprochen, zeigt die Eingabe von “pnorm” den Quellcode. Allerdings sinnvoller: Die Eingeweide von pnorm sind in C codiert, so dass der Hinweis in der vorherigen Frage Quellcode in R nur peripher nützlich ist (der größte Teil konzentriert sich auf functionen, die in Namespaces usw. versteckt sind).

Uwe Ligges Artikel in R news (S. 43) ist eine gute allgemeine Referenz. Aus diesem Dokument:

Bei der Betrachtung von R-Quellcode werden manchmal Aufrufe an eine der folgenden functionen angezeigt: .C (), .Call (), .Fortran (), .External () oder .Internal () und .Primitive (). Diese functionen rufen Einstiegspunkte in kompiliertem Code auf, z. B. gemeinsam genutzte Objekte, statische Bibliotheken oder dynamische Linkbibliotheken. Daher ist es notwendig, in die Quellen des kompilierten Codes zu schauen, 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-function entweder .Primitive () oder .Internal () ist. Dies geschieht im folgenden Beispiel für den Code, der die ‘einfache’ R-function sum () implementiert.

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

Je nachdem, wie ernsthaft Sie in den Code eindringen möchten, lohnt es sich, den Quellcode herunterzuladen und zu entpacken, wie Ligges es vorschlägt (Sie können beispielsweise Befehlszeilenprogramme wie grep , um den Quellcode zu durchsuchen). Zur einfacheren Überprüfung können Sie die Quellen online über den R Subversion-Server oder den Github-Mirror von Winston Chang anzeigen (die Links sind hier speziell für src/nmath/pnorm.c ). (Die richtige Stelle zu src/nmath/pnorm.c , src/nmath/pnorm.c , benötigt etwas Vertrautheit mit der Struktur des R-Quellcodes.)

mean und sum sind beide in summary.c implementiert.

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

Ich kopiere im Grunde nur meine Antwort auf diese andere ähnliche Frage, so dass sie sich für einige R-Benutzer, die die C-Quelldateien erkunden wollen, als nützlich erweisen kann.

  1. Zunächst können Sie mit pryr die function show_c_source verwenden, die auf GitHub den relevanten Code in den C-Quelldateien sucht. functioniert für .Internale und .Primitive functionen.

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

    Was bringt Sie zu dieser Seite , die zeigt, dass unique.c die function do_matchcall enthält.

  2. Ich habe diese names.c Datei zusammengestellt, die auf der Datei names.c und find-in-files verwendet , um den Speicherort des Quellcodes zu bestimmen. Es gibt einige functionen, die plattformspezifische Dateien enthalten, und eine Handvoll anderer, 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.

 > 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)) }