Je veux regarder le code source d'une fonction pour voir comment cela fonctionne. Je sais que je peux imprimer une fonction en tapant son nom à l'invite:
> t
function (x)
UseMethod("t")
<bytecode: 0x2332948>
<environment: namespace:base>
Dans ce cas, qu'est-ce que cela UseMethod("t")
signifie? Comment puis-je trouver le code source actuellement utilisé par, par exemple t(1:10)
:?
Y a-t-il une différence entre quand je vois UseMethod
et quand je vois standardGeneric
et showMethods
, comme avec 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.
Dans d'autres cas, je peux voir que les fonctions R sont appelées, mais je ne trouve pas le code source de ces fonctions.
> 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
Comment trouver des fonctions comme .cbindts
et .makeNamesTs
?
Dans d'autres cas encore, il y a un peu de code R, mais la plupart du travail semble être fait ailleurs.
> 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")
Comment savoir ce que fait la .Primitive
fonction? De même, certaines fonctions appellent .C
, .Call
, .Fortran
, .External
ou .Internal
. Comment puis-je trouver le code source de ceux-ci?
Réponses:
UseMethod("t")
vous indique qu'ilt()
s'agit d'une fonction générique ( S3 ) qui a des méthodes pour différentes classes d'objets.Le système de répartition de la méthode S3
Pour les classes S3, vous pouvez utiliser la
methods
fonction pour répertorier les méthodes d'une fonction ou classe générique particulière."Les fonctions non visibles sont marquées d'un astérisque" signifie que la fonction n'est pas exportée depuis l'espace de noms de son package. Vous pouvez toujours voir son code source via la
:::
fonction (iestats:::t.ts
), ou en utilisantgetAnywhere()
.getAnywhere()
est utile car vous n'avez pas besoin de savoir de quel paquet provient la fonction.Le système de répartition de la méthode S4
Le système S4 est un nouveau système de répartition des méthodes et une alternative au système S3. Voici un exemple de fonction S4:
La sortie offre déjà beaucoup d'informations.
standardGeneric
est un indicateur d'une fonction S4. La méthode pour voir les méthodes S4 définies est offerte utilement:getMethod
peut être utilisé pour voir le code source de l'une des méthodes:Il existe également des méthodes avec des signatures plus complexes pour chaque méthode, par exemple
Pour voir le code source de l'une de ces méthodes, la signature entière doit être fournie, par exemple
Il ne suffira pas de fournir la signature partielle
Fonctions qui appellent des fonctions non exportées
Dans le cas de
ts.union
,.cbindts
et.makeNamesTs
sont des fonctions non exportées de l'stats
espace de noms. Vous pouvez afficher le code source des fonctions non exportées à l'aide de l':::
opérateur ougetAnywhere
.Fonctions qui appellent du code compilé
Notez que "compilé" ne fait pas référence au code R compilé en octets tel que créé par le package du compilateur . La
<bytecode: 0x294e410>
ligne dans la sortie ci-dessus indique que la fonction est compilée en octets, et vous pouvez toujours afficher la source à partir de la ligne de commande R.Fonctions appel
.C
,.Call
,.Fortran
,.External
,.Internal
ou.Primitive
appellent des points d'entrée dans le code compilé, de sorte que vous devrez regarder les sources du code compilé si vous voulez comprendre la fonction. Ce miroir GitHub du code source R est un bon endroit pour commencer. La fonctionpryr::show_c_source
peut être un outil utile car elle vous mènera directement à une page GitHub pour.Internal
et.Primitive
appels. Les packages peuvent utiliser.C
,.Call
,.Fortran
et.External
; mais pas.Internal
ou.Primitive
, car ceux-ci sont utilisés pour appeler des fonctions intégrées à l'interpréteur R.Les appels à certaines des fonctions ci-dessus peuvent utiliser un objet au lieu d'une chaîne de caractères pour référencer la fonction compilée. Dans ces cas, l'objet est de classe
"NativeSymbolInfo"
,"RegisteredNativeSymbol"
ou"NativeSymbol"
; et l'impression de l'objet fournit des informations utiles. Par exemple, lesoptim
appels.External2(C_optimhess, res$par, fn1, gr1, con)
(notez queC_optimhess
pas le cas"C_optimhess"
).optim
est dans le package de statistiques, vous pouvez donc taperstats:::C_optimhess
pour voir les informations sur la fonction compilée appelée.Code compilé dans un package
Si vous souhaitez afficher le code compilé dans un package, vous devrez télécharger / décompresser la source du package. Les binaires installés ne sont pas suffisants. Le code source d'un package est disponible à partir du même référentiel CRAN (ou compatible CRAN) à partir duquel le package a été initialement installé. le
download.packages()
fonction peut obtenir la source du package pour vous.Cela va télécharger la version source du package Matrix et enregistrer le
.tar.gz
fichier correspondant dans le répertoire actuel. Le code source des fonctions compilées se trouve dans lesrc
répertoire du fichier non compressé et non taré. L'étape de décompression et de décompression peut être effectuée à l'extérieurR
ou à l'intérieur deR
launtar()
fonction. Il est possible de combiner l'étape de téléchargement et d'extension en un seul appel (notez qu'un seul package à la fois peut être téléchargé et décompressé de cette manière):Alternativement, si le développement du package est hébergé publiquement (par exemple via GitHub , R-Forge ou RForge.net ), vous pouvez probablement parcourir le code source en ligne.
Code compilé dans un package de base
Certains packages sont considérés comme des packages «de base». Ces paquets sont livrés avec R et leur version est verrouillé à la version des exemples R. comprennent
base
,compiler
,stats
etutils
. En tant que tels, ils ne sont pas disponibles en tant que packages téléchargeables séparés sur CRAN comme décrit ci-dessus. Ils font plutôt partie de l'arborescence source R dans les répertoires de packages individuels sous/src/library/
. Comment accéder à la source R est décrit dans la section suivante.Code compilé intégré à l'interpréteur R
Si vous souhaitez afficher le code intégré à l'interpréteur R, vous devrez télécharger / décompresser les sources R; ou vous pouvez afficher les sources en ligne via le référentiel R Subversion ou le miroir github de Winston Chang .
L' article de presse R d' Uwe Ligges (PDF) (p. 43) est une bonne référence générale sur la façon d'afficher le code source
.Internal
et les.Primitive
fonctions. Les étapes de base consistent à rechercher d'abord le nom de la fonction danssrc/main/names.c
, puis à rechercher le nom "C-entry" dans les fichiers desrc/main/*
.la source
RStudio
, il tentera d'extraire la source de la fonction sur laquelle se trouve votre curseur de texte si vous appuyez sur laF2
touche.scale
, qui est S3 - que j'ai acquiseUseMethod("scale")
puis utiliséegetAnywhere(scale.default)
). Mais les fonctions simples fonctionnent très bien.En plus des autres réponses à cette question et ses doublons, voici un bon moyen d'obtenir le code source d'une fonction de package sans avoir besoin de savoir dans quel package elle se trouve. Par exemple, si nous voulons la source pour
randomForest::rfcv()
:Pour l' afficher / le modifier dans une fenêtre contextuelle:
Pour rediriger vers un fichier distinct :
la source
View(foo)
; oùfoo
était une fonction d'un package déjà chargé.edit()
ouvre un éditeur de texte (au choix de l'utilisateur) , alors qu'ilView()
ouvre un visualiseur de type Excel pour les données , ce dernier est bon pour parcourir les données (multi-colonnes), mais généralement terrible pour le code autre que la longueur du jouet. Par exemple , comme j'allusion à, généralement la première chose que je veux faire lorsque vous naviguez sur une fonction de saut / effondrement / factice toutes les arg-analyse syntaxique et logique action par défaut, pour voir ce que la fonction fait fait .Il est révélé lorsque vous déboguez à l'aide de la fonction debug (). Supposons que vous souhaitiez voir le code sous-jacent dans la fonction de transposition t (). Le simple fait de taper 't' ne révèle pas grand-chose.
Mais, en utilisant le 'debug (functionName)', il révèle le code sous-jacent, sans les internes.
EDIT: debugonce () accomplit la même chose sans avoir à utiliser undebug ()
la source
debugonce
au lieu dedebug
dans ce cas.Pour les fonctions non primitives, R base inclut une fonction appelée
body()
qui renvoie le corps de la fonction. Par exemple, la source de laprint.Date()
fonction peut être consultée:produira ceci:
Si vous travaillez dans un script et que vous souhaitez que le code de fonction soit un vecteur de caractères, vous pouvez l'obtenir.
vous obtiendrez:
Pourquoi voudrais-je faire une telle chose? Je créais un objet S3 personnalisé (
x
, oùclass(x) = "foo"
) basé sur une liste. Un des membres de la liste (nommé "fun") était une fonction et je voulaisprint.foo()
afficher le code source de la fonction, en retrait. Je me suis donc retrouvé avec l'extrait de code suivant dansprint.foo()
:qui indente et affiche le code associé à
x[["fun"]]
.la source
Je n'ai pas vu comment cela s'inscrivait dans le flux de la réponse principale, mais cela m'a embarrassé pendant un moment, donc je l'ajoute ici:
Opérateurs Infix
Pour voir le code source de certains opérateurs infixes de base (par exemple
%%
,%*%
,%in%
), l' utilisationgetAnywhere
, par exemple:La réponse principale couvre comment utiliser ensuite les miroirs pour creuser plus profondément.
la source
getAnywhere
. Ou vous pouvez simplement utiliser si vous connaissez des accents graves déjà le nom de l'opérateur:`%in%`
.getAnywhere
est également mentionné dans votre réponse, mais je pense qu'une référence spécifique à infixe est utile pour une référence future à cette réponse - j'ai lu cette page plusieurs fois et j'étais encore un peu perplexe en essayant de trouver du code pour de telles fonctions pour un tandis que - et je ne pensais pas que cela s'inscrivait dans le flux de l'une ou l'autre autre réponse (qui sont toutes deux utiliséesgetAnywhere
dans un autre but).Il y a une fonction très pratique dans R
edit
Il ouvrira le code source de l'
optim
utilisation de l'éditeur spécifié dans les Roptions
, puis vous pourrez le modifier et affecter la fonction modifiée ànew_optim
. J'aime beaucoup cette fonction pour afficher le code ou déboguer le code, par exemple, imprimer certains messages ou variables ou même les affecter à des variables globales pour une enquête plus approfondie (bien sûr, vous pouvez utiliserdebug
).Si vous souhaitez simplement afficher le code source et ne souhaitez pas que le long code source ennuyeux soit imprimé sur votre console, vous pouvez utiliser
De toute évidence, cela ne peut pas être utilisé pour afficher le code source C / C ++ ou Fortran.
BTW,
edit
peut ouvrir d'autres objets comme la liste, la matrice, etc., qui montre également la structure des données avec des attributs. La fonctionde
peut être utilisée pour ouvrir un éditeur de type Excel (si l'interface graphique le prend en charge) pour modifier la matrice ou le bloc de données et renvoyer le nouveau. Ceci est parfois pratique, mais devrait être évité dans les cas habituels, en particulier lorsque votre matrice est grande.la source
Tant que la fonction est écrite en R pur et non en C / C ++ / Fortran, on peut utiliser ce qui suit. Sinon, la meilleure façon est de déboguer et d'utiliser " jump into ":
la source
body
.identical(functionBody, body)
estTRUE
.base::body
etmethods::functionBody
, bien qu'ils ne soient pas susceptibles d'être détruits.body
pourrait également être annulé: rdocumentation.org/search?q=bodyDans RStudio, il y a (au moins) 3 façons:
View
(nom_fonction) (comme indiqué ci-dessus)Un nouveau volet s'ouvre avec le code source. Si vous atteignez .Primitive ou .C, vous aurez besoin d'une autre méthode, désolé.
la source
View([function_name])
- par exemple.View(mean)
Assurez-vous d'utiliser des majuscules [V]. Le code en lecture seule s'ouvrira dans l'éditeur.la source
Vous pouvez également essayer d'utiliser
print.function()
, qui est générique S3, pour obtenir l'écriture de la fonction dans la console.la source
print.function()
est une méthode S3 . Le générique estprint()
. Et ce n'est généralement pas une bonne idée d'appeler directement des méthodes. Cela va à l'encontre de l'objectif des fonctions génériques et de la répartition des méthodes.