Funciones

1 Conceptos Básicos

1.2 Componentes de una función

  • Una función se define con function

name <- function(arg_1, arg_2, ...) expression

  • Está compuesta por:
    • Nombre de la función (name)
    • Argumentos (arg_1, arg_2, ...)
    • Cuerpo (expression): emplea los argumentos para generar un resultado

1.3 Mi primera función

  • Definición
myFun <- function(x, y)
{
    x + y
}
  • Argumentos
formals(myFun)
$x


$y
  • Cuerpo
body(myFun)
{
    x
y
}

1.4 Mi primera función

myFun(1, 2)
[1] 3
myFun(1:10, 21:30)
[1] 22 24 26 28 30 32 34 36 38 40
myFun(1:10, 3)
[1]  4  5  6  7  8  9 10 11 12 13

1.5 Argumentos: nombre y orden

Una función identifica sus argumentos por su nombre y por su orden (sin nombre)

power <- function(x, exp)
{
    x^exp
}
power(x=1:10, exp=2)
[1]   1   4   9  16  25  36  49  64  81 100
power(1:10, exp=2)
[1]   1   4   9  16  25  36  49  64  81 100
power(exp=2, x=1:10)
[1]   1   4   9  16  25  36  49  64  81 100

1.6 Argumentos: valores por defecto

  • Se puede asignar un valor por defecto a los argumentos
power <- function(x, exp = 2)
{
    x ^ exp
}
power(1:10)
[1]   1   4   9  16  25  36  49  64  81 100
power(1:10, 2)
[1]   1   4   9  16  25  36  49  64  81 100

1.7 Funciones sin argumentos

hello <- function()
{
    print('Hello world!')
}
hello()
[1] "Hello world!"

1.8 Argumentos sin nombre: ...

pwrSum <- function(x, power, ...)
{
    sum(x ^ power, ...)
}
x <- 1:10
pwrSum(x, 2)

[1] 385
x <- c(1:5, NA, 6:9, NA, 10)
pwrSum(x, 2)

[1] NA
pwrSum(x, 2, na.rm=TRUE)
[1] 385

1.9 Argumentos ausentes: missing

suma10 <- function(x, y)
{
    if (missing(y)) y <- 10
    x + y
}
suma10(1:10)
[1] 11 12 13 14 15 16 17 18 19 20

1.10 Control de errores: stopifnot

foo <- function(x, y)
{
    stopifnot(is.numeric(x) & is.numeric(y))
    x + y
}
foo(1:10, 21:30)
[1] 22 24 26 28 30 32 34 36 38 40
foo(1:10, 'a')
Error in foo(1:10, "a") : is.numeric(x) & is.numeric(y) is not TRUE

1.11 Control de errores: stop

foo <- function(x, y){
    if (!(is.numeric(x) & is.numeric(y))){
        stop('arguments must be numeric.')
    } else { x + y }
} 
foo(2, 3)
[1] 5
foo(2, 'a')
Error in foo(2, "a") : arguments must be numeric.

1.12 Mensajes para el usuario

stop para la ejecución y emite un mensaje de error

stop('Algo no ha ido bien.')
Error: Algo no ha ido bien.

warning no interfiere en la ejecución pero añade un mensaje a la cola de advertencias

warning('Quizás algo no es como debiera...')
Warning message:
Quizás algo no es como debiera...

message emite un mensaje (no usar cat o print)

message('Todo en orden por estos lares.')
Todo en orden por estos lares.

2 Lexical scope

2.1 Clases de variables

Las variables que se emplean en el cuerpo de una función pueden dividirse en:

  • Parámetros formales (argumentos): x, y
  • Variables locales (definiciones internas): z, w, m
  • Variables libres: a, b
myFun <- function(x, y){
    z <- x^2
    w <- y^3
    m <- a*z + b*w
    m
}
a <- 10
b <- 20
myFun(2, 3)

[1] 580

2.2 Lexical scope

  • Las variables libres deben estar disponibles en el entorno (environment) en el que la función ha sido creada.
environment(myFun) 
<environment: R_GlobalEnv>
ls()
 [1] "a"           "anidada"     "b"           "constructor" "fib"        
 [6] "foo"         "hello"       "i"           "lista"       "ll"         
[11] "M"           "makeNoise"   "myFoo"       "myFun"       "power"      
[16] "pwrSum"      "suma1"       "suma10"      "suma2"       "suma3"      
[21] "sumProd"     "sumSq"       "tmp"         "x"

2.3 Lexical scope: funciones anidadas

