[MÚSICA] [MÚSICA] [MÚSICA] Es muy común que quizá nos aparezcan errores en nuestro código. A veces podemos intentar resolver esto utilizando funciones como print para encontrar dónde pudiera estar el error. En R tenemos un conjunto de herramientas que nos pueden ayudar a poder localizar mucho más rápido un error y, además, también hay algunas técnicas que nos pueden ayudar a depurar cuando you hay un error de manera más rápida. Es justo eso lo que veremos en esta lección. Este es el flujo que se debe llevar a cabo para hacer una depuración. En primer lugar tenemos que darnos cuenta que hay un error, muchas veces ni siquiera sabemos eso. Esto va a depender de los tipos de mensajes de error que nosotros enviemos, por ejemplo, cuando no estemos introduciendo los parámetros correctos a una función. Una vez que sepamos que hay un error tenemos que saber bien cómo reproducirlo. Esto es un poco complicado a veces porque, como you hemos visto, muchas ocasiones, las funciones que estamos utilizando no son completamente terminísticas sino pueden ser aleatorias. Entonces, puede ser complicado encontrar un error en ese tipo de funciones. Para eso es recomendable utilizar funciones como set seed para llevar siempre a cabo el mismo, los mismos números aleatorios que pueden llevarnos a reproducir el problema. Una vez que you encontramos el problema y lo pudimos reproducir, entonces, debemos encontrar en qué parte del código está llevándose a cabo ese error y, una vez habiéndolo encontrado, tenemos que arreglarlo y volver a probar para ver que se haya resuelto. Una consideración importante cuando estemos escribiendo código en R y que you hemos hecho énfasis anteriormente es que las funciones tengan un tamaño adecuado, que no sean demasiado largas porque esto lo que provocan es que cuando haya algún tipo de problema sea difícil encontrarlo. Por ejemplo, hemos visto que es muy bueno que las funciones no pasen de una página, y si pasan más de una página podemos entonces repartirla en funciones más pequeñas donde así nos será más fácil encontrar errores o problemas cuando estos se presenten. En R Studio tenemos 3 herramientas que nos pueden servir muchísimo para llevar a cabo la depuración de nuestro código. La primera es Traceback, que nos ayuda a regresar los pasos que se han llevado a cabo hasta que encuentra el que nos está ocasionando el problema. Luego, también dentro de R studio hay otro que se conoce como Rerun and Debug, que lo que hace es que vuelve a correr el código de tal manera que cuando se empiece a ejecutar, uno puede ir llevando a cabo, paso por paso, las líneas del código de tal manera que pudiéramos probar línea por línea, y Breakpoints, que lo podemos mandar a llamar utilizando la función Breakpoints dentro de R Studio. Por ejemplo, en esta definición de las funciones f, g, h e i, podemos ver que no son más que las llamadas de una detrás de otra y, cuando llamamos a la función f con el parámetro 10, nos genera un error. En R Studio se genera entonces un error en color rojo y nos da 2 opciones. La primera es Show traceback, que es justamente el uso de la herramienta traceback, y la otra es Rerun and debug, que es justamente este modo interactivo donde nosotros podemos llevar a cabo la corrida paso por paso de nuestro código. Si damos clic en la opción Show traceback, lo que podemos ver es que nos aparece toda la pila de las llamadas de las funciones que se han llevado a cabo. Esta se debe leer de abajo hacia arriba. Si la leemos así, podemos llegar al punto donde se rompe el programa o donde se encuentra el error. En este caso, justamente, cuando se llama la función i. En el caso de que el error hubiera sido provocado en alguna función que hubiera sido cargada con la función source, este modo de R Studio nos permitiría darle clic al archivo donde están definidas las funciones que nos están dando el error. A veces esto es suficiente para poder encontrar el error y arreglarlo, pero otras esto no es posible. Para eso, necesitamos entonces, tal vez un modo más interactivo, que nos permita entonces poder llevar a cabo una depuración más fina de lo que está pasando. A este modo o herramienta para llevar a cabo este tipo de trabajo se el conoce como un debugger o depurador. Este nos permite correr el programa o la parte donde estamos teniendo el error paso a paso, para que así podamos nosotros hacer pruebas dentro de este modo para tratar de poder localizar el error también. Si nosotros queremos entrar en ese modo, entonces tenemos que darle clic a la opción de Rerun and Debug. En este modo nosotros tenemos 5 comandos básicos, que pueden ser utilizados con las teclas. El primero es n, que nos permite ejecutar el siguiente comando; s, que da paso a la siguiente función para ejecutarse; f, que termina el bucle actual o la función que se estuviera ejecutando; c, que continúa ejecutándose normalmente y q para salirse de esa consola. El uso de esta consola y sus comandos podrán manipularlos en la práctica. Para finalizar este tema de depuración hablaremos de la programación defensiva. Esta es una aproximación a la escritura del código de tal manera que los errores se generen pronto, para así, una vez que tenemos un error, se genere un mensaje que nos indique de manera clara que algo está fallando. Esto se puede hacer de 3 manera. La primera es checar que los parámetros de entrada sean los correctos. Es muy común, por ejemplo, que cuando tenemos funciones que no sean vectorizadas, estar utilizando dentro de estas funciones funciones que sí lo son. Entonces tenemos que checar los valores de entrada que sean de manera correcta, utilizando ifs o la función stop para parar cuando haya un error de este tipo. La segunda es evitar la evaluación no estándar. Esto es muy común cuando utilizamos funciones como subset, transform o with, que son funciones muy útiles cuando estamos utilizándolas de manera interactiva porque hacen suposiciones sobre los tipos pero que no mandan muchos mensajes informativos cuando pudiera haber una falla. Es por eso que debemos evitarlas cuando estemos escribiendo código que va a ser utilizado por alguien más. La tercera es evitar funciones que nos regresen diferentes tipos de salida. En este caso, es muy común que nos suceda cuando utilizamos el operador corchete o la función sapply. Para evitar esto, cuando utilicemos el operador corchete, podemos utilizar el parámetro Drop igual a False para que no nos haga un tipo de cambio de clase. Por ejemplo, cuando hacemos una extracción de una matriz y nos regrese un vector. De la misma manera podemos utilizar la función vapply, que es más estricta que sapply cuando se haga uso de ella dentro de una función. Una última recomendación es que tomemos en cuenta que cuando estamos escribiendo código en modo interactivo, lo que queremos son resultados rápidos, de tal manera que podamos corregir también, algún error o algún detalle al vuelo, pero, cuando estemos escribiendo código debemos evitar hacer suposiciones sobre lo que nuestro usuario quiere hacer. Es decir, debemos enviar mensajes de error o advertencia tan pronto nos percatemos de que pudiera haber un error de este tipo. Este es el último video en nuestro curso, por lo que quisiera agradecer a ustedes la atención y el tiempo invertido en este. Espero que una vez que hayan tenido los objetivos cumplidos puedan llevar a cabo análisis de datos más sofisticados. También a todo el equipo de producción y de diseño instruccional para poder lleva a buen puerto este curso. Y finalmente, quisiera agradecer a Coursera por haberme dado esta oportunidad de poder compartir con ustedes un poco el conocimiento en esta área. Muchísimas gracias. [MÚSICA] [MÚSICA]