3  Programación defensiva

Es importante garantizar que las funciones se utilicen solo para los propósitos previstos. Este concepto se llama programación defensiva, y consiste en verificar que se cumplan las condiciones necesarias para que la función funcione correctamente. Si alguna condición falla, se debe generar un error para prevenir comportamientos inesperados.

Vamos a usar las funciones stop() y stopifnot() para detener el código cuando hay un error.

Para más información sobre stopifnot() puedes leer su manual.

3.1 Usando stop() con if()

El argumento temp debe ser un valor numeric. Para crear un error, podemos usar la función stop(). Por ejemplo, dado que el argumento temp debe ser un vector numeric, podríamos probarlo con un condicional if() y devolver un error si la condición no se cumple. Podríamos agregar esto a nuestra función de la siguiente manera:

Code
fahr_to_kelvin <- function(temp) {
  if (!is.numeric(temp)) {
    stop("temp must be a numeric vector.") # condiciones
  }
  kelvin <- ((temp - 32) * (5 / 9)) + 273.15
  return(kelvin)
}

3.1.1 Verificación / Realizar pruebas

Code
fahr_to_kelvin(temp = 32)
[1] 273.15
Code
fahr_to_kelvin(temp = "A")
# Error in fahr_to_kelvin(temp = "A") : temp must be a numeric vector.

3.1.2 Probando condiciones con stopifnot()

Code
fahr_to_kelvin <- function(temp) {
  stopifnot(is.numeric(temp)) # condiciones
  kelvin <- ((temp - 32) * (5 / 9)) + 273.15
  return(kelvin)
}

3.1.3 Verificación / Realizar pruebas

Code
fahr_to_kelvin(temp = 32)
[1] 273.15
Code
fahr_to_kelvin(temp = as.factor(32))
# Error in fahr_to_kelvin(temp = as.factor(32)) :
# is.numeric(temp) is not TRUE

3.2 Usando warning() y message() con if()

Code
squareX <- function(x) {
    if (is.character(x)) {
        warning("Converting x to numeric")
        x <- as.numeric(x)
    } else {
        # the type checking done here is of course very incomplete
        message("x appears to be numeric")
    }
    x ^ 2 
}

Verificación / Realizar pruebas

Code
squareX("4")
Warning in squareX("4"): Converting x to numeric
[1] 16
Code
squareX(4)
x appears to be numeric
[1] 16

3.3 Usando el paquete assertthat

Instalar el paquete:

Code
install.packages("assertthat")

El paquete assertthat realiza lo mismo que stopifnot.

Ejemplos:

Code
library(assertthat) ## Mensajes de error
x <- 1:10
stopifnot(is.character(x))
# Error: is.character(x) is not TRUE
assert_that(is.character(x))
# Error: x is not a character vector
assert_that(length(x) == 5)
# Error: length(x) not equal to 5
assert_that(is.numeric(x))
# [1] TRUE

Para más información sobre assertthat puedes leer su manual.

Code
foo_message <- function(x) {
    assertthat::assert_that(x == 1, msg = "x must always be 1")
    "yay"
} 
# verficacion
foo_message(1)
[1] "yay"

4 Scripts

Un script es una colección de varias instrucciones de R escritas en un archivo. La extensión de los script en R es .r o .R. En los scripts podemos colocar comentarios, paquetes, instrucciones de tal forma que pueda ser ejecutado sin problemas.

4.0.1 Guardar funciones, Opcion A

Cargando la función almacenada en un RData

Code
squareX <- function(x) {
    if (is.character(x)) {
        warning("Converting x to numeric")
        x <- as.numeric(x)
    } else {
        # the type checking done here is of course very incomplete
        message("x appears to be numeric")
    }
    x ^ 2 
}
# Guardar
save(squareX, file="./squareX.Rdata")
rm(squareX) # eliminar funcion

Cargar en el ambiente de RStudio

Code
load("./squareX.Rdata")

4.0.2 Guardar funciones, Opcion B

Si has estado escribiendo estas funciones en un script de R aparte (¡una buena idea!), puedes cargar las funciones en nuestra sesión de R usando la función source(), en caso de no estar el script en nuestro directorio de trabajo debemos fijarlo o poner la ruta completa al script.

Code
source("squareX_function.R")

4.1 Material suplementario