anidada <- function(x, y){
    xn <- 2
    yn <- 3
    interna <- function(x, y)
    {
        sum(x^xn, y^yn)
    }
    print(environment(interna))
    interna(x, y)
}
anidada(1:3, 2:4)
<environment: 0x561467f15098>
[1] 113
sum((1:3)^2, (2:4)^3)
[1] 113

2.4 Lexical scope: funciones anidadas

xn
Error: objeto 'xn' no encontrado
yn
Error: objeto 'yn' no encontrado
interna
Error: objeto 'interna' no encontrado

2.5 Funciones que devuelven funciones

constructor <- function(m, n){
    function(x)
    {
        m*x + n
    }
}
myFoo <- constructor(10, 3)
myFoo

function(x)
    {
        m*x
n
    }
<environment: 0x561465446120>
## 10*5 + 3
myFoo(5)

[1] 53

2.6 Funciones que devuelven funciones

class(myFoo)
[1] "function"
environment(myFoo)
<environment: 0x561465446120>
ls()
 [1] "a"           "anidada"     "b"           "constructor" "fib"        
 [6] "foo"         "hello"       "i"           "lista"       "ll"         
[11] "M"           "makeNoise"   "myFoo"       "myFun"       "power"      
[16] "pwrSum"      "suma1"       "suma10"      "suma2"       "suma3"      
[21] "sumProd"     "sumSq"       "tmp"         "x"
ls(env = environment(myFoo))
[1] "m" "n"
get('m', env = environment(myFoo))
[1] 10
get('n', env = environment(myFoo))
[1] 3

3 Funciones para ejecutar funciones

3.1 lapply

Supongamos que tenemos una lista de objetos, y queremos aplicar a cada elemento la misma función:

lista <- list(a = rnorm(100),
              b = runif(100),
              c = rexp(100))

Podemos resolverlo de forma repetitiva…

sum(lista$a)

sum(lista$b)

sum(lista$c)
[1] 8.551703

[1] 48.13393

[1] 91.70712

O mejor con lapply (lista + función):

lapply(lista, sum)
$a
[1] 8.551703

$b
[1] 48.13393

$c
[1] 91.70712

3.2 do.call

Supongamos que queremos usar los elementos de la lista como argumentos de una función.

Resolvemos de forma directa:

sum(lista$a, lista$b, lista$c)
[1] 148.3928

Mejoramos un poco con with:

with(lista, sum(a, b, c))
[1] 148.3928

La forma recomendable es mediante do.call (función + lista)

do.call(sum, lista)
[1] 148.3928

3.3 do.call

Se emplea frecuentemente para adecuar el resultado de lapply (entrega una lista):

  x <- rnorm(5)
  ll <- lapply(1:5, function(i)x^i)
  do.call(rbind, ll)

              [,1]      [,2]     [,3]       [,4]     [,5]
[1,] -0.1741481604  1.836011 1.572541 0.38827268 1.408270
[2,]  0.0303275818  3.370936 2.472885 0.15075568 1.983224
[3,] -0.0052814926  6.189075 3.888713 0.05853431 2.792915
[4,]  0.0009197622 11.363209 6.115161 0.02272727 3.933179
[5,] -0.0001601749 20.862975 9.616340 0.00882438 5.538978

3.4 Reduce

Combina sucesivamente los elementos de un objeto aplicando una función binaria

## (((1+2)+3)+4)+5
Reduce('+', 1:5)

[1] 15

3.5 Reduce

## (((1/2)/3)/4)/5
Reduce('/', 1:5)

[1] 0.008333333
foo <- function(u, v)u + 1 /v
Reduce(foo, c(3, 7, 15, 1, 292))
## equivalente a
## foo(foo(foo(foo(3, 7), 15), 1), 292)

[1] 4.212948
Reduce(foo, c(3, 7, 15, 1, 292), right=TRUE)
## equivalente a
## foo(3, foo(7, foo(15, foo(1, 292))))
[1] 3.141593

3.6 Funciones recursivas

Ejemplo: Serie de Fibonnaci

fib <- function(n){
    if (n>2) {
        c(fib(n-1),
          sum(tail(fib(n-1),2)))
    } else if (n>=0) rep(1,n)
}
fib(10)
[1]  1  1  2  3  5  8 13 21 34 55

4 Debug

4.1 Post-mortem: traceback

sumSq <- function(x, ...)
    sum(x ^ 2, ...)

