martes, 7 de julio de 2015

Funciones acumulativas 1

[Lenguajes: R]

Problema

En R hay varias funciones acumulativas, que operan sobre un vector de datos. Por ejemplo, la función sum(), hace la sumatoria de los números contenidos en el vector que se le pasa como argumento:

sum(c(8,-2,5))
## [1] 11

Otro ejemplo es la función prod(), que, de manera similar a la anterior, hace el producto.

La pregunta que surge es: ¿Hay una función que permita hacer lo mismo, pero para un operador, o función, arbitraria?

Solución

La respuesta a la pregunta anterior es , y el nombre de dicha función es Reduce(), que toma al menos los siguientes argumentos:

  • el operador o función que se aplica
  • el vector de datos

Por ejemplo, para hacer una sumatoria como la del ejemplo anterior, con Reduce() se haría así:

Reduce('+', c(8,-2,5)) # Nótese que el operador va con ''
## [1] 11

Para cualquier otro operador, digamos la división:

Reduce('/', c(8,-2,5)) # Nótese que el operador va con ''
## [1] -0.8

Lo interesante de esta función es que admite, como primer argumento, cualquier función de dos argumentos, particularmente, las que nosotros mismos pudieramos escribir o crear.

Por ejemplo:

# Sea 'ff' una función que multiplica por 2 el primer argumento y
# ese resultado lo divide por el segundo argumento:
ff <- function (x, y) {
    2*x / y
}
# Apliquemos secuencialmente esta función a los elementos de
# un vector
Reduce(ff, c(8,-2,5)) # Reduce admite ff, y también 'ff'
## [1] -3.2

Una característica interesante de Reduce(), es que mediante su argumento, opcional, accumulate, se le puede indicar que entregue cada uno de los resultados intermedios de la operación. Para ejemplificar esto, supóngase que se cuenta en un vector con las alturas individuales de cada uno de los pisos de un edificio y que se quiere saber, desde el suelo, cuál es la altura total de cada uno de los niveles del edificio. El problema se resuelve fácilmente así:

# Vector de alturas de los pisos individuales:
alturas <- c(3.10, 3.15, 3.05, 2.95, 3.10, 3.20)
# Niveles, desde el suelo
niveles <- Reduce('+', alturas, accumulate = TRUE)
niveles
## [1]  3.10  6.25  9.30 12.25 15.35 18.55

Si quieres ver este mismo post en mis publicaciones de Rpubs:


No hay comentarios.:

Publicar un comentario