En esta entrada trataré de explicar cómo he logrado construir funciones a tramos. En estas, se puede especificar la función de respuesta deseada en función del dominio de la variable. En mi caso, necesitaba estandarizar entre el 0 y el 1 los recursos hídricos de una cuenca hidrológica. Para ello tenía los umbrales definidos (por ejemplo, 200 hectómetros cúbicos equivalen a un 0,15; 300 hm3 equivalen a 0,3 y 400 hm3 equivalen a 0,5). Como puedes ver, la estandarización no es directa porque el índice no es lineal (se trata de una función a tramos). Primero trataré de definirla informalmente y posteriormente la escribiré en código.
La función a tramos tendría la siguiente forma: 1. Para valores de x comprendidos entre 0 y 200: (0.15/200)x. (Para que queden entre 0 y 0.15) 2. Para valores de x comprendidos entre 200 y 300: (0.3/100)(x-200)+ 0.15. (Para que queden entre 0.15 y 0.3) 3. Para valores de x comprendidos entre 300 y 400: (0.5/100)(x-300)+ 0.3. (Para que queden entre 0.3 y 0.5) 4. Para valores de x comprendidos entre 400 y 650: (1/250)(x-400)+ 0.5. (Para que queden entre 0.5 y 1)
#En lenguaje de programación se escribiría usando el comando case_when (del paquete dplyr):
funcionatramos <- function(x)case_when(x>=0&x<=200~(0.15/200)*x,
x>=200&x<=300~(0.15/100)*(x-200)+ 0.15,
x>=300&x<=400~(0.2/100)*(x-300)+ 0.3,
x>=400&x<=650~(0.5/250)*(x-400)+ 0.5)
Podemos ver que para usar case_when simplemente hay que especificar unas condiciones (en nuestro caso que el valor del dominio se encuentre entre un valor y otro) y, tras ellas usar el símbolo “~” para especificar la función a aplicar (en nuestro caso estandariza los valores de cada dominio para que queden entre. Para pasar al siguiente tramo de la función sólo habría que establecer una coma y la secuencia volvería a empezar. Es importante saber que si la función no halla valores dentro del dominio los declara NA (como ocurrirá con un valor que supere el 650 que hemos establecido).
Una vez tenemos la función, podemos aplicarla a una tibble; por ejemplo:
valores=c(0,150,1300,137,79,229,330,450,60,300,344,600)
(tiabla <- tibble(valores))
## # A tibble: 12 x 1
## valores
## <dbl>
## 1 0
## 2 150
## 3 1300
## 4 137
## 5 79
## 6 229
## 7 330
## 8 450
## 9 60
## 10 300
## 11 344
## 12 600
Aplicando la función:
(tiabla <- tiabla %>% mutate(índice=funcionatramos(valores)))
## # A tibble: 12 x 2
## valores índice
## <dbl> <dbl>
## 1 0 0
## 2 150 0.112
## 3 1300 NA
## 4 137 0.103
## 5 79 0.0592
## 6 229 0.194
## 7 330 0.36
## 8 450 0.6
## 9 60 0.045
## 10 300 0.3
## 11 344 0.388
## 12 600 0.9
De hecho, si rellenamos todos los valores del dominio podremos ver que se trata de una función a tramos:
prueba <- tibble(valores=seq(0,650,by=10))
prueba <- prueba %>% mutate(índice=funcionatramos(valores))
ggplot(data=prueba,mapping=aes(x=valores,y=índice)) + geom_point() + geom_hline(yintercept = c(0.15,0.3,0.5))
Ahí podemos observar los cuatro tramos.