sumProd <- function(x, y, ...){
    xs <- sumSq(x, ...)
    ys <- sumSq(y, ...)
    xs * ys
}
sumProd(rnorm(10), runif(10))
[1] 38.5012
sumProd(rnorm(10), letters[1:10])
Error in x^2 : argumento no-numérico para operador binario
traceback()
2: sumSq(y, ...) at #3
1: sumProd(rnorm(10), letters[1:10])

4.2 Analizar antes de que ocurra: debug

debug activa la ejecución paso a paso de una función:

debug(sumProd)
  • Cada vez que se llame a la función, su cuerpo se ejecuta línea a línea y los resultados de cada paso pueden ser inspeccionados.
  • Los comandos disponibles son:
    • n o intro: avanzar un paso.
    • c: continua hasta el final del contexto actual (por ejemplo, terminar un bucle).
    • where: entrega la lista de todas las llamadas activas.
    • Q: termina la inspección y vuelve al nivel superior.
  • Para desactivar el análisis:
undebug(sumProd)

4.3 Debugging con RStudio

sumSq <- function(x, ...)
    sum(x ^ 2, ...)

sumProd <- function(x, y, ...){
    xs <- sumSq(x, ...)
    ys <- sumSq(y, ...)
    xs * ys
}

sumProd(rnorm(10), letters[1:10])

Error in x^2 : argumento no-numérico para operador binario

4.4 Analizar antes de que ocurra: trace

  • trace permite mayor control que debug
trace(sumProd, tracer=browser, exit=browser)
[1] "sumProd"
  • La función queda modificada
sumProd
Object with tracing code, class "functionWithTrace"
Original definition: 
function(x, y, ...){
    xs <- sumSq(x, ...)
    ys <- sumSq(y, ...)
    xs * ys
}

## (to see the tracing code, look at body(object))
body(sumProd)
{
    on.exit(.doTrace(browser(), "on exit"))
    {
        .doTrace(browser(), "on entry")
        {
            xs <- sumSq(x, ...)
            ys <- sumSq(y, ...)
            xs * ys
        }
    }
}

4.5 Analizar antes de que ocurra: trace

  • Los comandos n y c cambian respecto a debug:
    • c o intro: avanzar un paso.
    • n: continua hasta el final del contexto actual (por ejemplo, terminar un bucle).
  • Para desactivar
untrace(sumProd)

5 Profiling

5.1 ¿Cuánto tarda mi función? system.time

Defino una función que rellena una matriz de 106 filas y n columnas con una distribución normal:

