Quiero ver el código fuente de una función para ver cómo funciona. Sé que puedo imprimir una función escribiendo su nombre en el indicador:
> t
function (x)
UseMethod("t")
<bytecode: 0x2332948>
<environment: namespace:base>
En este caso, ¿qué UseMethod("t")
significa? ¿Cómo encuentro el código fuente que realmente está siendo utilizado, por ejemplo t(1:10)
:?
¿Hay alguna diferencia entre cuando veo UseMethod
y cuando veo standardGeneric
y showMethods
, como con 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.
En otros casos, puedo ver que se están llamando funciones R, pero no puedo encontrar el código fuente para esas funciones.
> 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
¿Cómo encuentro funciones como .cbindts
y .makeNamesTs
?
En otros casos, hay un poco de código R, pero la mayor parte del trabajo parece hacerse en otro lugar.
> 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")
¿Cómo averiguo qué hace la .Primitive
función? Del mismo modo, algunas funciones llaman .C
, .Call
, .Fortran
, .External
, o .Internal
. ¿Cómo puedo encontrar el código fuente para esos?
Respuestas:
UseMethod("t")
te dice quet()
es un ( S3 función genérica ) que tiene métodos para diferentes clases de objetos.El sistema de despacho del método S3
Para las clases S3, puede usar la
methods
función para enumerar los métodos para una función o clase genérica en particular."Las funciones no visibles están marcadas con un asterisco" significa que la función no se exporta desde el espacio de nombres de su paquete. Aún puede ver su código fuente a través de la
:::
función (es decirstats:::t.ts
), o usandogetAnywhere()
.getAnywhere()
es útil porque no tiene que saber de qué paquete proviene la función.El sistema de despacho del método S4
El sistema S4 es un sistema de envío de método más nuevo y es una alternativa al sistema S3. Aquí hay un ejemplo de una función S4:
La salida ya ofrece mucha información.
standardGeneric
es un indicador de una función S4. El método para ver los métodos S4 definidos se ofrece de manera útil:getMethod
se puede usar para ver el código fuente de uno de los métodos:También hay métodos con firmas más complejas para cada método, por ejemplo
Para ver el código fuente de uno de estos métodos, debe proporcionarse la firma completa, p. Ej.
No será suficiente proporcionar la firma parcial
Funciones que llaman funciones no exportadas
En el caso de
ts.union
,.cbindts
y.makeNamesTs
son funciones no exportadas delstats
espacio de nombres. Puede ver el código fuente de funciones no exportadas utilizando el:::
operador ogetAnywhere
.Funciones que llaman código compilado
Tenga en cuenta que "compilado" no se refiere al código R compilado en bytes creado por el paquete del compilador . La
<bytecode: 0x294e410>
línea en la salida anterior indica que la función está compilada en bytes, y aún puede ver la fuente desde la línea de comando R.Funciones esa llamada
.C
,.Call
,.Fortran
,.External
,.Internal
, o.Primitive
están llamando a los puntos de entrada en el código compilado, por lo que tendrá que buscar en las fuentes del código compilado, si se quiere entender completamente la función. Este espejo GitHub del código fuente R es un lugar decente para comenzar. La funciónpryr::show_c_source
puede ser una herramienta útil, ya que le llevará directamente a una página de GitHub para.Internal
y.Primitive
llamadas. Los paquetes pueden utilizar.C
,.Call
,.Fortran
, y.External
; pero no.Internal
o.Primitive
porque se usan para llamar a funciones integradas en el intérprete R.Las llamadas a algunas de las funciones anteriores pueden usar un objeto en lugar de una cadena de caracteres para hacer referencia a la función compilada. En esos casos, el objeto es de la clase
"NativeSymbolInfo"
,"RegisteredNativeSymbol"
o"NativeSymbol"
; e imprimir el objeto produce información útil. Por ejemplo,optim
llamadas.External2(C_optimhess, res$par, fn1, gr1, con)
(tenga en cuenta queC_optimhess
no"C_optimhess"
).optim
está en el paquete de estadísticas, por lo que puede escribirstats:::C_optimhess
para ver información sobre la función compilada que se llama.Código compilado en un paquete
Si desea ver el código compilado en un paquete, deberá descargar / desempaquetar la fuente del paquete. Los binarios instalados no son suficientes. El código fuente de un paquete está disponible en el mismo repositorio CRAN (o compatible con CRAN) desde el que se instaló originalmente el paquete. La
download.packages()
función puede obtener la fuente del paquete por usted.Esto descargará la versión fuente del paquete Matrix y guardará el
.tar.gz
archivo correspondiente en el directorio actual. El código fuente para las funciones compiladas se puede encontrar en elsrc
directorio del archivo sin comprimir y sin tartar. El paso de descompresión y descompresión se puede realizar desde afueraR
o desde adentroR
usando launtar()
función. Es posible combinar el paso de descarga y expansión en una sola llamada (tenga en cuenta que solo un paquete a la vez se puede descargar y desempaquetar de esta manera):Alternativamente, si el desarrollo del paquete está alojado públicamente (por ejemplo, a través de GitHub , R-Forge o RForge.net ), probablemente pueda buscar el código fuente en línea.
Código compilado en un paquete base
Ciertos paquetes se consideran paquetes "básicos". Estos paquetes se envían con R y su versión se bloquea en la versión de R. Los ejemplos incluyen
base
,compiler
,stats
, yutils
. Como tales, no están disponibles como paquetes descargables por separado en CRAN como se describió anteriormente. Más bien, son parte del árbol de origen R en directorios de paquetes individuales en/src/library/
. Cómo acceder a la fuente R se describe en la siguiente sección.Código compilado integrado en el intérprete R
Si desea ver el código incorporado en el intérprete de R, deberá descargar / desempaquetar las fuentes de R; o puede ver las fuentes en línea a través del repositorio R Subversion o el espejo github de Winston Chang .
El artículo de noticias R de Uwe Ligges (PDF) (p. 43) es una buena referencia general de cómo ver el código fuente
.Internal
y las.Primitive
funciones. Los pasos básicos son buscar primero el nombre de la funciónsrc/main/names.c
y luego buscar el nombre de "entrada C" en los archivos desrc/main/*
.fuente
RStudio
, intentará extraer la fuente de la función sobre la que termina el cursor de texto si presiona laF2
tecla.scale
que es S3: obtuveUseMethod("scale")
y luego lo uségetAnywhere(scale.default)
). Pero las funciones simples funcionan bien.Además de las otras respuestas a esta pregunta y sus duplicados, esta es una buena manera de obtener el código fuente para una función de paquete sin necesidad de saber en qué paquete está. Por ejemplo, si queremos la fuente para
randomForest::rfcv()
:Para verlo / editarlo en una ventana emergente:
Para redirigir a un archivo separado :
fuente
View(foo)
; dondefoo
fue una función de un paquete ya cargado.edit()
abre un editor de texto (a elección del usuario) , mientras queView()
abre un visor de hoja de cálculo de tipo Excel para datos , este último es bueno para examinar datos (multicolumnares), pero generalmente es terrible para el código de cualquier otra cosa que no sea la longitud del juguete. Por ejemplo, como insinúo, generalmente lo primero que quiero hacer al examinar una función es omitir / colapsar / descartar toda la lógica de análisis de argumentos y acción predeterminada, para ver qué hace realmente la función .Se revela cuando depura usando la función debug (). Suponga que desea ver el código subyacente en la función de transposición t (). Simplemente escribiendo 't', no revela mucho.
Pero, al usar el 'debug (functionName)', revela el código subyacente, sin los elementos internos.
EDITAR: debugonce () logra lo mismo sin tener que usar undebug ()
fuente
debugonce
lugar dedebug
en este caso.Para funciones no primitivas, R base incluye una función llamada
body()
que devuelve el cuerpo de la función. Por ejemploprint.Date()
, se puede ver la fuente de la función:producirá esto:
Si está trabajando en un script y quiere el código de función como un vector de caracteres, puede obtenerlo.
te conseguirá:
¿Por qué querría hacer algo así? Estaba creando un objeto S3 personalizado (
x
, dondeclass(x) = "foo"
) basado en una lista. Uno de los miembros de la lista (llamado "diversión") era una función y queríaprint.foo()
mostrar el código fuente de la función, sangrado. Así que terminé con el siguiente fragmento enprint.foo()
:que sangra y muestra el código asociado con
x[["fun"]]
.fuente
No vi cómo esto encajaba en el flujo de la respuesta principal, pero me dejó perplejo por un tiempo, así que lo agrego aquí:
Operadores de infijo
Para ver el código fuente de algunos operadores infijos base (por ejemplo,
%%
,%*%
,%in%
), el usogetAnywhere
, por ejemplo:La respuesta principal cubre cómo usar los espejos para cavar más profundo.
fuente
getAnywhere
. O usted podría utilizar acentos abiertos si ya conoce el nombre del operador:`%in%`
.getAnywhere
también se menciona en su respuesta, pero creo que una referencia específica a infix es útil para referencia futura a esta respuesta: he leído esta página muchas veces y todavía estaba un poco perplejo tratando de encontrar código para tales funciones para un while, y no pensé que encajara en el flujo de ninguna otra respuesta (que ambas están usandogetAnywhere
para otro propósito).Hay una función muy útil en R
edit
Se abrirá el código fuente del
optim
uso del editor especificado en Roptions
, y luego podrá editarlo y asignarle la función modificadanew_optim
. Me gusta mucho esta función para ver el código o para depurar el código, por ejemplo, imprimir algunos mensajes o variables o incluso asignarlos a variables globales para una mayor investigación (por supuesto, puede usardebug
).Si solo desea ver el código fuente y no desea que se imprima el molesto código fuente largo en su consola, puede usar
Claramente, esto no se puede usar para ver el código fuente de C / C ++ o Fortran.
Por cierto,
edit
puede abrir otros objetos como lista, matriz, etc., que luego muestra la estructura de datos con atributos también. La funciónde
se puede utilizar para abrir un editor similar a Excel (si la GUI lo admite) para modificar la matriz o el marco de datos y devolver el nuevo. Esto es útil a veces, pero debe evitarse en el caso habitual, especialmente cuando la matriz es grande.fuente
Mientras la función esté escrita en R puro, no en C / C ++ / Fortran, se puede usar lo siguiente. De lo contrario, la mejor manera es depurar y usar " saltar a ":
fuente
body
.identical(functionBody, body)
esTRUE
.base::body
ymethods::functionBody
, aunque no es probable que los separen.body
también podría ser anulado: rdocumentation.org/search?q=bodyEn RStudio, hay (al menos) 3 formas:
View
(nombre_función) (como se indicó anteriormente)Se abrirá un nuevo panel con el código fuente. Si llega a .Primitive o .C necesitará otro método, lo siento.
fuente
View([function_name])
- p.ej.View(mean)
Asegúrese de usar mayúsculas [V]. El código de solo lectura se abrirá en el editor.fuente
También puede intentar usar
print.function()
, que es S3 genérico, para que la función escriba en la consola.fuente
print.function()
Es un método S3 . El genérico esprint()
. Y generalmente no es una buena idea llamar a los métodos directamente. Eso anula todo el propósito de las funciones genéricas y el envío de métodos.