¿Es una buena práctica llamar a funciones en un paquete a través de:


Estoy escribiendo algunas funciones R que emplean algunas funciones útiles en otros paquetes como stringr y base64enc. ¿Es bueno no llamar a library(...) o require(...) para cargar estos paquetes primero, sino usar :: para referirse directamente a la función que necesito, como stringr::str_match(...)?

¿Es una buena práctica en general? O ¿qué problema podría inducir?

Author: smci, 2014-04-23

1 answers

Todo depende del contexto.

:: es principalmente necesario si hay colisiones de espacio de nombres, funciones de paquetes diferentes con el mismo nombre. Cuando carga el paquete dplyr, proporciona una función filter, que choca con (y enmascara) la función filter cargada por defecto en el paquete stats. Así que si quiero usar la versión stats de la función, necesitaré llamarla con stats::filter. Esto también da motivación para no cargar muchos paquetes. Si realmente solo desea una función de un paquete, puede ser mejor usar :: que cargar todo el paquete, especialmente si sabe que el paquete enmascarará otras funciones que desea usar.

No en código, sino en texto, encuentro :: muy útil. Es mucho más conciso escribir stats::filter que "la función filter en el paquete stats".

Desde una perspectiva de rendimiento , hay un precio (muy) pequeño para usar ::. Martin Maechler escribió (en la lista de correo de r-devel (Sept 2017))

Mucha gente parece olvidar que cada uso de :: es una R llamar a la función y usarla es ineficiente en comparación con solo usar el nombre ya importado.

La penalización de rendimiento es muy pequeña, del orden de unos pocos microsegundos, por lo que solo es una preocupación cuando se necesita código altamente optimizado. Ejecutar una línea de código que usa :: un millón de veces tomará uno o dos segundos más que el código que no usa ::.

En cuanto a la portabilidad, es bueno cargar explícitamente paquetes en la parte superior de un script porque hace que sea fácil echar un vistazo a las primeras líneas y ver qué paquetes se necesitan, instalándolos si es necesario antes de profundizar demasiado en cualquier otra cosa, es decir, llegar a la mitad de un largo proceso que ahora no se puede completar sin comenzar de nuevo.

Aparte: se puede hacer un argumento similar para preferir library() sobre require(). La biblioteca causará un error y se detendrá si el paquete no está allí, mientras que require avisará pero continuará. Si su código tiene un plan de contingencia en caso de que el paquete no esté allí, entonces por todos los medios use if (require(package)) ..., pero si su código fallará sin un paquete, debe usar library(package) en la parte superior para que falle temprano y claramente. (Gracias a Hugh y BondedDust en los comentarios.)

Escribiendo su propio paquete

La solución general es hacer su propio paquete que imports los otros paquetes que necesita usar en el archivo de DESCRIPCIÓN. Esos paquetes se instalarán automáticamente cuando su paquete esté instalado, por lo que puede usar pkg::fun internamente. O, al importarlos también en el archivo NAMESPACE, puede import un paquete completo o selectivamente importFrom funciones específicas y no necesita ::. Las opiniones difieren al respecto. El miembro de R-Core Martin Maechler (la misma fuente de r-devel que la anterior) dice:

Personalmente tengo la impresión de que:: es mucho "sobreutilizado" hoy en día, sobre todo en los paquetes donde defensor using importFrom () in NAMESPACE, so all this happens en el tiempo de carga del paquete, y luego no usando :: en el paquete fuentes en sí.

Por otro lado, el destacado desarrollador de paquetes Hadley Wickham dice en su R Packages book :

Es común que los paquetes se listen en Imports en DESCRIPTION, pero no en NAMESPACE. De hecho, esto es lo que recomiendo: listar el paquete en DESCRIPTION para que esté instalado, luego siempre referirse a él explícitamente con pkg::fun(). A menos que haya una fuerte razón para no hacerlo, es mejor ser explícito.

Con dos estimados expertos en R que dan recomendaciones opuestas, creo que es justo decir que debe elegir el estilo que más le convenga y satisfaga sus necesidades de claridad, eficiencia y capacidad de mantenimiento.


Si con frecuencia se encuentra usando solo una función de otro paquete, puede copiar el código y agregarlo a su propio paquete. Por ejemplo, tengo un paquete para personal use eso toma prestado %nin% del paquete Hmisc porque creo que es una gran función, pero no uso a menudo nada más de Hmisc. Con roxygen2, es fácil agregar @author y @references para atribuir correctamente el código para una función prestada. También asegúrese de que las licencias de los paquetes sean compatibles al hacer esto.

 34
Author: Gregor,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-08-01 15:52:34