makeNoise <- function(n){
    sapply(seq_len(n), function(i) rnorm(1e6))
}
M <- makeNoise(100)
summary(M)

       V1                  V2                  V3           
 Min.   :-4.850557   Min.   :-4.794546   Min.   :-4.959313  
 1st Qu.:-0.676386   1st Qu.:-0.675196   1st Qu.:-0.673844  
 Median :-0.000827   Median :-0.000570   Median :-0.001241  
 Mean   :-0.001329   Mean   :-0.000532   Mean   : 0.000115  
 3rd Qu.: 0.673604   3rd Qu.: 0.674320   3rd Qu.: 0.673666  
 Max.   : 4.937682   Max.   : 4.724857   Max.   : 4.829274  
       V4                  V5                  V6           
 Min.   :-4.746586   Min.   :-4.418662   Min.   :-4.922335  
 1st Qu.:-0.672089   1st Qu.:-0.675456   1st Qu.:-0.675237  
 Median : 0.000235   Median : 0.000346   Median :-0.001352  
 Mean   : 0.000877   Mean   :-0.000081   Mean   :-0.000835  
 3rd Qu.: 0.672989   3rd Qu.: 0.673988   3rd Qu.: 0.674756  
 Max.   : 5.064697   Max.   : 5.112633   Max.   : 4.896000  
       V7                  V8                  V9           
 Min.   :-4.644428   Min.   :-4.627102   Min.   :-5.352816  
 1st Qu.:-0.672574   1st Qu.:-0.673407   1st Qu.:-0.674217  
 Median : 0.002164   Median : 0.000271   Median :-0.000229  
 Mean   : 0.002565   Mean   : 0.000547   Mean   : 0.000024  
 3rd Qu.: 0.677710   3rd Qu.: 0.674456   3rd Qu.: 0.675413  
 Max.   : 4.618701   Max.   : 4.601317   Max.   : 4.949978  
      V10                 V11                 V12           
 Min.   :-5.027927   Min.   :-4.903829   Min.   :-4.697789  
 1st Qu.:-0.675302   1st Qu.:-0.674489   1st Qu.:-0.675601  
 Median :-0.000820   Median :-0.000714   Median :-0.001707  
 Mean   :-0.000438   Mean   :-0.000620   Mean   :-0.001225  
 3rd Qu.: 0.675767   3rd Qu.: 0.674138   3rd Qu.: 0.673670  
 Max.   : 5.346777   Max.   : 4.676823   Max.   : 4.580514  
      V13                 V14                 V15           
 Min.   :-4.509624   Min.   :-5.036134   Min.   :-4.782108  
 1st Qu.:-0.673944   1st Qu.:-0.674532   1st Qu.:-0.673579  
 Median : 0.000975   Median : 0.000433   Median : 0.000503  
 Mean   : 0.000949   Mean   : 0.000039   Mean   : 0.000373  
 3rd Qu.: 0.675379   3rd Qu.: 0.674557   3rd Qu.: 0.673238  
 Max.   : 4.909678   Max.   : 4.641636   Max.   : 4.858559  
      V16                 V17                 V18           
 Min.   :-4.840236   Min.   :-4.884061   Min.   :-4.802291  
 1st Qu.:-0.676883   1st Qu.:-0.674009   1st Qu.:-0.676295  
 Median :-0.001808   Median :-0.000962   Median : 0.000528  
 Mean   :-0.000204   Mean   : 0.000562   Mean   :-0.000269  
 3rd Qu.: 0.677312   3rd Qu.: 0.674364   3rd Qu.: 0.675237  
 Max.   : 5.173266   Max.   : 4.633160   Max.   : 4.861439  
      V19                 V20                 V21           
 Min.   :-4.734104   Min.   :-4.628800   Min.   :-4.998211  
 1st Qu.:-0.676435   1st Qu.:-0.675693   1st Qu.:-0.675295  
 Median :-0.000923   Median :-0.000543   Median : 0.001051  
 Mean   :-0.001369   Mean   : 0.000363   Mean   : 0.000287  
 3rd Qu.: 0.672723   3rd Qu.: 0.675628   3rd Qu.: 0.676204  
 Max.   : 4.519534   Max.   : 4.770924   Max.   : 4.872298  
      V22                 V23                 V24           
 Min.   :-4.584718   Min.   :-5.008954   Min.   :-4.962820  
 1st Qu.:-0.674432   1st Qu.:-0.675657   1st Qu.:-0.673911  
 Median :-0.001037   Median : 0.000553   Median :-0.000414  
 Mean   :-0.001069   Mean   :-0.000315   Mean   : 0.000217  
 3rd Qu.: 0.672974   3rd Qu.: 0.673243   3rd Qu.: 0.674113  
 Max.   : 4.896479   Max.   : 5.849746   Max.   : 4.723353  
      V25                 V26                 V27           
 Min.   :-4.648474   Min.   :-5.041275   Min.   :-5.076685  
 1st Qu.:-0.673811   1st Qu.:-0.675506   1st Qu.:-0.673777  
 Median : 0.001180   Median :-0.000345   Median : 0.001884  
 Mean   : 0.000649   Mean   : 0.000347   Mean   : 0.001570  
 3rd Qu.: 0.674306   3rd Qu.: 0.676356   3rd Qu.: 0.675758  
 Max.   : 4.820999   Max.   : 4.928471   Max.   : 4.949749  
      V28                 V29                 V30           
 Min.   :-4.782954   Min.   :-5.421742   Min.   :-5.172364  
 1st Qu.:-0.675536   1st Qu.:-0.675365   1st Qu.:-0.672259  
 Median :-0.000095   Median :-0.001912   Median : 0.001398  
 Mean   :-0.001065   Mean   :-0.001701   Mean   : 0.001383  
 3rd Qu.: 0.672350   3rd Qu.: 0.672334   3rd Qu.: 0.675230  
 Max.   : 5.436804   Max.   : 5.085306   Max.   : 4.964369  
      V31                 V32                 V33           
 Min.   :-4.667793   Min.   :-4.833797   Min.   :-4.694007  
 1st Qu.:-0.675107   1st Qu.:-0.671960   1st Qu.:-0.674966  
 Median :-0.001197   Median : 0.001690   Median : 0.001354  
 Mean   :-0.000142   Mean   : 0.002202   Mean   : 0.000867  
 3rd Qu.: 0.675070   3rd Qu.: 0.676421   3rd Qu.: 0.674366  
 Max.   : 4.787195   Max.   : 4.699088   Max.   : 5.010420  
      V34                 V35                 V36           
 Min.   :-5.446058   Min.   :-4.533631   Min.   :-4.752244  
 1st Qu.:-0.673664   1st Qu.:-0.674191   1st Qu.:-0.672597  
 Median : 0.001297   Median : 0.000455   Median : 0.001093  
 Mean   : 0.000679   Mean   :-0.000148   Mean   : 0.001487  
 3rd Qu.: 0.673649   3rd Qu.: 0.674547   3rd Qu.: 0.675785  
 Max.   : 5.414420   Max.   : 5.189383   Max.   : 4.849343  
      V37                 V38                 V39           
 Min.   :-4.807822   Min.   :-4.922465   Min.   :-4.574132  
 1st Qu.:-0.675665   1st Qu.:-0.673740   1st Qu.:-0.674085  
 Median :-0.000619   Median : 0.001534   Median : 0.000419  
 Mean   :-0.000317   Mean   : 0.001441   Mean   : 0.000211  
 3rd Qu.: 0.674693   3rd Qu.: 0.675951   3rd Qu.: 0.675237  
 Max.   : 4.711566   Max.   : 5.234585   Max.   : 4.912451  
      V40                 V41                 V42           
 Min.   :-4.742904   Min.   :-5.386501   Min.   :-4.999125  
 1st Qu.:-0.674248   1st Qu.:-0.674838   1st Qu.:-0.672386  
 Median : 0.000948   Median :-0.001003   Median : 0.001399  
 Mean   :-0.000004   Mean   :-0.000596   Mean   : 0.001309  
 3rd Qu.: 0.674465   3rd Qu.: 0.673916   3rd Qu.: 0.676335  
 Max.   : 4.915512   Max.   : 4.789493   Max.   : 4.707417  
      V43                 V44                 V45           
 Min.   :-4.753084   Min.   :-4.709842   Min.   :-5.273677  
 1st Qu.:-0.674923   1st Qu.:-0.674049   1st Qu.:-0.674362  
 Median :-0.000884   Median : 0.000834   Median : 0.000490  
 Mean   :-0.000630   Mean   :-0.000506   Mean   : 0.000223  
 3rd Qu.: 0.674982   3rd Qu.: 0.673910   3rd Qu.: 0.673923  
 Max.   : 4.932571   Max.   : 5.026923   Max.   : 4.653212  
      V46                 V47                 V48           
 Min.   :-4.996664   Min.   :-4.738134   Min.   :-4.859197  
 1st Qu.:-0.676372   1st Qu.:-0.673854   1st Qu.:-0.674312  
 Median :-0.000825   Median : 0.001036   Median :-0.000106  
 Mean   :-0.000718   Mean   : 0.000624   Mean   :-0.000005  
 3rd Qu.: 0.674396   3rd Qu.: 0.674806   3rd Qu.: 0.674820  
 Max.   : 5.120740   Max.   : 5.081875   Max.   : 4.877178  
      V49                 V50                 V51           
 Min.   :-4.953889   Min.   :-4.520459   Min.   :-4.708236  
 1st Qu.:-0.675264   1st Qu.:-0.673504   1st Qu.:-0.673751  
 Median :-0.000249   Median :-0.001242   Median : 0.000700  
 Mean   :-0.000428   Mean   :-0.000663   Mean   : 0.000855  
 3rd Qu.: 0.674614   3rd Qu.: 0.673366   3rd Qu.: 0.676419  
 Max.   : 4.985089   Max.   : 4.661399   Max.   : 4.840113  
      V52                 V53                 V54           
 Min.   :-4.862482   Min.   :-5.107180   Min.   :-5.798235  
 1st Qu.:-0.674127   1st Qu.:-0.675357   1st Qu.:-0.674056  
 Median :-0.000690   Median :-0.001088   Median :-0.002170  
 Mean   :-0.001007   Mean   :-0.000679   Mean   :-0.001286  
 3rd Qu.: 0.673654   3rd Qu.: 0.672905   3rd Qu.: 0.672970  
 Max.   : 4.751464   Max.   : 5.179290   Max.   : 4.702111  
      V55                 V56                 V57           
 Min.   :-5.005057   Min.   :-5.060830   Min.   :-5.105633  
 1st Qu.:-0.673712   1st Qu.:-0.676715   1st Qu.:-0.673642  
 Median :-0.001579   Median :-0.000958   Median : 0.001118  
 Mean   :-0.000529   Mean   :-0.001274   Mean   : 0.000237  
 3rd Qu.: 0.674349   3rd Qu.: 0.672709   3rd Qu.: 0.674212  
 Max.   : 4.658009   Max.   : 4.753345   Max.   : 4.951854  
      V58                 V59                 V60           
 Min.   :-4.822032   Min.   :-4.776918   Min.   :-4.640167  
 1st Qu.:-0.672959   1st Qu.:-0.674258   1st Qu.:-0.674527  
 Median : 0.001876   Median :-0.001701   Median :-0.001111  
 Mean   : 0.001451   Mean   :-0.000080   Mean   :-0.000308  
 3rd Qu.: 0.676163   3rd Qu.: 0.674081   3rd Qu.: 0.674874  
 Max.   : 4.719650   Max.   : 4.674338   Max.   : 4.794550  
      V61                 V62                 V63           
 Min.   :-4.967301   Min.   :-4.366678   Min.   :-4.801026  
 1st Qu.:-0.674279   1st Qu.:-0.673558   1st Qu.:-0.675316  
 Median :-0.000496   Median :-0.000239   Median : 0.000897  
 Mean   :-0.001024   Mean   : 0.000339   Mean   : 0.000617  
 3rd Qu.: 0.673062   3rd Qu.: 0.674447   3rd Qu.: 0.676415  
 Max.   : 4.704742   Max.   : 4.800138   Max.   : 4.992336  
      V64                 V65                 V66           
 Min.   :-5.160700   Min.   :-4.720091   Min.   :-4.869707  
 1st Qu.:-0.675937   1st Qu.:-0.675230   1st Qu.:-0.677457  
 Median : 0.000050   Median :-0.000026   Median :-0.004332  
 Mean   :-0.000888   Mean   : 0.000342   Mean   :-0.002243  
 3rd Qu.: 0.673925   3rd Qu.: 0.675889   3rd Qu.: 0.672396  
 Max.   : 5.233259   Max.   : 4.550943   Max.   : 4.574867  
      V67                 V68                 V69           
 Min.   :-4.863161   Min.   :-5.044760   Min.   :-5.093013  
 1st Qu.:-0.673692   1st Qu.:-0.675270   1st Qu.:-0.673751  
 Median :-0.001351   Median :-0.000887   Median :-0.000434  
 Mean   :-0.000251   Mean   : 0.000325   Mean   :-0.000079  
 3rd Qu.: 0.674305   3rd Qu.: 0.675674   3rd Qu.: 0.676045  
 Max.   : 5.108234   Max.   : 5.261013   Max.   : 4.745168  
      V70                 V71                 V72           
 Min.   :-4.756397   Min.   :-4.936753   Min.   :-4.474239  
 1st Qu.:-0.673857   1st Qu.:-0.673124   1st Qu.:-0.675507  
 Median : 0.002404   Median : 0.001445   Median :-0.000661  
 Mean   : 0.000838   Mean   : 0.001182   Mean   : 0.000048  
 3rd Qu.: 0.674465   3rd Qu.: 0.676302   3rd Qu.: 0.675517  
 Max.   : 4.744661   Max.   : 5.116368   Max.   : 4.921679  
      V73                 V74                 V75           
 Min.   :-4.827140   Min.   :-4.856865   Min.   :-4.779098  
 1st Qu.:-0.675988   1st Qu.:-0.673974   1st Qu.:-0.676952  
 Median : 0.000424   Median :-0.001063   Median : 0.001478  
 Mean   : 0.000151   Mean   :-0.000969   Mean   :-0.000148  
 3rd Qu.: 0.674845   3rd Qu.: 0.671933   3rd Qu.: 0.674716  
 Max.   : 4.846236   Max.   : 4.655334   Max.   : 4.461740  
      V76                 V77                 V78           
 Min.   :-4.653744   Min.   :-4.406902   Min.   :-4.718347  
 1st Qu.:-0.674304   1st Qu.:-0.673636   1st Qu.:-0.674781  
 Median : 0.001131   Median : 0.002247   Median :-0.000615  
 Mean   : 0.000609   Mean   : 0.000869   Mean   :-0.000468  
 3rd Qu.: 0.674453   3rd Qu.: 0.674921   3rd Qu.: 0.673226  
 Max.   : 5.264564   Max.   : 4.795977   Max.   : 5.220267  
      V79                 V80                 V81           
 Min.   :-4.880356   Min.   :-4.988047   Min.   :-4.913894  
 1st Qu.:-0.675600   1st Qu.:-0.676624   1st Qu.:-0.672188  
 Median :-0.001672   Median :-0.002173   Median :-0.001573  
 Mean   :-0.001071   Mean   :-0.001445   Mean   :-0.000749  
 3rd Qu.: 0.674288   3rd Qu.: 0.673656   3rd Qu.: 0.672490  
 Max.   : 4.748778   Max.   : 4.935536   Max.   : 4.681703  
      V82                 V83                 V84           
 Min.   :-4.883418   Min.   :-4.901276   Min.   :-5.079876  
 1st Qu.:-0.674083   1st Qu.:-0.672021   1st Qu.:-0.675706  
 Median :-0.000996   Median :-0.000583   Median :-0.000639  
 Mean   :-0.000086   Mean   : 0.000978   Mean   : 0.000049  
 3rd Qu.: 0.673292   3rd Qu.: 0.674668   3rd Qu.: 0.675364  
 Max.   : 4.944165   Max.   : 4.944620   Max.   : 4.569763  
      V85                 V86                 V87           
 Min.   :-4.641984   Min.   :-4.949596   Min.   :-4.611695  
 1st Qu.:-0.675703   1st Qu.:-0.676107   1st Qu.:-0.673572  
 Median : 0.000791   Median :-0.000695   Median :-0.000016  
 Mean   :-0.000274   Mean   :-0.001878   Mean   : 0.000228  
 3rd Qu.: 0.674507   3rd Qu.: 0.672439   3rd Qu.: 0.674904  
 Max.   : 5.031343   Max.   : 5.217666   Max.   : 5.637254  
      V88                 V89                 V90           
 Min.   :-5.004213   Min.   :-4.761411   Min.   :-4.885385  
 1st Qu.:-0.671865   1st Qu.:-0.673912   1st Qu.:-0.676176  
 Median : 0.001239   Median : 0.000242   Median :-0.001612  
 Mean   : 0.002014   Mean   : 0.000157   Mean   :-0.001368  
 3rd Qu.: 0.676138   3rd Qu.: 0.674306   3rd Qu.: 0.672445  
 Max.   : 4.986575   Max.   : 4.730267   Max.   : 4.723730  
      V91                 V92                 V93           
 Min.   :-4.446145   Min.   :-5.038213   Min.   :-4.968904  
 1st Qu.:-0.673762   1st Qu.:-0.673108   1st Qu.:-0.674537  
 Median : 0.001250   Median : 0.002066   Median : 0.000254  
 Mean   : 0.000878   Mean   : 0.002104   Mean   : 0.000594  
 3rd Qu.: 0.676381   3rd Qu.: 0.676996   3rd Qu.: 0.675007  
 Max.   : 4.925884   Max.   : 4.868710   Max.   : 4.980750  
      V94                 V95                 V96           
 Min.   :-4.585104   Min.   :-4.782599   Min.   :-5.465619  
 1st Qu.:-0.675851   1st Qu.:-0.675098   1st Qu.:-0.672931  
 Median : 0.000276   Median :-0.002806   Median : 0.001174  
 Mean   :-0.001256   Mean   :-0.001156   Mean   : 0.001409  
 3rd Qu.: 0.672974   3rd Qu.: 0.673394   3rd Qu.: 0.676320  
 Max.   : 5.144434   Max.   : 5.329044   Max.   : 4.860244  
      V97                 V98                 V99           
 Min.   :-4.562743   Min.   :-4.924833   Min.   :-4.946087  
 1st Qu.:-0.673969   1st Qu.:-0.674671   1st Qu.:-0.672491  
 Median :-0.001026   Median : 0.000308   Median : 0.001414  
 Mean   :-0.000260   Mean   :-0.000628   Mean   : 0.001663  
 3rd Qu.: 0.672525   3rd Qu.: 0.672930   3rd Qu.: 0.675098  
 Max.   : 4.627507   Max.   : 4.670783   Max.   : 4.471793  
      V100          
 Min.   :-5.108010  
 1st Qu.:-0.673406  
 Median : 0.000605  
 Mean   : 0.000219  
 3rd Qu.: 0.675098  
 Max.   : 4.465086

