Pregunta

Cuando emprendo un proyecto de I de cualquier complejidad, mis guiones obtener rápidamente largo y confuso.

¿Cuáles son algunas de las prácticas que pueden adoptar para que mi código siempre será un placer trabajar con ellos? Estoy pensando en cosas como

  • La colocación de funciones en archivos de origen
  • Cuando romper algo a otro archivo fuente
  • ¿Cuál debería ser en el archivo maestro
  • Uso de funciones como unidades de organización (si esto vale la pena teniendo en cuenta que R hace que sea difícil acceder estado global)
  • prácticas
  • sangría / salto de línea.
    • Treat (como {?
    • Poner cosas similares)} en 1 o 2 líneas?

Básicamente, ¿cuáles son sus reglas generales para la organización de grandes guiones R?

¿Fue útil?

Solución

La respuesta estándar es el uso de paquetes - ver el Escribir extensiones R Manual así como diferentes tutoriales en la web.

Se le da

  • una manera casi automática de organizar el código por tema
  • le recomienda escribir un archivo de ayuda, por lo que se piensa en la interfaz
  • una gran cantidad de comprobaciones de sanidad a través de R CMD check
  • la oportunidad de añadir pruebas de regresión
  • así como un medio para espacios de nombres.

source() Sólo se ejecuta sobre el código funciona para fragmentos muy cortos. Todo lo demás debe estar en un paquete - incluso si usted no tiene intención de publicarla como se puede escribir paquetes internos aplicables a los registros internos.

En cuanto a la parte de 'cómo editar', el funcionamiento interno de I manual tiene excelentes codificación R normas en la sección 6. de lo contrario, tienden a utilizar los valores predeterminados en Emacs modo ESS .

Actualización 2008-Ago-13: David Smith acaba de blogs sobre el Guía de google R Estilo .

Otros consejos

Me gusta poner una funcionalidad diferente en sus propios archivos.

Pero no me gusta sistema de paquetes de R. Es bastante difícil de usar.

Yo prefiero una alternativa ligera, para colocar las funciones de un archivo dentro de un entorno (lo que cualquier otro lenguaje llama un "espacio de nombres") y adjuntarlo. Por ejemplo, he hecho un grupo 'util' de las funciones de este modo:

util = new.env()

util$bgrep = function [...]

util$timeit = function [...]

while("util" %in% search())
  detach("util")
attach(util)

Esto es todo en un archivo util.R . Cuando la fuente él, se obtiene el medio ambiente 'util' para que pueda llamar util$bgrep() y tal; pero por otra parte, la llamada attach() hace tan solo bgrep() y tal trabajo directamente. Si usted no puso todas esas funciones en su propio entorno, que habían contaminan espacio de nombres de primer nivel del intérprete (el que ls() espectáculos).

Yo estaba tratando de simular el sistema de Python, donde cada archivo es un módulo. Eso sería mejor tener, pero esto parece que está bien.

Esto puede sonar un poco obvio, especialmente si eres un programador, pero existen algunas cosas que pienso en unidades lógicas y físicas de código.

No sé si este es su caso, pero cuando estoy trabajando en I, que rara vez comienzan con un gran programa complejo en mente. Por lo general comienzan en una secuencia de comandos y código separado en unidades lógicamente separables, a menudo utilizando funciones. La manipulación de datos y el código de visualización quedan colocados en sus propias funciones, etc. Y esas funciones se agrupan en una sección del archivo (manipulación de datos en la parte superior, a continuación, la visualización, etc.). En última instancia, usted quiere pensar acerca de cómo hacer que sea más fácil para usted para mantener su guión y bajar la tasa de defectos.

Como bien / grano grueso a hacer sus funciones variarán y hay varias reglas de oro: por ejemplo, 15 líneas de código, o "una función debe ser responsable de hacer una tarea que se identifica por su nombre", etc. Su kilometraje puede variar. Puesto que R no soporta llamada por referencia, estoy suelen variar de hacer mis funciones demasiado grano fino cuando implica el paso de tramas de datos o estructuras similares alrededor. Pero esto puede ser una sobrecompensación de algunos errores tontos de rendimiento cuando empecé a cabo con R.

