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.