5.2 Diferentes formas de sumar

system.time mide el tiempo de CPU que consume un código1.

system.time({
    suma1 <- numeric(1e6)
    for(i in 1:1e6) suma1[i] <- sum(M[i,])
})

 user  system elapsed 
1.565   0.008   2.090
system.time(suma2 <- apply(M, 1, sum))
 user  system elapsed 
2.718   0.028   2.747
system.time(suma3 <- rowSums(M))
 user  system elapsed 
0.323   0.000   0.323

5.3 ¿Cuánto tarda cada parte de mi función?: Rprof

  • Usaremos un fichero temporal
tmp <- tempfile()
  • Activamos la toma de información
Rprof(tmp)
  • Ejecutamos el código a analizar
suma1 <- numeric(1e6)
for(i in 1:1e6) suma1[i] <- sum(M[i,])

suma2 <- apply(M, 1, FUN = sum)

suma3 <- rowSums(M)

5.4 ¿Cuánto tarda cada parte de mi función?: Rprof

  • Paramos el análisis
Rprof()
  • Extraemos el resumen
summaryRprof(tmp)
$by.self
                self.time self.pct total.time total.pct
"apply"              1.64    50.00       2.62     79.88
"aperm.default"      0.46    14.02       0.46     14.02
"FUN"                0.46    14.02       0.46     14.02
"rowSums"            0.34    10.37       0.34     10.37
"sum"                0.32     9.76       0.32      9.76
"unlist"             0.04     1.22       0.04      1.22
"lengths"            0.02     0.61       0.02      0.61

