2012-12-26 13 views
62

Nessuno di questi mostrano il codice sorgente di pnorm funzione,Come vedere il codice sorgente della funzione R. Interno o .Primitiva?

stats:::pnorm 
getAnywhere(pnorm) 

Come posso vedere il codice sorgente di pnorm?

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

e, come è possibile visualizzare il codice sorgente della funzione sum?

risposta

74

Il codice sorgente R di pnorm è:

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

Quindi, tecnicamente parlando, digitando "pnorm" fa vi mostrano il codice sorgente. Tuttavia, più efficacemente: le viscere di pnorm sono codificate in C, quindi il consiglio nella domanda precedente view source code in R è solo marginalmente utile (la maggior parte si concentra su funzioni nascoste in spazi dei nomi ecc.).

Uwe Ligges article in R news (pagina 43) è un buon riferimento generale. Da quel documento:

Se si guarda a codice sorgente R, a volte chiamate ad una delle seguenti funzioni presentarsi: .C(), .Call(), .Fortran(), .External(), o .Internal() e .Primitive(). Queste funzioni chiamano i punti di ingresso nel codice compilato come oggetti condivisi, librerie statiche o librerie di collegamento dinamico. Pertanto, è necessario esaminare le origini del codice compilato, se la completa comprensione del codice è richiesta . ... Il primo passo è cercare il punto di ingresso nel file '$ R HOME/src/main/names.c', se la funzione R chiamante è .Primitive() o .Internal() . Questo viene fatto nel seguente esempio per il codice che implementa la funzione R semplice ' sum().

(Il corsivo è perché la funzione precisa hai chiesto (sum) è coperto in articolo di Ligges.)

A seconda di quanto seriamente si vuole scavare nel codice, può valere la pena scaricare e decomprimere il codice sorgente come suggerisce Ligges (ad esempio, è possibile utilizzare gli strumenti da riga di comando come grep per cercare attraverso il codice sorgente). Per ulteriori ispezioni casuali, è possibile visualizzare le fonti online tramite R Subversion server o Winston Chang's github mirror (i collegamenti qui sono specificatamente a src/nmath/pnorm.c). (Indovinare il posto giusto per cercare, src/nmath/pnorm.c, richiede una certa familiarità con la struttura del codice sorgente R.)

mean e sum sono entrambi implementati in summary.c.

+1

si trova in una categoria diversa da 'pnorm'. Prova "mean.default" per il codice R e https://github.com/wch/r-source/blob/trunk/src/main/summary.c per il codice C. E leggi l'articolo di Uwe Ligges linkato sopra! –

6
> 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> 
+0

Questo sembra non rispondere alla domanda originale dell'OP (su 'pnorm'), ma il loro commento qui sotto su' mean' - e nota che questo rientra anche nel codice C, in basso (vedi il mio commento sotto). –

+1

Infatti. E la "risposta corretta" è quella che hai dato in precedenza ... leggi l'articolo di Uwe Ligges in RNews. –

23

So che questo post ha più di 2 anni, ma ho pensato che questo potesse essere utile ad alcuni utenti che navigano attraverso questa domanda.

In pratica sto semplicemente copiando la mia risposta allo this other similar question in modo che possa rivelarsi utile per alcuni utenti R che desiderano esplorare i file di origine C.

  1. In primo luogo, con pryr si può fare utilizzare la funzione show_c_source che cercare su GitHub pezzo rilevante del codice nei file sorgente C. Funziona per. Funzioni interne e .Primitive.

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

    che porta a this page, dimostrando che unique.c contiene la funzione do_matchcall.

  2. Ho messo insieme questo tab delimited file, costruendo sul file names.c e utilizzando find-a-file per determinare la posizione del codice sorgente. Esistono alcune funzioni con file specifici della piattaforma e una manciata di altre per le quali esiste più di un file con codice sorgente pertinente. Ma per il resto la mappatura è abbastanza consolidata, almeno per la versione attuale (3.1.2).

Problemi correlati