Cuando para extraer las unidades lógicas en sus propias unidades físicas (como archivos de origen y las agrupaciones más grandes, como paquetes)? Tengo dos casos. En primer lugar, si el archivo se hace demasiado grande y el desplazamiento alrededor de entre las unidades no relacionadas lógicamente es una molestia. En segundo lugar, si tengo funciones que pueden ser reutilizados por otros programas. Por lo general comienzan a cabo mediante la colocación de alguna unidad agrupada, dicen las funciones de manipulación de datos, todo esto en un archivo separado. Puedo entonces la fuente de este archivo desde cualquier otro script.

Si va a desplegar sus funciones, entonces usted necesita para empezar a pensar acerca de los paquetes. Yo no se despliegan código R en la producción o para su reutilización por otros, por diversas razones (por poco tiempo: la cultura org prefiere otros langauges, las preocupaciones sobre el rendimiento, GPL, etc). Además, tiendo a refinar y añadir a mis colecciones de archivos sourced constantemente, y yo prefiero no tratar sobre los paquetes cuando hago un cambio. Por lo tanto usted debe comprobar las otras respuestas relacionadas de paquetes, como Dirk, para más detalles sobre este frente.

Por último, creo que su pregunta no es necesariamente particular, a R. Verdaderamente recomiendo la lectura de código completo de Steve McConnell, que contiene una gran cantidad de sabiduría acerca de estas cuestiones y prácticas de codificación en general.

Estoy de acuerdo con el consejo Dirk! En mi humilde opinión, la organización de los programas de secuencias de comandos simples para paquetes documentados es, para la programación en R, como el cambio de la Palabra de TeX / LaTeX para escribir. Recomiendo a echar un vistazo a los Creación de paquetes de gran utilidad R: Un tutorial por Friedrich Leisch.

Mi respuesta concisa:

  1. Escriba sus funciones con cuidado, la identificación de los productos e insumos suficientes generales;
  2. Limite el uso de variables globales;
  3. objetos Uso S3 y, donde, objetos S4 apropiadas;
  4. Poner las funciones en paquetes, especialmente cuando sus funciones están llamando C / Fortran.

Creo que R es cada vez más utilizada en la producción, por lo que la necesidad de código reutilizable es mayor que antes. Me parece que el intérprete mucho más robusto que antes. No hay duda de que R es 100-300x más lento que C, pero por lo general el cuello de botella se concentra alrededor de unas pocas líneas de código, que pueden delegarse a C / C ++. Creo que sería un error de delegar los puntos fuertes de R en la manipulación de datos y el análisis estadístico a otro idioma. En estos casos, la penalización en el rendimiento es bajo, y en todo caso vale la pena el ahorro en el esfuerzo de desarrollo. Si solo el tiempo de ejecución fuera el caso, estaríamos todos ensamblador escrito.

He tenido la intención de encontrar la manera de escribir los paquetes pero no han invertido el tiempo. Para cada uno de mis mini-proyectos guardo todas mis funciones de bajo nivel en una carpeta llamada 'funciones /', y la fuente de ellas en un espacio de nombres separado que se crea de forma explícita.

Las siguientes líneas de código va a crear un entorno llamado "myfuncs" en la ruta de búsqueda si no existe ya (usando adjuntar), y rellenarlo con las funciones contenidas en los archivos .R en mis funciones '/' directorio (utilizando sys.source). Yo suelo poner estas líneas en la parte superior de mi script principal destinado a la "interfaz de usuario" de la que se conocen como funciones de alto nivel (invocando las funciones de bajo nivel).

if( length(grep("^myfuncs$",search()))==0 )
  attach("myfuncs",pos=2)
for( f in list.files("functions","\\.r$",full=TRUE) )
  sys.source(f,pos.to.env(grep("^myfuncs$",search())))