$by.total
                total.time total.pct self.time self.pct
"apply"               2.62     79.88      1.64    50.00
"aperm.default"       0.46     14.02      0.46    14.02
"FUN"                 0.46     14.02      0.46    14.02
"aperm"               0.46     14.02      0.00     0.00
"rowSums"             0.34     10.37      0.34    10.37
"sum"                 0.32      9.76      0.32     9.76
"unlist"              0.04      1.22      0.04     1.22
"lengths"             0.02      0.61      0.02     0.61

$sample.interval
[1] 0.02

$sampling.time
[1] 3.28

6 Ejercicios

6.1 Áreas de figuras geométricas

Escribe una función que calcule el área de un círculo, un triángulo o un cuadrado. La función empleará, a su vez, una función diferente definida para cada caso.

6.2 Conversión de temperaturas

Escribe una función para realizar la conversión de temperaturas. La función trabajará a partir de un valor (número real) y una letra. La letra indica la escala en la que se introduce esa temperatura. Si la letra es ’C’, la temperatura se convertirá de grados centígrados a Fahrenheit. Si la letra es ’F’ la temperatura se convertirá de grados Fahrenheit a grados Centígrados. Se usarán 2 funciones auxiliares, cent2fahr y fahr2cent para convertir de una escala a otra. Estas funciones aceptan un parámetro (la temperatura en una escala) y devuelven el valor en la otra escala.

