Introducción.

Como hemos visto informalmente hasta ahora, R permite crear objetos del modo function, que constituyen nuevas funciones de R, que se pueden utilizar a su vez en expresiones posteriores. En este proceso, el lenguaje gana considerablemente en potencia, comodidad y elegancia, y aprender a escribir funciones útiles es una de las mejores formas de conseguir que el uso de R sea cómodo y productivo.

Debemos recalcar que muchas de las funciones que se suministran con R, como mean, var o postscript, están de hecho escritas en R y, por tanto, no difieren materialmente de las funciones que pueda escribir el usuario.

Para definir una función debe realizar una asignación de la forma:

NombreDeFuncion <-function(arg_1, arg_2, …) expresión, donde expresión es una expresión de R (normalmente una expresión agrupada) que utiliza los argumentos arg_i para calcular un valor que es devuelto por la función.

El uso de la función es normalmente de la forma NombreDeFuncion(expr 1,expr 2,…) y puede realizarse en cualquier lugar en que el uso de una función sea correcto.

Escribiendo funciones R

Por lo general, escribe funciones en R para realizar operaciones que requieren dos o más líneas de código para ejecutarse y que no desea escribir muchas veces. Podríamos querer escribir funciones simples para calcular medidas de tendencia central, calcular factoriales y similares. Las funciones en R son objetos que realizan operaciones sobre argumentos que se les proporcionan y devuelven uno o más valores. La sintaxis para escribir una función es:

-function (argument list){body}

El primer componente de la declaración de la función es la palabra clave función, que le indica a R que desea crear una función. Una lista de argumentos es una lista de argumentos formales separados por comas. Un argumento formal puede ser un símbolo (es decir, un nombre de variable como x o y), una declaración de la forma symbol = expression (por ejemplo, pch=16) o el argumento formal especial… (triple dot).

El cuerpo puede ser cualquier expresión R válida o un conjunto de expresiones R en una o más líneas. Generalmente, el cuerpo es un grupo de expresiones contenidas entre corchetes {}, con cada expresión en una línea separada (si el cuerpo cabe en una sola línea, no se necesitan corchetes).

Las funciones normalmente se asignan a símbolos, pero no es necesario. Esto sólo empezará a significar algo después de haber visto varios ejemplos en funcionamiento.

1-Media aritmética de una sola muestra

1-Media aritmética de una sola muestra

La media es la suma de los números ∑ x dividida por el número de números n = ∑1 (suma sobre el número de números en el vector llamado x). La función R para n es length(x) y para ∑ x es sum(x), por lo que una función para calcular medias aritméticas es:

mean <- function(x) sum(x)/length(x)

Podemos probar la función con algunos datos donde sabemos la respuesta correcta:

-Creamos un o más vectores númericos:

-Recurrimos a la función mean() y para ejemplificar utilizamos sum(x)/length(x)

x1 <-c(3,3,4,5,5) 

x2 <-c(2.1,3.8,5.7,2.1,5.7)

mean(x1)
## [1] 4
sum(x1)/length(x1)
## [1] 4
mean(x2)
## [1] 3.88
sum(x2)/length(x2)
## [1] 3.88

No hace falta decir que hay una función incorporada para las medias aritméticas llamada mean.

2-Mediana de una sola muestra.

2-Mediana de una sola muestra.

La mediana (o percentil 50) es el valor medio de los valores ordenados de un vector de números:

sort(x1)[ceiling(length(x1)/2)]
## [1] 4
median(x1)
## [1] 4
median(x2)
## [1] 3.8

3 Medios geométricos

3 Medios geométricos

Para procesos que cambian de forma multiplicativa en lugar de aditiva, ni la media aritmética ni la mediana son medidas ideales de tendencia central. En estas condiciones, la medida apropiada es la media geométrica. La definición formal de esto es algo abstracta: la media geométrica es la raíz enésima del producto de los datos. Si usamos pi ( ) para representar la multiplicación, y yˆ(pronounced y-hat) para representar la media geométrica, entonces

yˆ =√(n&Hy )

Tomemos un ejemplo simple que podemos resolver a mano: el número de insectos en 5 plantas fue el siguiente: 10, 1, 1000, 1, 10. Multiplicando los números da 100 000. Hay cinco números, así que queremos la raíz quinta de esto. Las raíces son difíciles de hacer mentalmente, así que usaremos R como calculadora. Recuerda que las raíces son potencias fraccionarias, por lo que la raíz quinta es un número elevado a la potencia 1/5 = 0,2. En R, potencias se denotan con el símbolo:

100000ˆ0.2

[1] 10

Entonces, la media geométrica de estos números de insectos es 10 insectos por tallo. Tenga en cuenta que dos de los datos eran exactamente como este, por lo que parece una estimación razonable de la tendencia central. La media aritmética, por otro lado, es una medida inútil de tendencia central en este caso, porque el valor grande (1000) es muy influyente: está dado por (10 + 1 + 1000 + 1 + 10)/5 = 204.4 , y ninguno de los datos está cerca de él.

insects <- c(1,10,1000,10,1)

mean(insects)

[1] 204.4

insects <- c(1,10,1000,10,1)
mean(insects)
## [1] 204.4

Otra forma de calcular la media geométrica implica el uso de logaritmos. Recuerda que para multiplicar números juntos sumamos sus logaritmos. Y para sacar raíces, dividimos el logaritmo por la raíz. Entonces, deberíamos poder calcular una media geométrica encontrando el antilog (exp) del promedio de los logaritmos (log) de los datos:

exp(mean(log(insects)))

[1] 10

insects <- c(1,10,1000,10,1)
exp(mean(log(insects)))
## [1] 10

Así que aquí hay una función para calcular la media geométrica de un vector de números x:

geometric <- function (x) exp(mean(log(x)))

Podemos probarlo con los datos de insectos:

geometric(insects)

[1] 10

insects <- c(1,10,1000,10,1)
geometric <- function (x) exp(mean(log(x)))
geometric(insects)
## [1] 10

El uso de medios geométricos llama la atención sobre un problema científico general. Observa la siguiente figura, que muestra números que varían a lo largo del tiempo en dos poblaciones. Ahora pregúntese qué población es la más variable. Lo más probable es que elija la línea superior

imagen 1

Pero ahora mira la escala en el eje y. La población superior fluctúa 100, 200, 100, 200 y así sucesivamente. En otras palabras, es duplicar y reducir a la mitad, duplicar y reducir a la mitad. La curva inferior fluctúa 10, 20, 10, 20, 10, 20 y así sucesivamente. También se está duplicando y reduciendo a la mitad, duplicando y reduciendo a la mitad. Así que la respuesta a la pregunta es que son igualmente variables. Es solo que una población tiene un valor medio más alto que la otra (150 frente a 15 en este caso). Para no caer en la trampa de decir que la curva superior es más variable que la curva inferior, es una buena práctica graficar los logaritmos en lugar de los valores brutos de cosas como el tamaño de la población que cambia multiplicativamente, como se muestra a continuación.

imagen 2

Ahora está claro que ambas poblaciones son igualmente variables. Tenga en cuenta el cambio de escala, como se especifica utilizando el:

ylim=c(1,6) dentro de la función plot (p. 193).

4-Media armónica

4-Media armónica

Considere el siguiente problema. Un elefante tiene un territorio que es un cuadrado de 2 km de lado. Cada mañana, el elefante camina por el límite de este territorio. Comienza el día a paso tranquilo, recorriendo el primer lado del territorio a una velocidad de 1 km/h. En el segundo lado, ha acelerado hasta 2 km/h. Por el tercer lado ha acelerado a unos impresionantes 4 km/h, pero esto lo desgasta tanto que tiene que volver por el último lado a un lento 1 km/h.

-Entonces, ¿cuál es su velocidad promedio sobre el suelo?

Podrías decir que viajó a 1, 2, 4 y 1 km/h, por lo que la velocidad promedio es (1+2+4+1)/4=8/4=2 km/h. Pero eso está mal.

-¿Puedes ver cómo encontrar la respuesta correcta?

Recuerde que la velocidad se define como la distancia recorrida dividida por el tiempo empleado. La distancia recorrida es fácil: son sólo 4×2=8 km. El tiempo necesario es un poco más difícil. El primer borde tenía 2 km de largo, y viajando a 1 km/h esto debe haber tomado 2 horas. El segundo borde tenía 2 km de largo, y viajando a 2 km/h esto debe haber tomado 1 hora. El tercer borde tenía 2 km de largo y viajaba a 4 km/h esto debió tomar 0.5 hr. El borde final tenía 2 km de largo y viajando a 1 km/h esto debe haber tomado 2 horas. Así que el tiempo total empleado fue 2+1+0,5+2=5,5 h. Entonces la velocidad promedio no es 2 km/hr sino 8/5.5=1.4545 km/hr.