Cuando se realizan cambios puede volver a la fuente siempre con las mismas líneas, o usar algo como

evalq(f <- function(x) x * 2, pos.to.env(grep("^myfuncs$",search())))

para evaluar adiciones / modificaciones en el medio ambiente que ha creado.

Es kludgey lo sé, pero evita tener que ser demasiado formal al respecto (pero si tienes la oportunidad lo hago fomentar el sistema de paquetes - esperemos que migrará de esa manera en el futuro)

.

En cuanto a las convenciones de codificación, esto es lo único que he visto en cuanto a la estética (me gustan y sin apretar sigo, pero yo no uso demasiadas llaves en I):

http://www1.maths.lth.se/help/R/RCC /

Hay otros "convenciones" en relación con el uso de [, gota = FALSO] y <- como el operador de asignación sugerido en diversas presentaciones (por lo general la tónica) en el usuario! conferencias, pero no creo que ninguno de estos son estricta (aunque el [, gota = FALSO] es útil para los programas en los que usted no está seguro de la entrada que espera).

Me apunto como otra persona a favor de los paquetes. Voy a admitir a ser bastante pobre en la escritura de páginas de manual y viñetas hasta que si / cuando tengo que (es decir, de ser liberado), pero lo hace para una forma práctica real para agrupar DOE fuente. Además, si usted consigue serio sobre el mantenimiento de su código, los puntos que nos lleva a Dirk todo entra en plya.

También estoy de acuerdo. Utilice la función package.skeleton () para empezar. Incluso si piensa que su código no se puede ejecutar de nuevo, puede ayudar a motivarle para crear código más general que podría ahorrarle tiempo después.

En cuanto a acceder al entorno global, es fácil con el << - operador, aunque no se recomienda.

no haber aprendido cómo escribir paquetes sin embargo, siempre he organizado por abastecimiento de guiones sub. Su similar a clases de escritura, pero no tan complicado. No es programáticamente elegante pero encuentro construyo análisis a través del tiempo. Una vez que tengo una sección grande que trabaja a menudo moverlo a un guión diferente y simplemente la fuente él, ya que utilizará los objetos del espacio de trabajo. Tal vez lo que necesito para importar datos de varias fuentes, clasificar todos ellos y encontrar las intersecciones. Yo podría poner esa sección en un script adicional. Sin embargo, si desea distribuir su "aplicación" para otras personas, o se utiliza alguna entrada interactiva, un paquete es probablemente una buena ruta. Como investigador rara vez necesito para distribuir mi código de análisis, sino que a menudo la necesidad de aumentar o modificar la misma.

También he estado buscando el Santo Grial del flujo de trabajo adecuado para la elaboración de un gran proyecto de I. He encontrado el año pasado este paquete llamado rsuite , y, desde luego, era lo que busca. Este paquete de R fue desarrollado expresamente para la implementación de grandes proyectos de I pero he encontrado que se puede utilizar para pequeñas, medianas y grandes proyectos de I tamaño. Voy a dar enlaces a ejemplos del mundo real en un minuto (más abajo), pero primero quiero explicar el nuevo paradigma de la construcción de proyectos de I con rsuite.

Nota. No soy el creador o desarrollador de rsuite.

  1. Hemos estado haciendo proyectos malo en rstudio; el objetivo no debe ser la creación de un proyecto o un paquete, pero de un alcance más amplio. En rsuite crear un super-proyecto o proyecto principal, que tiene el proyectos de I y R paquetes estándar, en todas las combinaciones posibles.

  2. Al tener un súper proyecto de I usted no necesita más Unix make para gestionar los niveles más bajos de los proyectos de I debajo; R utiliza secuencias de comandos en la parte superior. Deja que te enseñe. Cuando se crea un proyecto principal rsuite, se obtiene esta estructura de carpetas:

introducir descripción de la imagen aquí

  1. El R carpeta es donde pones las secuencias de comandos de gestión de proyectos, los que reemplazarán a make.

  2. El packages carpeta es la carpeta donde rsuite contiene todos los paquetes que componen el super-proyecto. También puede copiar y pegar un paquete que no es accesible desde internet, y rsuite va a construir también.

  3. deployment la carpeta es donde rsuite escribirá todos los binarios de paquetes que fueron indicados en los paquetes de archivos DESCRIPTION. Por lo tanto, esto hace que, por sí mismo, que proyectas tiempo accros totalmente reproducible.

  4. rsuite viene con un cliente para todos los sistemas operativos. Los he probado. Pero también se puede instalar como un addin para rstudio.

  5. rsuite también le permite crear una instalación conda aislado en su propia conda carpeta. Esto no es un medio sino una instalación de Python física derivada de Anaconda en su máquina. Esto funciona junto con SystemRequirements de R, desde donde se podía instalar todos los paquetes de Python que desee, desde cualquier canal Conda desea.

  6. También puede crear repositorios locales para tirar R paquetes cuando no esté conectado, o quiere construir todo el asunto más rápido.

  7. Si lo desea, también se puede construir el proyecto de I como un archivo zip y compartirlo con colegas. Se ejecutará, proporcionando a sus colegas tienen instalada la misma versión R.

  8. Otra opción es la construcción de un contenedor de todo el proyecto en Ubuntu, Debian, o CentOS. Así, en lugar de compartir un archivo zip con su proyecto de construcción, que comparte todo el contenedor Docker con su proyecto listo para funcionar.

He estado experimentando mucho con rsuite buscando completa reproducibilidad, y no depender de los paquetes que se instala en el entorno global. Esto está mal, porque tan pronto como se instala una actualización de paquete, el proyecto, más a menudo que no, deja de funcionar, especialmente aquellos paquetes con llamadas muy específicas para una función con ciertos parámetros.

Lo primero que empecé a experimentar con los ebooks era bookdown. Nunca he tenido la suerte de tener un bookdown para sobrevivir a la prueba del tiempo durante más de seis meses. Por lo tanto, lo que he hecho es convertir el proyecto original de bookdown seguir el marco rsuite. Ahora, yo no tengo que preocuparme por actualizar mi gloR bal medio ambiente, debido a que el proyecto tiene su propio conjunto de paquetes en la carpeta deployment.

El siguiente que hice fue crear proyectos de aprendizaje automático sino en la forma rsuite. Un maestro, la orquestación de proyecto en la parte superior, y todos los sub-proyectos y paquetes a estar bajo el control del maestro. Realmente cambia la forma de código con R, lo que hace más productivo.

Después de eso empecé a trabajar en un nuevo paquete de mina llamada rTorch. Esto fue posible, en gran parte, debido a rsuite; que permite pensar a lo grande.

Un consejo sin embargo. Aprender rsuite no es fácil. Debido a que presenta una nueva forma de crear proyectos de I, se siente duro. No consternación por los primeros intentos, continúe subiendo la pendiente hasta que lo hagas. Se requiere un conocimiento avanzado de su sistema operativo y de su sistema de archivos.

espero que un día RStudio nos permite generar proyectos que orquestan como rsuite hace desde el menú. Sería increíble.

Enlaces:

RSuite GitHub repo

r4ds bookdown

Keras y brillante tutorial

moderndive-libro-rsuite

interpretable_ml-rsuite

IntroMachineLearningWithR-rsuite

clark-intro_ml-rsuite

Hyndman-bookdown-rsuite

statistical_rethinking-rsuite

fread-parámetros de referencia con rsuite

DataViz-rsuite

menor segmentación-H2O-tutorial

telco-cliente-mantequera-tutorial

sclerotinia_rsuite

R está bien para uso interactivo y pequeñas secuencias de comandos, pero no lo utilizaría para un programa grande. Que haría uso de un lenguaje de la corriente principal de la mayor parte de la programación y se envuelve en una interfaz R.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top