Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Apuntes R MCE y SLOG
Apuntes R MCE y SLOG
PROGRAMACIÓN ESTADÍSTICA
CON EL SOFTWARE R
CURSO 2023-2024
1. PRIMERAS NOCIONES 5
1.1. Conceptos iniciales . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
1.2. Función help . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
1.3. Asignaciones y Cáculos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
1.3.1. Asignaciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
1.3.2. Operaciones con números reales . . . . . . . . . . . . . . . . . . . . . 9
1.3.3. Operadores comparativos y lógicos . . . . . . . . . . . . . . . . . . . 11
1.3.4. Valores ausentes (“missing values”) . . . . . . . . . . . . . . . . . . . 13
1.4. Scripts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
1.5. Paquetes y Librerı́as . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
2. MANIPULACIÓN DE DATOS 17
2.1. Operaciones con Vectores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
2.2. Operaciones con Matrices . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
2.3. Operaciones con Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
2.4. Listas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
2.5. Hoja de datos (data.frame) . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
2.6. Lectura y escritura de datos . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
2.7. Bases de datos conocidas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
3. FUNCIONES 45
3.1. Definición de una función . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
3.2. Ejemplos de funciones elementales en Estadı́stica . . . . . . . . . . . . . . . 47
3.2.1. Función media . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
3.2.2. Función varianza . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
3.3. Estructuras condicionales . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
3.4. Estructuras de repetición definida e indefinida . . . . . . . . . . . . . . . . . 50
3.5. Más ejemplos de funciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
3.5.1. Factorial de un número . . . . . . . . . . . . . . . . . . . . . . . . . . 50
3.5.2. Suma de una progresión aritmética . . . . . . . . . . . . . . . . . . . 51
3.5.3. Suma de una progresión geométrica . . . . . . . . . . . . . . . . . . . 52
3
4 ÍNDICE GENERAL
4. OPCIONES GRÁFICAS 53
4.1. Funciones gráficas básicas . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
4.2. Función plot . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
4.2.1. Funciones points, abline y lines . . . . . . . . . . . . . . . . . . . 54
4.2.2. Funciones polygon, rect, arrows y segments . . . . . . . . . . . . . 56
4.3. Función curve . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
4.4. Gráficos estadı́sticos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
4.4.1. Función barplot . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
4.4.2. Función pie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
4.4.3. Función hist . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
4.4.4. Función boxplot . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
4.4.5. Función pairs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
Capı́tulo 1
PRIMERAS NOCIONES
5
6 CAPÍTULO 1. PRIMERAS NOCIONES
Una vez instalado el programa, la forma más fácil de usarlo es de forma interactiva me-
diante la lı́nea de comandos. Cuando R se inicia, aparece la ventana del programa “Gui”
(graphical user interface) con un mensaje de apertura.
Ejemplo: Los datos “Nile” son una serie temporal del flujo del rı́o Nilo.
> Nile
T imeSeries :
Start = 1871
End = 1970
F requency = 1
[1] 1120 1160 963 1210 1160 1160 813 1230 1370 1140 995 935 1110 994 1020
[16] 960 1180 799 958 1140 1100 1210 1150 1250 1260 1220 1030 1100 774 840
[31] 874 694 940 833 701 916 692 1020 1050 969 831 726 456 824 702
[46] 1120 1100 832 764 821 768 845 864 862 698 845 744 796 1040 759
[61] 781 865 845 944 984 897 822 1010 771 676 649 846 812 742 801
[76] 1040 860 874 848 890 744 749 838 1050 918 986 797 923 975 815
[91] 1020 906 901 1170 912 746 919 718 714 740
> mode(Nile)
[1] "numeric"
> length(Nile)
[1] 100
> str(Nile)
Time-Series [1:100] from 1871 to 1970: 1120 1160 963 1210 1160 1160 813
1230 1370 1140 ...
Es importante saber que el nombre de un objeto debe comenzar con una letra (A-Z ó a-z)
y además puede incluir letras, dı́gitos (0-9) o puntos. R discrimina entre letras mayúsculas
y minúsculas para el nombre de un objeto, de tal manera que x y X se referirán a objetos
diferentes.
Una caracterı́stica de R es que nos permite guardar la sesión de trabajo, lo que nos será
muy útil en el caso de que necesitemos utilizar librerı́as o datos que ya hemos implementado.
Al cerrar el programa o al teclear q() nos preguntará si deseamos salvar los datos de esta
sesión. Podemos responder Yes (Sı́), No (No) o Cancel (Cancelar). Los datos salvados estarán
disponibles en la siguiente sesión de R.
Otra opción muy útil es la ayuda a través de internet. Si tecleamos help.start() aparece
una ayuda en formato HTML con la información más actual.
Como para poder visualizar un dato renombrado hay de escribir el nombre después de ha-
berlo asignado, puede resultar útil recurrir al sı́mbolo ; después de la asignacion para ahorrar
lı́neas de código. Hay que tener en cuenta que R utiliza determinados términos para referirse
a algunas funciones, por lo que lo mejor es evitar esos nombres a la hora de las asignaciones.
Por ejemplo, c se utiliza para crear vectores y t calcula la traspuesta de un conjunto de datos
(vectores, matrices, dataframes, etc.).
> rnorm(6)->x
> x
[1] -0.05092882 0.39198294 -0.76096311 0.25944247 1.70030099 0.40690559
> X<-rnorm(5)
> X
[1] -1.0556861 0.4802372 0.4809718 -0.2799668 0.2983207
> y=1:15; y
[1] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
1.3. ASIGNACIONES Y CÁCULOS 9
> c
function (..., recursive = FALSE) .Primitive("c")
> #Hola
> #Recuerda que los comentarios son siempre de gran utilidad ;)
Es importante saber que R no evalúa una expresión hasta que tiene la certeza de que se
ha terminado su escritura. Ası́, si la expresion comienza con un paréntesis, deberemos cerrar
la expresión con otro paréntesis.
R proporciona funciones para hacer todo tipo de operaciones básicas como sumas, senos,
cosenos, etc. En la siguiente tabla se muestran algunos comandos frecuentes.
10 CAPÍTULO 1. PRIMERAS NOCIONES
Comando Significado
sum(...) Suma de elementos.
sqrt(...) Raı́z cuadrada.
abs(...) Valor absoluto.
sin(...), cos(...),... Funciones trigonométricas.
log(...), exp(...) Logaritmo y exponencial.
round(...), signif(...) Redondeo de valores numéricos.
> sum(1,4,6)
[1] 11
> seq(1,9,by=2)
[1] 1 3 5 7 9
> rep(1:3,3)
[1] 1 2 3 1 2 3 1 2 3
> sum(seq(1,9,by=2))
[1] 25
> cumsum(seq(1,9,by=2))
[1] 1 4 9 16 25
> sqrt(81)
[1] 9
> abs(-9)
[1] 9
> sin(-2*pi)
[1] 2.449294e-16
> log(100)
[1] 4.60517
> exp(3)
[1] 20.08554
> round(2.345632)
[1] 2
> round(2.3456432,3)
[1] 2.346
> ceiling(2.3456432)
[1] 3
> floor(2.3456432)
[1] 2
> signif(2.345432,3)
[1] 2.35
1.3. ASIGNACIONES Y CÁCULOS 11
Los vectores lógicos pueden utilizarse en expresiones aritméticas, en cuyo caso se transfor-
man primero en vectores numéricos, de tal modo que FALSE se transforma en 0 y TRUE en 1.
En lógica la conjunción &, es un enunciado con dos o más elementos que deben verifi-
carse de forma simultánea. Por ejemplo, “una lámpara eléctrica se enciende si hay corriente
eléctrica, el interruptor está conectado y el fusible está correcto. En cualquier otro caso la
lámpara no se encenderá.” Por otra parte, la disyuncion | es un enunciado con dos o más
elementos optativos. Por ejemplo, “puedes ejecutar el código durante la clase o en casa” es
una disyunción con dos elementos, mientras que “puedes ejecutar el código durante la clase,
en casa o no hacerlo” es una disyunción con tres elementos.
De relación Lógicos
< menor que !x negación
> mayor que x&y conjunción
<= menor o igual que x&&y conjunción (∗)
>= mayor o igual que x|y disyunción
== igual que x||y disyunción (∗)
!= distinto a xor(x, y) ó exclusivo (∗∗)
(∗) Cuando ponemos dos sı́mbolos evaluamos la expresión de izquierda a derecha exami-
nando sólo el primer elemento de cada vector. Puede resultar conveniente en programación,
especialmente en sentencias “if”.
[1] TRUE
> #Le preguntamos si x vale 5
> x==5
[1] FALSE
> #Le preguntamos si x es distinto de 5
> x!=5
[1] TRUE
> #Creamos dos vectores
> y=1:3; z=3:1
> #Le preguntamos si son iguales
> identical(y,z)
[1] FALSE
> #Vemos los elementos que coinciden
> y==z
[1] FALSE TRUE FALSE
> #Renombramos x e y
> x=1:5
> y=c(2,4,3,6,5)
> x==y
[1] FALSE FALSE TRUE FALSE TRUE
> x!=y
[1] TRUE TRUE FALSE TRUE FALSE
> x[x==y]
[1] 3 5
> x[x!=y]
[1] 1 2 4
> A=c(TRUE,FALSE);A
[1] TRUE FALSE
> !A
[1] FALSE TRUE
> B=c(TRUE,TRUE);B
[1] TRUE TRUE
> xor(A,B)
[1] FALSE TRUE
> #A y B
> A & B
[1] TRUE FALSE
> A && B
[1] TRUE
> #A o B
> A | B
1.3. ASIGNACIONES Y CÁCULOS 13
> m=c(2,4,6,1,NA,3)
> m
[1] 2 4 6 1 NA 3
> m-1
[1] 1 3 5 0 NA 2
> is.na(m)
14 CAPÍTULO 1. PRIMERAS NOCIONES
1.4. Scripts
Los scripts son ficheros que contienen listas de comandos según se escriben en la consola,
pudiendo incluir comentarios (recordamos: lı́neas comenzando por #) que explican lo que se
pretende hacer. Son muy útiles para repetir en sucesivas ocasiones, ciertos procedimientos
que hemos tecleado en un determinado momento y para almacenar los comandos utilizados
en las diferentes sesiones.
Ejemplo: Para crear y hacer funcionar un script que genere dos muestras de tamaño 50
de una distribución N (2, 3) y calcule su coeficiente de correlación.
Arrancar R
En la persiana “File” seleccionar “New Script”, si se quiere utilizar un script almacenado
seleccionar “Open Script”.
Escribir en el script las siguientes lı́neas:
> x=rnorm(50,2,3)
> y=rnorm(50,2,3)
> plot(x,y)
> cor(x,y)
Seleccionar todas las lı́neas y presionar el botón derecho del ratón y aparecerá una
ventana de diálogo en la que se selecciona “Run line or selection”, ası́ se ejecutarán
todas las sentencias del script. Si no se selecciona nada, se ejecuta la sentencia al final
de la cual está colocado el cursor. También se puede seleccionar un bloque de sentencias
a ejecutar.
1.5. PAQUETES Y LIBRERÍAS 15
Para guardar y cerrar el script debemos activar la ventana del mismo y seleccionar “File
→ Save”. Se guardará con extensión .R. A continuación: “Close Script” para cerrarlo.
Con la función search() podemos ver los paquetes que hay actualmente en memoria y
con la funcion library() una lista con las librerı́as disponibles. Si dentro de los paréntesis
ponemos el nombre de una de ellas, se cargará para su uso.
search()
[1] ".GlobalEnv" "tools:RGUI" "package:stats" "package:graphics"
[5] "package:grDevices" "package:utils" "package:datasets" "package:methods"
[9] "Autoloads" "package:base"
> library()
> library(MASS)
En resumen, se podrı́a considerar que los paquetes R proporcionan una forma de manejar
conjuntos de funciones o datos y su documentación.
16 CAPÍTULO 1. PRIMERAS NOCIONES
Capı́tulo 2
MANIPULACIÓN DE DATOS
> 1:10
[1] 1 2 3 4 5 6 7 8 9 10
> 10:1
[1] 10 9 8 7 6 5 4 3 2 1
> 1.5:7.5
[1] 1.5 2.5 3.5 4.5 5.5 6.5 7.5
> c(1,2,4,3)
[1] 1 2 4 3
> c(1:5)
[1] 1 2 3 4 5
> c(1:5,2,4,-3)
[1] 1 2 3 4 5 2 4 -3
Otra de las más comunes es utilizando la función seq(a,b,c) que genera una secuencia
de números reales comenzando en a, terminando en b y con incremento c. Otras variantes de
esta función son seq(length=d,from=a,to=b) o seq(by=c,from=a,to=b). Veamos algunos
ejemplos:
> seq(1,10,2)
[1] 1 3 5 7 9
> seq(from=1,to=20,by=2)
[1] 1 3 5 7 9 11 13 15 17 19
> #Si lo que queremos son 6 elementos
17
18 CAPÍTULO 2. MANIPULACIÓN DE DATOS
> seq(from=1,to=10,length=6)
[1] 1.0 2.8 4.6 6.4 8.2 10.0
> sequence(3)
[1] 1 2 3
> sequence(c(3,2))
[1] 1 2 3 1 2
> #Hemos creado una secuencia del vector 1:3 y del 1:2
> c(1:3,1:2)
[1] 1 2 3 1 2
> sequence(c(5,3))
[1] 1 2 3 4 5 1 2 3
> #Hemos creado una secuencia del vector 1:5 y del 1:3
2.1. OPERACIONES CON VECTORES 19
R, además de con números reales, nos permite operar con vectores. Podemos multiplicar
vectores por escalares, vectores por vectores, realizar sumas de vectores, etc. Veremos algunos
ejemplos.
> (1:5)*(2:6)
[1] 2 6 12 20 30
> (1:5)^2
[1] 1 4 9 16 25
> 1:5^2
[1] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
> (1:5)(2:6)
Error: tentativa de aplicar una no-función
> (1:5)+(2:6)
[1] 3 5 7 9 11
> (1:5)+(2:4)
[1] 3 5 7 6 8
Mensajes de aviso perdidos
In (1:5) + (2:4) :
longitud de objeto mayor no es múltiplo de la longitud de uno menor
> (1:5)^3
[1] 1 8 27 64 125
> (1:5)^(1:3)
[1] 1 4 27 4 25
Mensajes de aviso perdidos
In (1:5)^(1:3) :
longitud de objeto mayor no es múltiplo de la longitud de uno menor
> (1:5)^(1:5)
[1] 1 4 27 256 3125
La longitud de un vector puede obtenerse con la función length. Esta función sirve además
para definir la longitud del vector, haciéndolo ası́ más largo o más corto. En el caso de querer
hacerlo más largo, se completar con NAs (valores faltantes).
> jj=c("Pepe","Paco")
> jj
[1] "Pepe" "Paco"
> length(jj)
[1] 2
> #Asigno a jj una longitud igual a 5
> length(jj)=5
> jj
[1] "Pepe" "Paco" NA NA NA
20 CAPÍTULO 2. MANIPULACIÓN DE DATOS
> aa=(1:6)^3
> aa
[1] 1 8 27 64 125 216
> aa[5]
[1] 125
> aa[c(1,3,5)]
[1] 1 27 125
> #Asignamos un género a tres elementos ordenados
> sexo=c("Mujer","Mujer","Hombre")
> sexo
[1] "Mujer" "Mujer" "Hombre"
> #Asignamos un nombre a tres elementos ordenados
> nombre=c("Pepa","Pepita","Pepe")
> nombre
[1] "Pepa" "Pepita" "Pepe"
> #Preguntamos cual de los elementos son mujeres
> sexo==Mujer
Error: objeto ‘Mujer’ no encontrado
> #Si es un caracter tiene que ir entre ""
> sexo=="Mujer"
[1] TRUE TRUE FALSE
> #Quiero sólo los nombres de las mujeres
> nombre[sexo=="Mujer"]
[1] "Pepa" "Pepita"
Un factor es un vector de cadenas de caracteres que sirve para representar datos categóri-
cos o diferentes niveles posibles de una variable. El atributo levels indica los posibles valores
en el vector. Se utiliza, por ejemplo, para clasificar una poblacion en grupos.
La función factor se utiliza para codificar un vector como un factor, creando tantos
niveles como le indiquemos.
A continuación presentamos una tabla con un conjunto de funciones muy útiles a la hora
de trabajar con vectores:
Comando Significado
mean(x) Media aritmética de los valores del vector x
median(x) Mediana de los valores del vector x
sum(x) Suma de los valores del vector x
max(x) Máximo valor de los valores del vector x
min(x) Mı́nimo valor de los valores del vector x
range(x) Rango de los valores del vector x
var(x) Cuasivarianza de los valores del vector x
cov(x) Covarianza de los valores del vector x
cor(x,y) Coeficiente correlación entre los vectores x e y
sort(x) Una versión ordenada del vector x
rank(x) Vector de las filas de los valores en x
order(x) Indica la posición que tendrı́an los valores ordenados de x
quantile(x) Mı́nimo, primer cuartil, mediana, tercer cuartil y máximo de x
cumsum(x) Vector formado por la frecuencia acumulada del vector x
cumprod(x) Vector formado por el producto acumulado del vector x
El siguiente código sirve como ejemplo de cómo utilizar las funciones anteriores:
> x=c(1,2,3,4,5)
22 CAPÍTULO 2. MANIPULACIÓN DE DATOS
> y=c(1,3,3,1,5)
> z=c(1,3,3)
> mean(x)
[1] 3
> median(x)
[1] 3
> sum(x)
[1] 15
> max(x)
[1] 5
> min(x)
[1] 1
> range(x)
[1] 1 5
> #La cuasivarianza muestral
> var(x)
[1] 2.5
> #Veamos que es ası́
> n=length(x)
> sum((x-mean(x))^2)/(n-1)
[1] 2.5
> #La varianza vendrı́a dada por
> ((n-1)/n)*var(x)
[1] 2
> sum((x-mean(x))^2)/(n)
[1] 2
> #La cuasicovarianza
> cov(x,y)
[1] 1.5
> sum((x-mean(x))*(y-mean(y)))/(n-1)
[1] 1.5
> #La covarianza serı́a
> ((n-1)/n)*cov(x,y)
[1] 1.2
> sum((x-mean(x))*(y-mean(y)))/(n)
[1] 1.2
> cor(x,y)
[1] 0.5669467
> sort(x)
[1] 1 2 3 4 5
> sort(y)
2.2. OPERACIONES CON MATRICES 23
[1] 1 1 3 3 5
> sort(y,index.return=TRUE)
$x
[1] 1 1 3 3 5
$ix
[1] 1 4 2 3 5
> y
[1] 1 3 3 1 5
> rank(x)
[1] 1 2 3 4 5
> rank(y)
[1] 1.5 3.5 3.5 1.5 5.0
> order(y)
[1] 1 4 2 3 5
> cumsum(y)
[1] 1 4 7 8 13
> cumprod(y)
[1] 1 3 9 9 45
> m0=matrix(1:6,ncol=2,nrow=3)
> #Hemos formado una matriz de unos de dos filas y tres columnas
> m0
[,1] [,2]
[1,] 1 4
[2,] 2 5
[3,] 3 6
> m1=matrix(1,nrow=2,ncol=3)
> m1
[,1] [,2] [,3]
[1,] 1 1 1
[2,] 1 1 1
> m2=matrix(1:4,2)
> m2
24 CAPÍTULO 2. MANIPULACIÓN DE DATOS
[,1] [,2]
[1,] 1 3
[2,] 2 4
> m2=matrix(1:8,4)
> m2
[,1] [,2]
[1,] 1 5
[2,] 2 6
[3,] 3 7
[4,] 4 8
> #Hemos formado una matriz con el vector 1:8 de cuatro filas
> m3=matrix(1:8,ncol=4)
> m3
[,1] [,2] [,3] [,4]
[1,] 1 3 5 7
[2,] 2 4 6 8
> #Hemos formado una matriz con el vector 1:8 de cuatro columnas
> #Tenemos que tener en cuenta el tama~no de la matriz
> m2=matrix(1:4,3)
Mensajes de aviso perdidos
In matrix(1:4, 3) :
la longitud de los datos [4] no es un submúltiplo o múltiplo del
número de filas [3] en la matriz
> m2
[,1] [,2]
[1,] 1 4
[2,] 2 1
[3,] 3 2
Si se quiere dar nombre a las columnas (o a las filas), se puede hacer asignando valores
al parámetro dim, con los nombres de las filas y las columnas como se ilustra el siguiente
ejemplo.
Un argumento útil del comando matrix es byrow, que indica si la matriz debe construirse
por filas (el valor predeterminado es FALSE).
Hemos visto como crear una matriz a partir de un vector con la función matrix pero
también puede resultar interesante ver cómo podemos pasar de una matriz a un vector.
Veamos el siguiente ejemplo:
26 CAPÍTULO 2. MANIPULACIÓN DE DATOS
> A=matrix(c(1:4,2,3,1,2,7),nrow=3)
> A
[,1] [,2] [,3]
[1,] 1 4 1
[2,] 2 2 2
[3,] 3 3 7
> x=c(A)
> x
[1] 1 2 3 4 2 3 1 2 7
Podemos realizar operaciones con matrices de la misma forma que lo hacı́amos con los
vectores, es decir, componente a componente: suma, resta, multiplicación por escalares, mul-
tiplicación elemento a elemento, división, exponenciación, división entera y módulo, que se
realizan mediante los sı́mbolos: +, −, ∗, /,ˆ, %/ % y % %, respectivamente. Veamos algunos
ejemplos ejecutando el código siguiente:
> M1=matrix(1:6,2,3)
> M1
[,1] [,2] [,3]
[1,] 1 3 5
[2,] 2 4 6
> M2=matrix((1:6)^2,2,3)
> M2
[,1] [,2] [,3]
[1,] 1 9 25
[2,] 4 16 36
> M1+M2
[,1] [,2] [,3]
[1,] 2 12 30
[2,] 6 20 42
> #He sumado componente a componente
> M1*M2
[,1] [,2] [,3]
[1,] 1 27 125
[2,] 8 64 216
> #He multiplicado componente a componente
> M2/M1
[,1] [,2] [,3]
[1,] 1 3 5
[2,] 2 4 6
> #He dividido componente a componente
> M2%%M1
2.2. OPERACIONES CON MATRICES 27
> M1
[,1] [,2] [,3]
[1,] 1 3 5
[2,] 2 4 6
> t(M1)
[,1] [,2]
[1,] 1 2
[2,] 3 4
[3,] 5 6
> #Para realizar la multiplicación usual de matrices uso %*%
> #Ojo a las dimensiones
> dim(M1)
[1] 2 3
> dim(M2)
[1] 2 3
> M1%*%t(M2)
[,1] [,2]
[1,] 153 232
[2,] 188 288
Los comandos cbind y rbind nos permiten concatenar matrices y/o vectores. La función
diag se puede usar para extraer o modificar la diagonal de una matriz o para construir una
matriz diagonal.
> m1=matrix(1,nr=2,nc=2)
> m1
[,1] [,2]
[1,] 1 1
[2,] 1 1
28 CAPÍTULO 2. MANIPULACIÓN DE DATOS
> m2=matrix(2,nr=2,nc=2)
> m2
[,1] [,2]
[1,] 2 2
[2,] 2 2
> #Unimos las dos matrices por filas
> rbind(m1,m2)
[,1] [,2]
[1,] 1 1
[2,] 1 1
[3,] 2 2
[4,] 2 2
> #Unimos las dos matrices por columnas
> cbind(m1,m2)
[,1] [,2] [,3] [,4]
[1,] 1 1 2 2
[2,] 1 1 2 2
> #Mostramos la diagonal de la matriz
> diag(m1)
[1] 1 1
> diag(m2)
[1] 2 2
> #Cambiamos la diagonal de la matriz
> diag(m1)=15
> m1
[,1] [,2]
[1,] 15 1
[2,] 1 15
> #Creamos una matriz diagonal de orden 4
> diag(4)
[,1] [,2] [,3] [,4]
[1,] 1 0 0 0
[2,] 0 1 0 0
[3,] 0 0 1 0
[4,] 0 0 0 1
> v=c(10,15,20)
> diag(v)
[,1] [,2] [,3]
[1,] 10 0 0
[2,] 0 15 0
[3,] 0 0 20
2.2. OPERACIONES CON MATRICES 29
> diag(3.6,nr=2,nc=5)
[,1] [,2] [,3] [,4] [,5]
[1,] 3.6 0.0 0 0 0
[2,] 0.0 3.6 0 0 0
Ya hemos visto cómo se agregan filas y columnas a una matriz ya existente, pero a veces
es útil también eliminarlas. Veamos algún ejemplo.
> A=matrix(c(1,2,1,3,1,4,5,6),nrow=2)
> A
[,1] [,2] [,3] [,4]
[1,] 1 1 1 5
[2,] 2 3 4 6
> #Para eliminar la tercera columa simplemente la selecciono con - delante
> A[,-3]
[,1] [,2] [,3]
[1,] 1 1 5
[2,] 2 3 6
> #Para filas es análogo
La función solve invierte una matriz (si se le da sólo un argumento) y resuelve sistemas
lineales de ecuaciones (cuando se le dan dos). El primer argumento debe ser una matriz cua-
drada no singular, y el segundo argumento (opcional) será un vector o matriz de coeficientes.
> A2=matrix(c(1,2,1,3),nrow=2)
> A2
[,1] [,2]
[1,] 1 1
[2,] 2 3
> b1=c(1,2)
> b1
[1] 1 2
> solve(A2)
[,1] [,2]
[1,] 3 -1
[2,] -2 1
> solve(A2)%*%A2
[,1] [,2]
[1,] 1 0
[2,] 0 1
> A2%*%solve(A2)
[,1] [,2]
30 CAPÍTULO 2. MANIPULACIÓN DE DATOS
[1,] 1 0
[2,] 0 1
> solve(A2,b1)
[1] 1 0
> A2%*%solve(A2,b1)==b1
[,1]
[1,] TRUE
[2,] TRUE
La función eigen calcula los autovalores y autovectores de una matriz cuadrada, el resul-
tado es una lista de dos componentes llamados values y vectors. Con la función det calculamos
el determinante de una matriz cuadrada..
> A2
[,1] [,2]
[1,] 1 1
[2,] 2 3
> eigen(A2)
$values
[1] 3.7320508 0.2679492
$vectors
[,1] [,2]
[1,] -0.3437238 -0.8068982
[2,] -0.9390708 0.5906905
> #Si sólo me interesan los autovectores puedo extraerlos asi
> eigen(A2)$vectors
[,1] [,2]
[1,] -0.3437238 -0.8068982
[2,] -0.9390708 0.5906905
> eigenvec1=eigen(A2)$vectors[,1]
> eigenvec1
[1] -0.3437238 -0.9390708
> det(A2)
[1] 1
objetos. Tienen como atributo la dimensión, que puede asignarse o describirse mediante dim.
Un vector numérico puede utilizarse como un array si se le asigna una dimensión.
El siguiente código nos ayuda a entender cómo funciona dim, y cómo podemos pasar de
un vector a un array mediante este simple comando.
> w=c(seq(2,10,by=2),rep(0,2),1:5)
> w
[1] 2 4 6 8 10 0 0 1 2 3 4 5
> dim(w)
NULL
> dim(w)=c(6,2)
> w
[,1] [,2]
[1,] 2 0
[2,] 4 1
[3,] 6 2
[4,] 8 3
[5,] 10 4
[6,] 0 5
> dim(w)=c(2,6)
> w
[,1] [,2] [,3] [,4] [,5] [,6]
[1,] 2 6 10 0 2 4
[2,] 4 8 0 1 3 5
> dim(w)=c(6,2)
> w
[,1] [,2]
[1,] 2 0
[2,] 4 1
[3,] 6 2
[4,] 8 3
[5,] 10 4
[6,] 0 5
> dim(w)=c(2,3,2)
> w
, , 1
, , 2
Como se puede observar en el ejemplo anterior, la forma de colocar los datos es rellenando
por columnas los sucesivos bloques. A los elementos colocados en cada posición se les puede
denominar con el nombre del array seguido de su posición entre [ ] y separando los subı́ndices
que describen dicha posición entre comas.
Otra forma de construir arrays a partir de vectores, es mediante la función array, espe-
cificando el nombre del vector y la dimensión del nuevo objeto. Veamos un ejemplo.
> x=rnorm(50, 2, 3)
> arx=array(x, c(5, 5, 2))
> arx
, , 1
, , 2
2.4. LISTAS 33
Cuando usamos la función array, si el vector no tiene elementos suficientes para rellenar
los huecos del array, éste se completa con los primeros valores del vector.
2.4. Listas
La función list devuelve un objeto tipo “lista” con tantas componentes como argumentos
se le suministren. Se utiliza para devolver resultados de una función.
> dias.semana=c("Lunes","Martes","Miercoles","Jueves","Viernes","Sabado","Domingo")
> dias.semana
[1] "Lunes" "Martes" "Miercoles" "Jueves" "Viernes" "Sabado"
[7] "Domingo"
> list(A=dias.semana,B=1:7)
$A
[1] "Lunes" "Martes" "Miercoles" "Jueves" "Viernes" "Sabado"
[7] "Domingo"
$B
[1] 1 2 3 4 5 6 7
Para referirnos a cada uno de los elementos de la lista lo hacemos mediante dobles corche-
tes. Si los elementos tienen nombre, entonces también podemos usar el sı́mbolo $ y el nombre
del elemento.
> list(A=dias.semana,B=1:7)[[1]]
[1] "Lunes" "Martes" "Miercoles" "Jueves" "Viernes" "Sabado"
[7] "Domingo"
> list(A=dias.semana,B=1:7)[[2]]
[1] 1 2 3 4 5 6 7
> list(A=dias.semana,B=1:7)$A
[1] "Lunes" "Martes" "Miercoles" "Jueves" "Viernes" "Sabado"
[7] "Domingo"
> list(A=dias.semana,B=1:7)$B
[1] 1 2 3 4 5 6 7
34 CAPÍTULO 2. MANIPULACIÓN DE DATOS
La diferencia fundamental entre las tres formas: [, [[ y $ es que la primera permite selec-
cionar varios elementos, en tanto que las dos últimas sólo permiten seleccionar uno. Además,
$ no permite utilizar ı́ndices calculados. El operador [[ necesita que se le indiquen todos los
ı́ndices (ya que debe seleccionar un solo elemento) y [ permite obviar ı́ndices, en cuyo caso
se seleccionan todos los valores posibles. Si se aplican a una lista, [[ devuelve el elemento de
la lista especificado y [ devuelve una lista con los elementos especificados.
> lista1=list(A=dias.semana,B=1:7)
> lista2=list(lista1,C="Hola",D=matrix(1:8,2))
> lista1
$A
[1] "Lunes" "Martes" "Miercoles" "Jueves" "Viernes" "Sabado"
[7] "Domingo"
$B
[1] 1 2 3 4 5 6 7
> lista2
[[1]]
[[1]]$A
[1] "Lunes" "Martes" "Miercoles" "Jueves" "Viernes"
[6] "Sabado" "Domingo"
[[1]]$B
[1] 1 2 3 4 5 6 7
$C
[1] "Hola"
$D
[,1] [,2] [,3] [,4]
[1,] 1 3 5 7
[2,] 2 4 6 8
> lista2[[1]]
$A
[1] "Lunes" "Martes" "Miercoles" "Jueves" "Viernes"
[6] "Sabado" "Domingo"
$B
[1] 1 2 3 4 5 6 7
> lista2[[2]]
2.5. HOJA DE DATOS (DATA.FRAME) 35
[1] "Hola"
> lista2[[3]]
[,1] [,2] [,3] [,4]
[1,] 1 3 5 7
[2,] 2 4 6 8
> lista2[[4]]
Error in lista2[[4]] : subı́ndice fuera de los lı́mites
> lista2[[1]]$A
[1] "Lunes" "Martes" "Miercoles" "Jueves" "Viernes"
[6] "Sabado" "Domingo"
> lista2[[1]]$B
[1] 1 2 3 4 5 6 7
[1] FALSE
> is.data.frame(datos1)
[1] TRUE
> datos1[2]
Altura
1 1.90
2 1.87
3 1.70
> datos2[3]
Sexo
1 Hombre
2 Hombre
3 Mujer
> is.factor(datos1[2])
[1] FALSE
> str(datos1[2])
‘data.frame’: 3 obs. of 1 variable:
$ Altura: num 1.9 1.87 1.7
> is.factor(datos2[[3]])
[1] TRUE
> nombres=c("Pepe","Paco","Pepita")
> nombres
[1] "Pepe" "Paco" "Pepita"
> datos3=data.frame(datos2,Nombres=I(nombres))
> datos3
Peso Altura Sexo Nombres
1 90 1.90 Hombre Pepe
2 120 1.87 Hombre Paco
3 56 1.70 Mujer Pepita
Si se desea seleccionar un subconjunto de una hoja de datos, se puede hacer con la función
subset, función que puede utilizar también en vectores. Para realizar modificaciones en un
data frame es muy útil la función transform.
> datos3
Peso Altura Sexo Nombres
1 90 1.90 Hombre Pepe
2 120 1.87 Hombre Paco
3 56 1.70 Mujer Pepita
2.5. HOJA DE DATOS (DATA.FRAME) 37
> subset(datos3,select=c(Sexo,Nombres))
Sexo Nombres
1 Hombre Pepe
2 Hombre Paco
3 Mujer Pepita
> subset(datos3,subset=c(Sexo=="Mujer"))
Peso Altura Sexo Nombres
3 56 1.7 Mujer Pepita
> subset(datos3,subset=Sexo=="Mujer")
Peso Altura Sexo Nombres
3 56 1.7 Mujer Pepita
> transform(datos3,logPeso=log(Peso))
Peso Altura Sexo Nombres logPeso
1 90 1.90 Hombre Pepe 4.499810
2 120 1.87 Hombre Paco 4.787492
3 56 1.70 Mujer Pepita 4.025352
> transform(datos3,IMC=Peso/Altura^2)
Peso Altura Sexo Nombres IMC
1 90 1.90 Hombre Pepe 24.93075
2 120 1.87 Hombre Paco 34.31611
3 56 1.70 Mujer Pepita 19.37716
> #Obsérvese que el archivo original no cambia
> datos3
Peso Altura Sexo Nombres
1 90 1.90 Hombre Pepe
2 120 1.87 Hombre Paco
3 56 1.70 Mujer Pepita
Como hemos visto, la funcion de R data.frame permite concatenar todas las variables
en un solo conjunto de datos. De la misma forma, también podemos guardar en un archivo
dicho conjunto de datos utilizando la función write.table. El formato del archivo guardado
es .CSV (comma separated variables, variables separadas por comas). Éste es un formato de
texto muy fácil de leer con cualquier editor de texto como Excel. Para leer el archivo en R
usaremos read.csv.
> misdatos=list(A=c(1,2),B=matrix(0,nrow=3,ncol=2),CC="Hola")
> misdatos
$A
[1] 1 2
$B
[,1] [,2]
[1,] 0 0
[2,] 0 0
[3,] 0 0
$CC
[1] "Hola"
> A
Error: objeto ’A’ no encontrado
> B
Error: objeto ’B’ no encontrado
> CC
Error: objeto ’CC’ no encontrado
> attach(misdatos)
> A
[1] 1 2
> B
[,1] [,2]
[1,] 0 0
[2,] 0 0
[3,] 0 0
> CC
[1] "Hola"
> detach(misdatos)
> A
Error: objeto ’A’ no encontrado
2.6. LECTURA Y ESCRITURA DE DATOS 39
> B
Error: objeto ’B’ no encontrado
> CC
Error: objeto ’CC’ no encontrado
> misdatos=data.frame(A=c(1,2),B=matrix(0,nrow=3,ncol=2),CC="Hola")
Error in data.frame(A = c(1, 2), B = matrix(0, nrow = 3, ncol = 2), CC = "Hola") :
arguments imply differing number of rows: 2, 3, 1
> misdatos=data.frame(A=c(1,2),B=matrix(0,nrow=2,ncol=3),CC="Hola")
> misdatos
A B.1 B.2 B.3 CC
1 1 0 0 0 Hola
2 2 0 0 0 Hola
> attach(misdatos)
> A
[1] 1 2
> B.1
[1] 0 0
> CC
[1] Hola Hola
Levels: Hola
> detach(misdatos)
> A
Error: objeto ’A’ no encontrado
> B.1
Error: objeto ’B.1’ no encontrado
> CC
Error: objeto ’CC’ no encontrado
read.table("path_archivo",header=TRUE,sep="",na.strings="NA",dec=".")
Con ella estamos indicando que R debe leer los datos que se encuentran en la ruta indicada
(usando /) y que dichos datos tienen cabecera (es decir que existe una primera fila con los
nombres de las variables). Con na.strings=“NA” indicamos que los valores faltantes los tome
40 CAPÍTULO 2. MANIPULACIÓN DE DATOS
como NAs. El separador decimal de los datos que tenemos es el punto en vez de la coma.
Hay otros argumentos que se le pueden añadir a la función, tales como el tipo de valores de
los datos (lógicos, enteros, etc.), el número de columnas, etc.
También serı́a posible leer los datos directamente de una página web o repositorio digital
de la siguiente forma:
> Datos=read.table("http://www.mat.ucm.es/~albfranc/eng/scoredata.txt",
header=T,sep="",na.strings="NA",dec=".")
Con la función View visualizamos los datos que hemos cargado en memoria anteriormente.
> View(Datos)
Con la función fix podemos modificar los datos cambiando o añadiendo elementos.
> fix(Datos)
Con la función write podemos crear ficheros a partir de los datos que vamos calculando
con R o con datos que nosotros vamos introduciendo. Por ejemplo:
> #Con la siguiente orden creamos una tabla en blanco a la que nombramos Datos1
> Datos1=edit(as.data.frame(NULL))
2.7. BASES DE DATOS CONOCIDAS 41
Cuando terminamos de introducir los datos, cerramos la ventana Editor de datos. Y vemos
que, efectivamente, se ha creado el fichero de datos Datos1.
> Datos1
var1 var2
1 1 2
2 3 4
3 2 1
4 4 2
5 3 1
> #Vamos a guardar en A y en B, respectivamente, las columnas
> A=Datos1$var1
> B=Datos1$var2
> A
[1] 1 3 2 4 3
> B
[1] 2 4 1 2 1
> #Creamos un fichero vector con la suma de los dos elementos
> A+B
[1] 3 7 3 6 4
> #Lo guardamos en un fichero .txt que se llame sumaAyB
> write(A*B,"sumaAyB.txt")
> data()
42 CAPÍTULO 2. MANIPULACIÓN DE DATOS
El archivo “AirPassengers” es una base muy conocida en el contexto de las series tempo-
rales. Si queremos más información relativa a estos datos podemos escribir:
> AirPassengers
Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec
1949 112 118 132 129 121 135 148 148 136 119 104 118
1950 115 126 141 135 125 149 170 170 158 133 114 140
1951 145 150 178 163 172 178 199 199 184 162 146 166
1952 171 180 193 181 183 218 230 242 209 191 172 194
1953 196 196 236 235 229 243 264 272 237 211 180 201
1954 204 188 235 227 234 264 302 293 259 229 203 229
1955 242 233 267 269 270 315 364 347 312 274 237 278
1956 284 277 317 313 318 374 413 405 355 306 271 306
1957 315 301 356 348 355 422 465 467 404 347 305 336
1958 340 318 362 348 363 435 491 505 404 359 310 337
1959 360 342 406 396 420 472 548 559 463 407 362 405
1960 417 391 419 461 472 535 622 606 508 461 390 432
> help(AirPassengers)
starting httpd help server ... done
> dim(USArrests)
[1] 50 4
> dim(cars)
[1] 50 2
Para probar nuevas técnicas de análisis discriminante se suele recurrir al archivo “iris”,
que contiene medidas del ancho y la longitud del pétalo y el sépalo de un conjunto de tres
tipos de flores.
La librerı́a MASS es una de las más utilizadas. Está directamente ligada al libro de
Venables y Ripley (2002).
> library(MASS)
> data()
2.7. BASES DE DATOS CONOCIDAS 43
Con estos comandos vemos las bases de datos que ya tenı́amos y a las que tenemos acceso
ahora que hemos cargado la librerı́a MASS. Para visualizar los datos Aids2 ponemos:
> Aids2
> pbc
Error: objeto ‘pbc’ no encontrado
> library(survival)
Loading required package: splines
> pbc
44 CAPÍTULO 2. MANIPULACIÓN DE DATOS
Capı́tulo 3
FUNCIONES
Como hemos visto anteriormente, las funciones permiten realizar las diferentes acciones.
Existen funciones ya definidas (aunque pueden ser modificadas) pero, además, R permite
crear nuevas funciones. Estas nuevas funciones se incorporan al lenguaje y se utilizan poste-
riormente como las ya existentes.
Las funciones tradicionales de uso matemático y estadı́stico, están definidas. Entre ellas
las más utilizadas son: abs, sqrt, sin, cos, tan, exp, log, log10, min, max, sum, prod,
length, range, mean, median, var, cov, summary, sort, rev y order.
> sin(1:5)
[1] 0.8414710 0.9092974 0.1411200 -0.7568025 -0.9589243
> rev(sin(1:5))
[1] -0.9589243 -0.7568025 0.1411200 0.9092974 0.8414710
> sin(pi)
[1] 1.224606e-16
> sin(pi/2)
[1] 1
> sum(1:5)
[1] 15
> prod(1:5)
[1] 120
45
46 CAPÍTULO 3. FUNCIONES
La expresión es una fórmula o grupo de fórmulas que utilizan los argumentos para calcular
un valor. El valor de dicha expresion es el valor que proporciona R en su salida y éste puede
ser un simple número, un vector, una gráfica, una lista o un mensaje.
> funcion.suma=function(A,B){
+ A+B}
> funcion.suma(10,3)
[1] 13
> funcion.suma(12,30)
[1] 42
La función que acabamos de definir no se refiere a la suma de dos números, sino a la suma
de dos objetos, que podrán ser vectores, matrices, variables indexadas, etc. Si le asignamos
dos valores concretos los sumará, como hemos visto en el ejemplo anterior.
> funcion.suma(c(1,12),c(3,0))
[1] 4 12
Si se desea enfatizar cuál será el valor devuelto, se puede utilizar el comando return.
Cuando se encuentra esta orden, la función detiene la ejecución y devuelve los valores indi-
cados.
> primera.funcion=function(A,B){
+ #esta función devuelve el valor suma A+B
+ return(A+B)
+ }
> primera.funcion(2,4)
[1] 6
> primera.funcion=function(A=1,B=-2){
+ #esta función devuelve el valor suma A+B
+ return(A+B)
+ }
> primera.funcion()
[1] -1
> primera.funcion(3)
[1] 1
Es posible acceder a los argumentos o cuerpo de una función mediante los comandos
formals y body.
3.2. EJEMPLOS DE FUNCIONES ELEMENTALES EN ESTADÍSTICA 47
> formals(primera.funcion)
> formals(primera.funcion)
$A
[1] 1
$B
-2
> body(primera.funcion)
{
return(A + B)
}
A través de la función expression. En el siguiente ejemplo se muestra cómo utilizar esta
función.
#Modificamos el cuerpo de la función
> body(primera.funcion)=expression(A*B)
> body(primera.funcion)
A * B
> body(primera.funcion)=expression({A*B})
> body(primera.funcion)
{
A * B
}
> primera.funcion(3,1)
[1] 3
> primera.funcion(3)
[1] -6
Otra orden interesante para modificar funciones es edit. Con ella podemos editar la
función que necesitemos y adaptarla a nuestras necesidades.
> edit(primera.funcion)
Se abre una ventana que nos permite editar la función que hemos creado conteriormente.
> mean(c(2,4,1,3,6,7))
[1] 3.833333
> mean(c(2,4,1,3,6,NA))
[1] NA
> mean(c(2,4,1,3,6,NA),na.rm=TRUE)
[1] 3.2
Vamos a crear nuestra propia función media. Será una función de un único argumento.
La función presupone que el argumento dado es un vector, elimina las componentes de dicho
vector que son NAs y calcula la media del resto de las componentes. Recordemos que ! indica
negación.
> media=function(x){
+ x=x[!is.na(x)]
+ sum(x)/length(x)
+ }
> media(c(2,4,1,3,6,7))
[1] 3.833333
> media(c(2,4,1,3,6,NA))
[1] 3.2
> var(c(2,4,1,3,6,7))
[1] 5.366667
> var(c(2,4,1,3,6,NA))
[1] NA
> var(c(2,4,1,3,6,NA),na.rm=TRUE)
[1] 3.7
Creamos una nueva función en R que calcule la cuasivarianza muestral. Será una función
de un único argumento. La función presupone que el argumento dado es un vector, elimina
las componentes de dicho vector que son NAs y calcula la cuasivarianza del resto de las
componentes.
> Varianza=function(x){
+ x=x[!is.na(x)]
+ v=sum((x-(sum(x)/length(x)))^2)/(length(x)-1)
+ return(v)
+ }
3.3. ESTRUCTURAS CONDICIONALES 49
> Varianza(c(2,4,1,3,6,7))
[1] 5.366667
> Varianza(c(2,4,1,3,6,NA))
[1] 3.7
Las estructuras condicionales son aquellas que, según el resultado de una comparación,
realizan una u otra acción. La primera estructura que veremos es:
> x=c(-2:3)
> Inverso=ifelse(x==0,"no se puede dividir por 0",1/x)
> Inverso
[1] "-0.5" "-1"
[3] "no se puede dividir por 0" "1"
[5] "0.5" "0.333333333333333"
repeat {acción}
La estructura for asigna a “variable” cada uno de los valores y realiza la acción para cada
uno de ellos. La estructura while evalúa la condición y, mientras ésta es cierta, se realiza
la acción. La estructura repeat realiza la acción indefinidamente. En los tres casos, el valor
del ciclo completo es el correspondiente a la última acción. Las expresiones pueden contener
algún condicional como if asociado con las funciones next o break. El comando next indica
que debe terminarse la iteración actual y pasar a la siguiente. El comando break indica que
debe terminarse el ciclo. Vamos a ver algunos ejemplos.
> new_factorial=function(n){
+ f=1
+ if(n>1) {for(i in 1:n) f=f*i}
+ return(f)
+ }
3.5. MÁS EJEMPLOS DE FUNCIONES 51
> new_factorial(3)
[1] 6
> new_factorial(25)
[1] 1.551121e+25
> new_factorial(0)
[1] 1
La siguiente función es similar pero utiliza while en lugar de for:
> new_factorial2=function(n){
+ f=1
+ i=1
+ if(n>1) {while(i<=n){
+ f=f*i
+ i=i+1}}
+ return(f)
+ }
> new_factorial2(3)
[1] 6
> new_factorial2(25)
[1] 1.551121e+25
> new_factorial2(0)
[1] 1
Sn = a1 + a2 + . . . + an = n(a1 + an )/2,
+ return(sum(v))
+ }
> arit.1(10,2,3)
[1] 155
> arit.2=function(n,a1,d){
+ v=numeric()
+ v[1]=a1
+ for (i in 2:n){
+ v[i]=v[i-1]+d
+ }
+ return(n*(v[1]+v[n])/2)
+ }
> arit.2(10,2,3)
[1] 155
En este caso también podemos construir varias funciones para implementarla. Usaremos
la siguiente notación:
> geom.1=function(n,a1,r){
+ v=numeric()
+ v[1]=a1
+ for(i in 2:n) v[i]=v[i-1]*r
+ return(sum(v))
+ }
> geom.1(2,3,2)
[1] 9
> geom.2=function(n,a1,r) a1*(r^n-1)/(r-1)
> geom.2(2,3,2)
[1] 9
Capı́tulo 4
OPCIONES GRÁFICAS
Los gráficos disponibles en R son todos de gran calidad y poseen una versatilidad muy
grande. Para hacernos una idea, podemos ejecutar la demo:
> demo("graphics")
Comando Significado
plot(...) Función genérica para representar en el plano xy puntos, lı́neas, etc.
curve(...) Representa gráficamente una función dada.
barplot(...) Representa un diagramas de barras.
pie(...) Realiza un diagramas de sectores.
hist(...) Crea el histograma.
boxplot(...) Realiza un diagramas de box-and-whisker (caja y bigotes).
pairs(...) Crea un diagrama de puntos entre dos o más variables.
Para crear gráficos más completos podemos ayudarnos de las siguientes funciones:
Comando Significado
points(...) Añade puntos a un gráfico.
abline(...) Añade una recta de pendiente e intersección dadas.
lines(...) Añade curvas a un gráfico.
polygon(...) Añade polı́gonos a un gráfico.
rect(...) Añade rectángulos a un gráfico.
arrows(...) Añade flechas a un gráfico.
segments(...) Añade segmentos a un gráfico.
53
54 CAPÍTULO 4. OPCIONES GRÁFICAS
> x=seq(-10,10)
> x
[1] -10 -9 -8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8
[20] 9 10
> plot(x,x,xlim=c(0,10),ylim=c(0,10))
Veamos algunos argumentos que podemos usar en la función plot, como type:
> plot(x,x,xlim=c(0,10),ylim=c(0,10),type="l")
> plot(x,x,xlim=c(0,10),ylim=c(0,10),type="s")
> plot(1:100,(1:100)^2,type="l")
> #Ahora generamos un gráfico de dos variables comprendidas entre -4 y 4
> plot(-4:4,-4:4,type="n")
> # Representamos 20 números aleatorios de una distribución normal en rojo
> points(rnorm(20),rnorm(20),col="red")
> #Ojo porque para que points funcione debo tener un gráfico activo
> #Representamos 10 números aleatorios de una distribución normal en azul más grandes
> points(rnorm(10),rnorm(10),col="blue",cex=3)
> abline(1,1,col="blue")
> abline(1,2,col="blue")
> for(i in 1:10) {abline(h=i,col=i)}
> for(i in -2:2) {abline(v=i,col="red")}
Al igual que points, abline requiere que haya un gráfico activo para funcionar.
También text es una función muy útil, ya que nos permite añadir texto a un gráfico
existente. A continuación creamos una gráfica de dos variables x e y, con x entre -2 y 3 e y
entre -1 y 5.
4.2. FUNCIÓN PLOT 55
> plot(c(-2,3),c(-1,5),type="n",xlab="x",ylab="y")
> #Creamos un eje xy de color rojo
> abline(h=0,v=0,col="red")
> #Asignamos una leyenda (recta y=0), de color azul en el par (1,0)
> text(1.75,0.25,"recta (y = 0)",col="blue")
> #Creamos una red para distinguir los pares
> abline(h=-1:5,v=-2:3,col="lightgray",lty=3)
> #Creamos una recta de pendiente 2 y término independiente 1
> abline(a=1,b=2,col=2)
> #A~
nadimos una leyenda para nombrar la recta y=2x+1
> text(1.75,3.25,"recta y=2x+1",col="green")
> x=-5:5
> #Creamos un gráfico con tı́tulo
> plot(x,x^2-2,type="l",main="Gráfico con tı́tulo",sub="y subtı́tulo")
> #A~
nadimos tı́tulo y subtı́tulo a un gráfico
> plot(x=-5:5,x^2-2,type="l")
> title(main="Gráfico con tı́tulo",sub="y subtı́tulo")
> x=-5:5
> plot(x,2*x+1,type="l",xlab="x",ylab="y",xlim=c(-4,5),ylim=c(-1,5),col="red")
> lines(x,rep(0,length(x)),col="red")
> y=-2:6
> lines(rep(0,length(y)),y,col="red")
> text(1,0,"recta( y = 0 )",col="blue")
> abline(h=-1:5,v=-2:3,col="lightgray",lty=3)
> abline(a=1,b=2,col=2)
> text(1,3,"recta y=2x+1",col="green")
La función par nos permite presentar gráficos múltiples. El argumento mfcol=c(m,n), di-
vide el dispositivo gráfico en mxn partes iguales, que se rellenan por columnas. Análogamente
mfrow=c(m,n) rellena por filas.
> x=1:10
> y=(3:12)^3
> par(mfrow=c(2,3))
> plot(x)
56 CAPÍTULO 4. OPCIONES GRÁFICAS
> plot(y)
> plot(x,y)
> plot(x^2,y)
> plot(x,y^2)
> plot(x^2,y^2)
Cada gráfico que creamos es independiente y podemos dar tı́tulo a cada uno.
> plot(0,0,type="n",xlim=c(-5,5),ylim=c(-5,5))
> x=c(0,4,2,-2,-4)
> y=c(-4,0,4,4,0)
> polygon(x,y,col="red",border="black")
> plot(0,0,type="n",xlim=c(-5,5),ylim=c(-5,5))
> x=c(0,4,2,-2,-4)
> y=c(-4,0,4,4,0)
> polygon(1:9,c(2,1,2,1,NA,2,1,2,1),density=c(10,20),angle=c(-45,45),col=c(2,"blue"))
> #Creamos un marco para la gráfica con x entre -10 y 10 e y en entre -10 y 10
> plot(0,0,type="n",xlim=c(-10,10),ylim=c(-10,10))
> #Creamos un rectángulo con x de -4 a 4 e y de -4 a 4 de color rojo
> rect(-4,-4,4,4,col="red",border="black")
> x=1:12
> y=c(10,2,3,10,11,5,6,3,8,11,9,12)
> plot(x,y,main="Flechas")
> #Flechas
> for (s in 1:12){arrows(x[s],y[s],x[s+1],y[s+1],col=1:3)}
> curve(tan,-2*pi,2*pi)
> curve(sin)
> #Si no borramos la gráfica anterior:
> curve(tan,-2*pi,2*pi)
> curve(sin,add=TRUE,col="red")
> #Polinomiales
> curve(x^3-3*x,-2,2)
> #Le adjuntamos una parábola
> curve(x^2-2*x+1,add=TRUE,col="red")
> x=c(1,2,3,1,2,1,2,4,1,3,2,4,1,2,3,1,2,4,2,1)
> #Primero calculamos la frecuencia acumulada de cada una de las variables
> table(x)
58 CAPÍTULO 4. OPCIONES GRÁFICAS
x
1 2 3 4
7 7 3 3
> frec.x=table(x)
> #Creamos el diagrama de barras con las leyendas
> barplot(frec.x, main="Frecuencia absoluta",xlab="Valores de la variable")
Vamos a ponerle nombre a las variables y a cambiar las barras verticales por barras
horizontales.
> barplot(frec.x, main="Frecuencia absoluta", xlab="valores de la variable",
horiz=TRUE,names.arg=c("Menores de 18","De 18 a 45","De 45 a 65","Mas de 65"))
Veamos ahora cómo realizar un gráfico de barras un poco más complejo.
> #Representamos un diagrama de barras con tres variables
> barplot(height=cbind(c(4,9),c(8,2),c(3,7)),beside=TRUE,width=c(45,50,35),
col=c(1,2),legend.text=c("hombre","mujer"))
Si nos fijamos, hay una variable numérica en la base de datos que es cyl y que discrimina
entre aquellos coches con 4, 6 u 8 cilindros. Con las siguientes intrucciones veremos cómo
realizar un boxplot en función de los valores que toma cyl.
Podemos usar los distintos argumentos de boxplot para que éste sea más vistoso y fácil
de interpretar.
> x=1:20
> y=rnorm(20)
> z=y^3
> pairs(cbind(x,y,z))
> pairs(~x+y+z)
Bibliografı́a
[1] Arriaza A. J., Fernandez F. y otros (2008), Estadı́stica Básica con R y R-Commander,
Servicio de Publicaciones de la Universidad de Cádiz.
[4] Everitt, Brian S. (2005). An R and S-Plus Companion to Multivariate Analysis. Springer.
[5] Faraway, J. (2004). Linear Models with R. Chapman Hall/CRC, Boca Raton, FL.
[6] Febrero, M., Galeano, P., González J. y Pateiro B. (2008). Prácticas de Estadı́stica en R
Ingenierı́a Técnica en Informática de Sistemas.
[9] Paradis E. (2002), R para Principiantes, Institut des Sciences de l’Evolution Universit
Montpellier II.
[13] Verzani, J. (2005). Using R for Introductory Statistics. Chapman Hall/CRC, Boca
Raton, FL.
61