La forma de resolver este problema es usar la media armónica.

La media armónica es el recíproco de la media de los recíprocos. El promedio de nuestros recíprocos es:

1/1+1/2+1/4+1/1=2.754=0.6875

El recíproco de este promedio es la media armónica.

4/2.75=1/0.6875=1.4545

En símbolos, por lo tanto, la media armónica, y(y-rotación), viene dada por:

y=1/(∑(1/x))/n=n/∑(1/x)

Una función R para calcular medias armónicas, por lo tanto, podría ser:

harmonic <- function (x) 1/mean(1/x)

Por lo tanto:

z <- c(1,2,4,1)
1/mean(1/z)
## [1] 1.454545

5-Varianza

5-Varianza

Una medida de variabilidad es quizás la cantidad más importante en el análisis estadístico. Cuanto mayor sea la variabilidad en los datos, mayor será nuestra incertidumbre en los valores de los parámetros estimados a partir de los datos. La varianza de una muestra se mide como una función de ‘la suma de los cuadrados de la diferencia entre los datos y la media aritmética’. Esta cantidad importante se llama la “suma de cuadrados”.

SS=∑(y−̄y)^2.

Naturalmente, esta cantidad aumenta con cada nuevo punto de datos que agrega a la muestra. Una forma obvia de compensar esto es medir la variabilidad como el promedio de las desviaciones al cuadrado de la media (la “desviación cuadrática media”). Sin embargo, hay un pequeño problema. Mire la fórmula para la suma de cuadrados, SS, arriba y pregúntese qué necesita saber antes de poder calcularla. Tienes los datos, y, pero la única manera de conocer la media de la muestra, ̄y, es calcularla a partir de los datos (nunca sabrás ̄y por adelantado).

6-Grados de libertad

6-Grados de libertad

Para completar nuestro cálculo de la varianza necesitamos los grados de libertad (d.f.).

Este importante concepto en estadística se define de la siguiente manera:

d.f.=n−k

Dicha definición dice que la muestra, n, menos el número de parámetros, k, estimado a partir de los datos.

Para la varianza, hemos estimado un parámetro a partir de los datos, ̄y, por lo que hay n−1 grados de libertad. En una regresión lineal, estimamos dos parámetros a partir de los datos, la pendiente y la intersección, por lo que hay n−2 grados de libertad en un análisis de regresión.

La varianza se denota con letras latinas minúsculas al cuadrado: s^2. La raíz cuadrada de la varianza, s, se llama desviación estándar. Siempre calculamos la varianza como:

Variance = s^2= sum of squares/degrees of freedom

Considere los siguientes datos:

y <- c(13,7,5,12,9,15,6,11,9,7,12)

Necesitamos escribir una función para calcular la varianza de la muestra: la llamamos variance y la definimos así:

variance <- function(y) sum((y - mean(y))ˆ2)/(length(y)-1)

Por lo cual lo podemos usar de la siguiente manera:

y <- c(13,7,5,12,9,15,6,11,9,7,12)
var(y)
## [1] 10.25455

Nuestra medida de variabilidad en estos datos, la varianza, es entonces 10.254 55. Se dice que es un estimador insesgado porque dividimos la suma de los cuadrados por los grados de libertad (n−1) en lugar de por el tamaño de la muestra, n, para compensar el hecho de que hemos estimado un parámetro de los datos.

Entonces, la varianza está cerca de la diferencia promedio cuadrática entre los datos y la media, especialmente para muestras grandes, pero no es exactamente igual a la desviación cuadrática promedio. No hace falta decir que R tiene una función integrada para calcular la varianza llamada var (la cual fue utilizada anteriormente).

7-Prueba de relación de varianza

7-Prueba de relación de varianza

¿Cómo sabemos si dos varianzas son significativamente diferentes entre sí?

Una de las varias formas sensatas de hacer esto es llevar a cabo la prueba F de Fisher, que es simplemente la razón de las dos varianzas. Aquí hay una función para imprimir el valor p asociado con una comparación de las varianzas más grandes y más pequeñas:

variance.ratio <- function(x,y)