Nota: La relación entre ambas escalas es \(T_F = 9/5 \cdot T_C + 32\)

6.3 Tablas de multiplicar

Construye un programa que muestre por pantalla las tablas de multiplicar del 1 al 10, a partir de dos funciones específicas. La primera función debe devolver el producto de dos valores numéricos enteros dados como parámetros. La segunda función debe mostrar por pantalla la tabla de multiplicar de un número dado como parámetro.

6.4 Números combinatorios

Escribe una función que calcule y muestre en pantalla el número combinatorio a partir de los valores n y k.

\[ nk = \frac{n!}{(n - k)! \cdot k!} \]

Esta función debe estar construida en base a dos funciones auxiliares, una para calcular el factorial de un número, y otra para calcular el número combinatorio.

6.5 Fibonacci

Escribe una función recursiva que genere los n primeros términos de la serie de Fibonacci. Esta función aceptará el número entero n como argumento. Este valor debe ser positivo, de forma que si el usuario introduce un valor negativo la función devolverá un error.

Nota: En la serie de Fibonacci los dos primeros números son 1, y el resto se obtiene sumando los dos anteriores: \(1, 1, 2, 3, 5, 8, 13, 21, \ldots\)

6.6 Serie de Taylor

Escribe un conjunto de funciones para calcular la aproximación de \(e ^ {-x}\) mediante el desarrollo de Taylor:

\[ e^{-x} = 1 + \sum_{i = 1}^\infty \frac{(-x)^n}{n!} \]

La función principal acepta como argumentos el valor del número real x y el número de términos deseados. Se basará en otras tres funciones:

  • factorial calcula el factorial de un número entero n.
  • potencia calcula la potencia n de un número real x.
  • exponencial calcula la aproximación anterior de un número real x usando n términos de la serie de Taylor.

Nota al pie de página:

1

Para entender la diferencia entre user y system véase explicación aquí.

Autor: Oscar Perpiñán Lamigueiro

Created: 2020-02-17 lun 23:25

Validate