v1 <- var(x v2 <- var(y) if (var(x) > var(y) vr <- var(x)/var(y) df1 <- length(x)-1 df2 <- length(y)-1 else vr <- var(y)/var(x) df1 <- length(y)-1 df2 <- length(x)-1 2*(1-pf(vr,df1,df2))

La última línea de nuestra función calcula la probabilidad de obtener una proporción tan grande como v o mayor solo por casualidad si las dos varianzas fueran realmente las mismas, usando la probabilidad acumulada de la distribución F, que es una función R llamada pf. Necesitamos proporcionar pf con tres argumentos: el tamaño de la razón de varianza (vr), el número de grados de libertad en el numerador (df1=9) y el número de grados de libertad en el denominador (df2=9).

Aquí hay algunos datos para probar nuestra función. Son números aleatorios distribuidos normalmente, pero el primer conjunto tiene una varianza de 4 y el segundo una varianza de 16 (es decir, desviaciones estándar de 2 y 4, respectivamente):

x <- rnorm(10,15,2)
y <- rnorm(10,15,4)
var.test(x,y)
## 
##  F test to compare two variances
## 
## data:  x and y
## F = 0.28534, num df = 9, denom df = 9, p-value = 0.07572
## alternative hypothesis: true ratio of variances is not equal to 1
## 95 percent confidence interval:
##  0.07087523 1.14879029
## sample estimates:
## ratio of variances 
##          0.2853433

8 Usando la varianza

8 Usando la varianza

La varianza se utiliza de dos formas principales: para establecer medidas de falta de fiabilidad (e.g. confidence intervals) y para probar hipótesis (e.g. Student’s t test) Aquí nos concentraremos en el primero; este último se analiza en el Capítulo 8.

Considere las propiedades que le gustaría que posea una medida de falta de confiabilidad. A medida que aumenta la varianza de los datos, ¿qué sucedería con la falta de confiabilidad de los parámetros estimados? ¿Subirá o bajará? La falta de confiabilidad aumentaría a medida que aumentara la varianza, por lo que nos gustaría tener la varianza en la parte superior (el numerador) de cualquier división en nuestra fórmula para la falta de confiabilidad:

unreliability ∝ s^2 / falta de fiabilidad ∝ s^2

¿Qué pasa con el tamaño de la muestra? ¿Le gustaría que su estimación de la falta de confiabilidad aumentara o disminuyera a medida que aumenta el tamaño de la muestra, n? Desearía que la falta de confiabilidad disminuyera a medida que aumentaba el tamaño de la muestra, por lo que colocaría el tamaño de la muestra en la parte inferior de la fórmula para la falta de confiabilidad (es decir, en el denominador):

unreliability ∝ (s^2/n) / falta de fiabilidad ∝ (s^2/n)

Finalmente, considere las unidades en las que se mide la falta de confiabilidad. ¿Cuáles son las unidades en las que se expresa nuestra medida actual? El tamaño de la muestra no tiene dimensiones, pero la varianza se basa en la suma de las diferencias al cuadrado, por lo que tiene dimensiones de media al cuadrado. Entonces, si la media fuera una longitud en cm, la varianza sería un área en cm^2. Este es un estado de cosas desafortunado. Tendría sentido tener las dimensiones de la medida de falta de fiabilidad y del parámetro cuya falta de fiabilidad está midiendo lo mismo. Es por eso que todas las medidas de falta de confiabilidad están encerradas dentro de un gran término de raíz cuadrada. Las medidas de falta de confiabilidad se denominan errores estándar. Lo que acabamos de calcular es el error estándar de la media

se_(y-)=√(s2/n)

donde s^2 es la varianza y n es el tamaño de la muestra. No hay una función R incorporada para calcular el error estándar de una media, pero es fácil escribir uno

se <- function(x) sqrt(var(x)/length(x))

se <- function(x) sqrt(var(x)/length(x))

Puede hacer referencia a funciones desde dentro de otras funciones. Recuerde que un intervalo de confianza (IC) es ‘t de tablas por el error estándar’:

CI = tα/2,d.f. × se.

La función R qt da el valor de Student’s t with 1 – α/2 = 0.975 y grados de libertad d.f. = length(x)-1. Aquí hay una función llamada ci95 que usa nuestra función para calcular intervalos de confianza del 95% para una media

ci95 <- function(x) {
    t.value <- qt(0.975,length(x)-1)
    standard.error <- se(x)
    ci <- t.value*standard.error
    cat("95 Confidence Interval = ", mean(x) -ci, "to ", mean(x) +ci,"\n") }

Podemos probar la función con 150 números aleatorios normalmente distribuidos con media 25 y desviación estándar 3:

x <- rnorm(150,25,3)
ci95(x)
## 95 Confidence Interval =  23.81728 to  24.74532

Si tuviéramos que repetir el experimento, podríamos estar 95% seguros de que la media de la nueva muestra estaría entre 24,76 y 25,74.

Podemos usar la función (se) para investigar cómo cambia el error estándar de la media con el tamaño de la muestra. Primero generamos un conjunto de datos del cual tomaremos muestras progresivamente más grandes:

xv <- rnorm(30)

Ahora, en un bucle, tome muestras de tamaño 2, 3, 4, . . . , 30:

sem <- numeric(30)
sem[1] <- NA
for(i in 2:30) sem[i] <- se(xv[1:i])
plot(1:30,sem,ylim=c(0,0.8),
     ylab="standard error of mean",xlab="sample size n",pch=16)

Puede ver claramente que a medida que el tamaño de la muestra cae por debajo de n = 15, el error estándar de la media aumenta rápidamente. Las irregularidades en la línea se deben a que los valores atípicos se incluyen en los cálculos del error estándar con aumentos en el tamaño de la muestra. La curva suave es fácil de calcular: dado que los valores en xv provienen de una distribución normal estándar con media 0 y desviación estándar 1, la curva promedio sería 1/ √n, que podemos agregar a nuestro gráfico usando líneas:

xv <- rnorm(30)
sem <- numeric(30)
sem[1] <- NA
for(i in 2:30) sem[i] <- se(xv[1:i])
plot(1:30,sem,ylim=c(0,0.8),
    ylab="standard error of mean",xlab="sample size n",pch=16)
lines(2:30,1/sqrt(2:30))

Puede ver que nuestra única simulación capturó la esencia de la forma pero se equivocó en los detalles, especialmente para las muestras con la replicación más baja. Sin embargo, nuestra muestra única fue razonablemente buena para n > 24

9-Deparsing: una función gráfica para barras de error.

9-Deparsing: una función gráfica para barras de error.

No hay ninguna función en el paquete base de R para dibujar barras de error en gráficos de barras, aunque varios paquetes contribuidos usan la función arrows para este propósito. Aquí hay una función simple y simplificada que se proporciona con tres argumentos: las alturas de las barras (yv), las longitudes (hacia arriba y hacia abajo) de las barras de error (z) y las etiquetas de las barras en ejex (nn).

El proceso de análisis convierte una expresión no evaluada en una cadena de caracteres. Uno de los usos importantes de deparsing es en funciones que producen resultados que desea etiquetar con los nombres particulares de las variables que se pasaron a la función. Por ejemplo, si la función está escrita en términos de una variable de respuesta continua y y una variable explicativa categórica x, es posible que desee etiquetar los ejes de un gráfico producido por la función con, por ejemplo, clipping y biomass en lugar de x e y. Por ejemplo, si la función está escrita en términos de una variable de respuesta continua yv, es posible que desee etiquetar los ejes de un gráfico producido por la función con, por ejemplo, biomass en lugar de yv . Dentro de la función error.bars, la función barplot usa la función deparse para crear el texto apropiado para ylab.

error.bars <- function(yv,z,nn){

xv <-

barplot(yv,ylim=c(0,(max(yv)+max(z))), names=nn, ylab=deparse(substitute(yv)))

g=(max(xv)-min(xv))/50

for (i in 1:length(xv)){

lines(c(xv[i],xv[i]),c(yv[i]+z[i],yv[i]-z[i]))

lines(c(xv[i]-g,xv[i]+g),c(yv[i]+z[i], yv[i]+z[i]))

lines(c(xv[i]-g,xv[i]+g),c(yv[i]-z[i], yv[i]-z[i]))}}

10 la funcion cabiar (switch)

10 la funcion cabiar (switch)

Cuando desea que una función haga cosas diferentes en diferentes circunstancias, la función canbiar (switch) puede ser útil. Aquí escribimos una función que puede calcular cualquiera de las cuatro medidas diferentes de tendencia central: media aritmética, media geométrica, media armónica o mediana (consulte las páginas 115–119 para obtener explicaciones de las funciones separadas). La variable de carácter llamada medida (Measure) debe tomar un valor de Media, Geométrica, Armónica o Mediana; cualquier otro texto dará lugar al mensaje de error Medida no incluida(Measure not included). Alternativamente, puede especificar el número del cambio (por ejemplo, 1 para Media, 4 para Mediana).

central <- function(y, measure) {
    switch(measure,
           Mean = mean(y),
           Geometric = exp(mean(log(y))),
           Harmonic = 1/mean(1/y),
           Median = median(y),
           stop("Measure not included")) }

Tenga en cuenta que debe incluir las cadenas de caracteres entre comillas como argumentos de la función, pero no deben estar entre comillas dentro de la propia función de cambio.

central(rnorm(100,10,2),"Harmonic")
## [1] 9.604906
central(rnorm(100,10,2),4)
## [1] 9.692777

11-El entorno de evaluación de una función.

El entorno de evaluación de una función.

Cuando se llama o se invoca una función, se crea un nuevo marco de evaluación. En este marco, los argumentos formales se comparan con los argumentos proporcionados de acuerdo con las reglas de coincidencia de argumentos (abajo). Las declaraciones en el cuerpo de la función se evalúan secuencialmente en este marco de entorno.

Lo primero que ocurre en la evaluación de una función es la coincidencia de los argumentos formales con los reales o suministrados. Esto se hace mediante un proceso de tres pasos:

°Coincidencia exacta en las etiquetas: para cada argumento provisto con nombre, se busca en la lista de argumentos formales un elemento cuyo nombre coincida exactamente.

°Coincidencia parcial en etiquetas: cada argumento proporcionado con nombre se compara con los argumentos formales restantes mediante la coincidencia parcial. Si el nombre del argumento proporcionado coincide exactamente con la primera parte de un argumento formal, se considera que los dos argumentos coinciden.

°Coincidencia posicional: cualquier argumento formal no coincidente está vinculado a argumentos proporcionados sin nombre, en orden. Si hay un . . . argumento, tomará los argumentos restantes, etiquetados o no.

°Si alguno de los argumentos no coincide, se declara un error.

Los argumentos proporcionados y los argumentos predeterminados se tratan de forma diferente. Los argumentos proporcionados a una función se evalúan en el marco de evaluación de la función que llama. Los argumentos predeterminados de una función se evalúan en el marco de evaluación de la función. En general, los argumentos proporcionados se comportan como si fueran variables locales inicializadas con el valor proporcionado y el nombre del argumento formal correspondiente. Cambiar el valor de un argumento proporcionado dentro de una función no afectará el valor de la variable en el marco de llamada.

12- Alcance

Alcance

Las reglas de alcance son el conjunto de reglas utilizadas por el evaluador para encontrar un valor para un símbolo. Un símbolo puede ser ligado o no enlazado. Todos los argumentos formales de una función proporcionan símbolos vinculados en el cuerpo de la función. Cualquier otro símbolo en el cuerpo de la función son variables locales o variables independientes. Una variable local es aquella que se define dentro de la función, generalmente colocándola en el lado izquierdo de una asignación. Durante el proceso de evaluación, si se detecta un símbolo no vinculado, R intenta encontrar un valor para él: primero se busca el entorno de la función, luego su recinto y así sucesivamente hasta que se alcanza el entorno global. A continuación, se utiliza el valor de la primera coincidencia.

13 Argumentos opcionales

13 Argumentos opcionales

Aquí hay una función llamada (charplot) que produce un diagrama de dispersión de x e y usando círculos rojos sólidos como símbolos de trazado: hay dos argumentos esenciales (x e y) y dos opcionales (pc y co) para controlar

selección del símbolo de trazado y su color:

charplot <- function(x,y,pc=16,co="red"){
    plot(y~x,pch=pc,col=co)}

Los argumentos opcionales reciben sus valores predeterminados usando = en la lista de argumentos. Para ejecutar la función, solo necesita proporcionar los vectores de x e y:

charplot(1:10,1:10)

para obtener círculos rojos sólidos. Puede obtener un símbolo de trazado diferente simplemente agregando un tercer argumento

charplot(1:10,1:10,17)

que produce triángulos sólidos rojos (pch=17). Si desea cambiar solo el color (el cuarto argumento), debe especificar el nombre de la variable porque los argumentos opcionales no se presentarían en secuencia. Entonces, para círculos sólidos azul marino, pones:

charplot(1:10,1:10,co="navy")

Para cambiar tanto el símbolo de trazado como el color, no necesita especificar los nombres de las variables, siempre que el símbolo de trazado sea el tercer argumento y el color el cuarto:

charplot(1:10,1:10,15,"green")

Esto produce cuadrados verdes sólidos. Invertir los argumentos opcionales no funciona:

charplot(1:10,1:10,"green",15)

(esto usa la letra g como símbolo de trazado y el color no. 15). Si especifica ambos nombres de variables, entonces el orden no importa:

charplot(1:10,1:10,co="green",pc=15)

Esto produce cuadrados verdes sólidos a pesar de que los argumentos están fuera de secuencia.

14 Números variables de argumentos ( . . . )

14 Números variables de argumentos ( . . . )

Algunas aplicaciones son mucho más sencillas si no es necesario especificar el número de argumentos de antemano. Hay un nombre formal especial. . . (punto triple) que se utiliza en la lista de argumentos para especificar que se debe pasar un número arbitrario de argumentos a la función. Aquí hay una función que toma cualquier número de vectores y calcula sus medias y varianzas:

many.means <- function ( ...) {
    data <- list( ...)
    n <- length(data)
    means <- numeric(n)
    vars <- numeric(n)
    for (i in 1:n) {
        means[i] <- mean(data[[i]])
        vars[i] <- var(data[[i]])
    }
    print(means)
    print(vars)
    invisible(NULL)
}

Las principales características a tener en cuenta son estas. La definición de la función tiene . . . como su único argumento. El argumento del ‘punto triple’. . . permite que la función acepte argumentos adicionales de nombre y número no especificados, y esto introduce una gran flexibilidad en la estructura y el comportamiento de las funciones. Lo primero que se hace dentro de la función es crear un objeto llamado datos(data) a partir de la lista de vectores que se suministran realmente en cada caso particular. La longitud de esta lista es el número de vectores, no las longitudes de los vectores en sí (estas pueden diferir de un vector a otro, como en el ejemplo siguiente). Luego, las dos variables de salida medias y vars(means y vars) se definen para tener tantos elementos como vectores hay en la lista de parámetros. El bucle va de 1 al número de vectores, y para cada vector usa las funciones integradas mean y var para calcular las respuestas que necesitamos. Es importante tener en cuenta que debido a que los datos son una lista, usamos subíndices dobles [[ ]] para abordar sus elementos. Ahora pruébalo. Para complicar las cosas le daremos tres vectores de diferentes longitudes. Todos provienen de la distribución normal estándar (con media 0 y varianza 1), pero (x) tiene una longitud de 100, (y) tiene una longitud de 200 y (z) tiene una longitud de 300 números:

x <- rnorm(100)
y <- rnorm(200)
z <- rnorm(300)

Ahora invocamos la función:

many.means(x,y,z)
## [1] -0.07079126  0.02807232  0.02339909
## [1] 1.023066 1.082359 1.120743

Como era de esperar, las tres medias (fila superior) están cerca de 0 y las tres varianzas están cerca de 1 (fila inferior). Puedes usar . . . para absorber algunos argumentos en una función intermedia que luego puede ser extraída por funciones llamadas posteriormente. R tiene una forma de evaluación perezosa de argumentos de función en la que los argumentos no se evalúan hasta que se necesitan (en algunos casos, el argumento nunca se evaluará).

15 Devolver valores de una función

15 Devolver valores de una función

A menudo, desea que una función devuelva un valor único (como una media o un máximo), en cuyo caso simplemente deja la última línea de la función sin asignar (es decir, no hay una “flecha de obtención” en la última línea). Aquí hay una función para devolver el valor mediano de los máximos paralelos (función incorporada “pmax”) de dos vectores proporcionados como argumentos:

parmax <- function (a,b) {
    c <- pmax(a,b)
    median(c) }

Aquí está la función en acción: la última línea no asignada median (c) devuelve la respuesta

x <- c(1,9,2,8,3,7)
y <- c(9,2,8,3,7,2)
parmax(x,y)
## [1] 8

Si desea devolver dos o más variables de una función, debe usar return con una lista que contiene las variables que se devolverán. Supongamos que quisiéramos el valor mediano de los máximos paralelos y del paralelo

mínimos a devolver:

parboth <- function (a,b) {
c <- pmax(a,b)
d <- pmin(a,b)
answer <- list(median(c),median(d))
names(answer)[[1]] <- "median of the parallel maxima"
names(answer)[[2]] <- "median of the parallel minima"
return(answer) }

Aquí está en acción con los mismos datos (x e y) que arriba:

parboth(x,y)
## $`median of the parallel maxima`
## [1] 8
## 
## $`median of the parallel minima`
## [1] 2

El punto es que haces los retornos múltiples en una lista, luego devuelves la lista. La provisión de devoluciones de múltiples argumentos (por ejemplo, return(median(c),median(d)) en el ejemplo anterior) ha quedado obsoleta en R y se da una advertencia, ya que las devoluciones de múltiples argumentos nunca se documentaron en (S), y si o no, la lista fue nombrada difiere de una versión de (S) a otra.

16-Funciones anónimas

Funciones anónimas

Aquí hay un ejemplo de una función anónima. Genera un vector de valores pero a la función no se le asigna un nombre (aunque la respuesta podría serlo).

(function(x, y){z <- 2* x*x + y*y; x+y+z})(0:7, 1)
## [1]   2   5  12  23  38  57  80 107

La función primero usa los valores provistos de xandy para calcular z, luego devuelve el valor de x+y+z evaluado para ocho valores de x (de 0 a 7) y uno valor de y (1). Las funciones anónimas se utilizan con más frecuencia con apply, tapply, sapply y lapply.

17-Manejo flexible de argumentos a funciones

17-Manejo flexible de argumentos a funciones

Debido a la perezosa evaluación practicada por R, es muy sencillo lidiar con los argumentos que faltan en las llamadas a funciones, dando al usuario la oportunidad de especificar el número mínimo absoluto de argumentos, pero anular los argumentos predeterminados si Ellos quieren. Como un ejemplo simple, tome una función plotx2 que queremos que funcione cuando se le proporciona uno o dos argumentos. En el caso de un argumento (solo se proporciona un número entero x>1), queremos que **plot z*z contra z para z=1 a x en pasos de 1. En el segundo caso, cuando se proporciona y, queremos que represente y frente a z para z=1 a x**.

En muchos otros idiomas, la primera línea fallaría porque no está definida en este punto. Pero R no evalúa una expresión hasta que el cuerpo de la función pide que se evalúe (es decir, nunca, en el caso de que y se proporcione como segundo argumento). Así, para el caso de un argumento obtenemos una gráfica de z2 contra z y en el caso de dos argumentos obtenemos una gráfica de y contra z (en este ejemplo, la línea recta 1:12 contra 1:12). Redimensionamos las ventanas (ancho y luego alto en pulgadas) para que los gráficos se vean más o menos cuadrados en lugar de alargados:

plotx2 <- function (x, y = z*z){
  z<-1:x
  plot(z,y,type="l")}
par(mfrow=c(1,2))
plotx2(12)
plotx2(12,1:12)

Es posible acceder a las expresiones reales (no predeterminadas) utilizadas como argumentos dentro de la función. El mecanismo se implementa a través de promesas. Puede encontrar una explicación de las promesas escribiendo ?promise en el símbolo del sistema.

18-Estructura de un objeto:str

Estructura de un objeto:str

Aquí está uno de los objetos más simples en R: un vector de longitud 7 que contiene números reales:

(y <- seq(0.9,0.3,-0.1))
## [1] 0.9 0.8 0.7 0.6 0.5 0.4 0.3

Podemos preguntarle a R sobre la estructura del objeto llamado y usando str:

str(y)
##  num [1:7] 0.9 0.8 0.7 0.6 0.5 0.4 0.3

Descubrimos que es numérico (tanto en clase como en modo), un vector de longitud 7 [1:7] y (debido a que el vector es corto) vemos todos los valores enumerados. Para vectores más largos, veríamos los primeros valores, dependiendo de lo que cabría en una sola línea impresa (según lo afectado por la cantidad de lugares decimales que se muestran).

¿Qué pasa con un objeto un poco más complicado?

Aquí hay un marco de datos con dos columnas:

library(readr)
 temp <- read.table("temp.txt")
head(temp, n = 156)