Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Objetivos
Asignar nombres a los elementos de un vector.
> x[2]
[1] 2.718281
> x[3]
[1] 1.618034
1
2 1.2 Variables lógicas en R
pi e phi
3.141592 2.718281 1.618034
> pi
[1] 3.141593
> exp(1)
[1] 2.718282
> (1+sqrt(5))/2
[1] 1.618034
Ahora, si queremos referirnos at tercer elemento, podemos optar por x[3] o, dado
que hemos asignado nombres a los elementos del vector, podemos hacer
> x["phi"]
phi
1.618034
> x<-1:5
> x==4
> x<4
> x>=4
> sum(x<4)
[1] 3
> sum(x>=4)
[1] 2
> set.seed(111)
> y<-runif(100)
> mean(y)
[1] 0.4895239
> sum(y<mean(y))
[1] 51
[1] 50
Veamos ahora el efecto que tiene colocar un vector lógico entre los corchetes de
ı́ndice de un vector:
> z<-1:5
> z[c(TRUE, FALSE, TRUE, FALSE, TRUE)]
4 1.2.2 Condiciones lógicas compuestas
[1] 1 3 5
donde el vector lógico c(TRUE, FALSE, TRUE, FALSE, TRUE) es uno de igual longi-
tud que x y donde TRUE y FALSE representan verdadero y falso, respectivamente.
El efecto de la instrucción es el de devolver únicamente aquellos valores de x cuyo
ı́ndice valga TRUE.
La instrucción y[y<0.1] devuelve no cuántos, sino cuáles son los valores que
cumplen la condición de estar por debajo de 0.1:
> y[y<0.1]
> y[(y<0.05)|(y>0.95)]
[1] 11
[1] 5.986717
Podrı́amos desear los valores de y que están por encima de 0.45 y por debajo de
0.55:
> y[(y>0.45)&(y<0.55)]
[1] 4 8 32 33 34 56 58 62 73 91
Estas son las posiciones que ocupan los 89 valores que obtuvimos anteriormente.
En resumen, en este apartado hemos visto cuáles, cuántos y qué posiciones ocupan
los valores que cumplen con determinadas condiciones impuestas.
Poner un ejemplo de detección de valores anómalos usando el diagrama
de cajas
> z<-3:10
> z[-1]
[1] 4 5 6 7 8 9 10
> z[-(1:3)]
[1] 6 7 8 9 10
> z[-((length(z)-2):length(z))]
[1] 3 4 5 6 7
Si bien puede parecer más natural, para el mismo objetivo podemos usar
> rev(z)[-(1:3)]
[1] 7 6 5 4 3
que nos da un vector resultante en orden inverso al original, aspecto que se puede
corregir con
6 1.3 Matrices en R
> rev(rev(z)[-(1:3)])
[1] 3 4 5 6 7
> z[-which(z<6)]
[1] 6 7 8 9 10
> w<-c(5,2,8,5,4,6,9,9)
> w
[1] 5 2 8 5 4 6 9 9
> rev(sort(w)[-c(1,2)])[-c(1,2)]
[1] 8 6 5 5
Expresión en la que, primero, hemos ordenado el vector original con sort, luego,
excluido los valores menores, a continuación, hemos invertido el vector resultante con
rev y, finalmente, hemos suprimido los dos primeros valores, que son los dos mayores
del vector original.
1.3. Matrices en R
Además de los objetos vistos hasta aquı́, introducimos ahora este nuevo tipo para
crear matrices con el comando matrix(). Podemos crear una matriz a partir de un
vector
> x<-1:12
> y<-matrix(x,nrow=3)
> y
Con matrix, se crea una matriz de tres filas (nrow=3) a partir de un vector (x) de
longitud 12. Nótese que los valores del vector se introducen, por defecto, por columnas.
El mismo efecto podrı́a haberse conseguido con
Práctica 2: Simulación con R 7
> y<-matrix(x,ncol=4)
> y
y se crea la misma matriz con 4 columnas y, por lo tanto, tres filas, pues ncol=4
obliga a que ası́ sea. Si queremos que se introduzcan por filas, se ha de proceder ası́:
Véase el efecto de
con lo que se ha construido una matriz de tres columnas, con los datos introducidos
por filas. Podemos, también, convertir directamente el vector original en una matriz
redefiniendo las dimensiones del vector.
Véase
> class(x)
[1] "integer"
que nos muestra que x es un vector de enteros y el efecto que tiene el redimensionar
x con la función dim
> dim(x)<-c(3,4)
> x
> class(x)
[1] "matrix"
que nos muestra que, ahora, x ya no es más un vector y que ha pasado a ser una
matriz. Se pueden asignar nombres a filas y columnas con rownames y colnames
> rownames(x)<-c("lunes","martes","miércoles")
> x
Podemos referirnos a los elementos de una matriz indicando la posición (de la fila
y la columna) con corchetes:
> x[1,2]
lunes
4
> colnames(x)<-c("marzo","abril","mayo","junio")
> x["lunes","abril"]
[1] 4
> x[,2]
que nos muestra los elementos de la columna 2 (aunque mostrados en forma de fila).
O bien la fila 3
> x[3,]
> x[1:2,]
O bien, excluirlas
> x[-(1:2),]
> sum(x)
[1] 78
> mean(x)
[1] 6.5
> var(x)
> mean(x[,2])
[1] 5
> var(x[2,])
10 1.3.1 Operaciones con matrices
[1] 15
> colSums(x)
> colMeans(x)
> rowSums(x)
> summary(x)
> apply(x,1,var)
donde el parámetro 1 indica que trabajamos por filas y podrı́amos añadir una nueva
columna a la matriz x con estas varianzas, mediante cbind:
Práctica 2: Simulación con R 11
> xx<-cbind(x,apply(x,1,var))
> xx
> colnames(xx)<-c(colnames(x),"varianzas")
> xx
> apply(x,2,var)
donde el parámetro 2 indica que trabajamos por columnas y podrı́amos añadir esta
fila a la matriz:
> xxx<-rbind(x,apply(x,2,var))
> xxx
> rownames(xxx)<-c(rownames(xx),"varfil")
> xxx
Producto de matrices:
> x<-matrix(1:4,nrow=2)
> y<-matrix(2:5,nrow=2)
> x
[,1] [,2]
[1,] 1 3
[2,] 2 4
> y
[,1] [,2]
[1,] 2 4
[2,] 3 5
> x%*%y
[,1] [,2]
[1,] 11 19
[2,] 16 28
> 2*x
[,1] [,2]
[1,] 2 6
[2,] 4 8
> x+y
[,1] [,2]
[1,] 3 7
[2,] 5 9
> x-y
[,1] [,2]
[1,] -1 -1
[2,] -1 -1
> z<-diag(c(2,-1,3))
> z
Práctica 2: Simulación con R 13
Modificar la diagonal:
> diag(z)<-c(4,3,3)
> z
Hallar un determinante:
> det(x)
[1] -2
> solve(x)
[,1] [,2]
[1,] -2 1.5
[2,] 1 -0.5
> x%*%solve(x)
[,1] [,2]
[1,] 1 0
[2,] 0 1
> x*y
[,1] [,2]
[1,] 2 12
[2,] 6 20
1.4. Simulaciones
La función sample es muy útil para efectuar simulaciones
> sample(1:10,6)
[1] 6 2 8 9 5 1
> sample(1:10,6,rep=TRUE)
[1] 7 3 6 10 2 7
1.4.1. Dados
Para simular la tirada de un dado podemos utilizar
> sample(1:6,1)
[1] 6
> sample(1:6,4,rep=TRUE)
[1] 6 6 4 4
admitiendo repetición.
Si queremos simular la distribución de la suma de los números que salen al tirar
4 dados
> t<-sapply(1:10000,function(x){sum(sample(1:6,4,rep=TRUE))})
donde la función sapply aplica a un vector de tamaño 10000 (el que va de 1 a 10000)
una función sin nombre, generando a su vez un vector de tamaño 10000. La función
obtiene muestras con repetición de tamaño 4 y, a continuación, suma los números de la
muestra. Este proceso se repite 10000 veces. Lo mismo se podrı́a haber conseguido con
un ciclo for, pero el procedimiento utilizado es más rápido. Para garantizar que los
resultados son los mismos que los de esta práctica, nos servimos de set.seed(111).
> set.seed(111)
> t<-sapply(1:10000,function(x){sum(sample(1:6,4,rep=TRUE))})
> table(t)
t
4 5 6 7 8 9 10 11 12 13 14 15 16 17
11 31 82 170 263 417 633 773 976 1086 1121 1131 971 754
18 19 20 21 22 23 24
598 467 230 154 75 49 8
> barplot(table(t))
4 6 8 10 12 14 16 18 20 22 24
Figura 1.1: Diagrama de barras de las frecuencias obtenidas del lanzamiento de cuatro
dados.
> x<-runif(4,0,6)
> x
16 1.4.1 Dados
[1] 6 2 6 1
> ceiling(runif(4,0,6))
[1] 1 4 6 1
> t<-sapply(1:10000,function(x){sum(ceiling(runif(4,0,6)))})
> t<-sapply(1:10000,function(x){sum(sample(1:6,4,rep=TRUE))})
Si lo que se quiere es simular el número de veces que sale, digamos, un seis, en,
por ejemplo, 10 tiradas, como el número de seises sigue una distribución binomial
de n=10 y p=1/6, podemos utilizar la función de R rbinom para generar números
aleatorios según esta distribución y realizar la simulación más cómodamente.
Con la siguiente expresión se generan 12 números aleatorios en las condiciones
antedichas
> xx<-rbinom(12,10,1/6)
> xx
[1] 4 2 3 3 1 2 1 0 2 1 1 3
> set.seed(111)
> t <- rbinom(10000, 10, 1/6)
> table(t)
Práctica 2: Simulación con R 17
t
0 1 2 3 4 5 6 7
1634 3209 2898 1572 537 127 20 3
y representamos con
> barplot(table(t))
según se puede ver en la Figura 1.2. Nótese que obtenemos un diagrama similar al
anteriormente obtenido en la Figura 1.1.
3000
2500
2000
1500
1000
500
0
0 1 2 3 4 5 6 7
Figura 1.2: Diagrama de barras de los éxitos obtenidos al simular de una Binomial.
1.4.2. Urnas
Tenemos una urna con 3 bolas blancas y 5 negras. Queremos simular la extracción
de una bola. El número 1 representa blanca y 0, negra. Podemos hacerlo con:
> bola<-sample(c(1,0),1,prob=c(3,5))
> bola
18 1.4.2 Urnas
[1] 0
[1] 0 1 0 1 0 0 0 1 0 0
En este caso, habrı́amos obtenido 3 bolas blancas en las 8 extracciones. Si lo que nos
interesa es sólo el número de bolas blancas, como este sigue una distribución binomial
con n=8 y p=3/8 podrı́amos escribir:
> rbinom(1,8,3/8)
[1] 2
> set.seed(111)
> t<-rbinom(10000,8,3/8)
> table(t)
t
0 1 2 3 4 5 6 7 8
232 1168 2288 2797 2174 984 299 54 4
> barplot(table(t))
> dbinom(0:8,8,3/8)
2500
2000
1500
1000
500
0
0 1 2 3 4 5 6 7 8
1.4.3. Barajas
Si estamos interesados en los oros que salen en una extracción de 12 cartas con
reposición, se trata de una distribución binomial con n=12 y p=10/40, ya que tenemos
10 cartas de oros de un total de 40 cartas en la baraja. Si repetimos el experimento
10000 veces obtenemos:
> t<-rbinom(10000,12,10/40)
> table(t)
t
0 1 2 3 4 5 6 7 8 9
307 1313 2287 2578 1907 1041 420 123 20 4
> t<-rpois(10000,15)
> table(t)
t
2 4 5 6 7 8 9 10 11 12 13 14 15 16
1 11 19 63 98 217 344 489 661 805 938 1005 998 933
17 18 19 20 21 22 23 24 25 26 27 28 29 30
864 696 536 459 317 210 135 87 54 27 16 10 2 1
31
4
y representamos con
> barplot(table(t))
> dpois(0:31,15)
con que obtenemos las probabilidades de los valores de 0 a 31, para una media de 15.
1000
800
600
400
200
0
2 5 7 9 11 14 17 20 23 26 29
Figura 1.4: Diagrama de barras con el número de personas en la cola de espera del
autobús.
> dbinom(5,10,.3)
[1] 0.1029193
devuelve la probabilidad P (X = 5), es decir, que una variable aleatoria X con distri-
bución binomial (n=10 y p=0.3) tome el valor 5.
> pbinom(5,10,.3)
[1] 0.952651
> pbinom(5,10,.3,lower.tail=FALSE)
[1] 0.04734899
> qbinom(0.952651,10,.3)
[1] 5
[1] 5
muestra el valor 5, que deja por encima de sı́ a 0.04734899 del total. O lo que es lo
mismo, P (X > 5) = 0,04734899.
> rbinom(5,10,.3)
[1] 2 4 5 2 1
genera 5 números aleatorios para una distribución binomial con n=10 y p=0.3.
Las restantes distribuciones rigen de modo análogo. Para saber qué parámetros
han de introducirse y en qué orden, se puede consultar la información disponible en
la ayuda. Por ejemplo ?dpois nos da la información correspondiente a las funciones
disponibles para la distribución de Poisson.
> dunif(5,0,6)
[1] 0.1666667
[1] 0.5
> punif(4,0,6,lower.tail=FALSE)
[1] 0.3333333
devuelve P (X > 4) en una uniforme entre 0 y 6.
> qunif(0.3,0,6)
[1] 1.8
devuelve el cuantil correspondiente a 0.3.
> qunif(0.6,0,6,lower.tail=FALSE)
[1] 2.4
devuelve el valor que deja por encima de sı́ a 0.6 del total. Es decir, P (X ≥ 2,4) = 0,6.
Por otro lado,
> runif(1,0,6)
[1] 1.518849
devuelve un número aleatorio para la distribución uniforme entre 0 y 6
Para las otras dos familias de funciones que nos interesan, la normal y la expo-
nencial, véase la información correspondiente en la ayuda. Por ejemplo con ?dnorm
o ?dexp podemos obtener información sobres cómo calcular sus respectivas funciones
de densidad. En la distribución exponencial, ha de tenerse en cuenta que el parámetro
rate coincide con la ordenada en el origen de la función de densidad y es igual al
inverso de la media. Para saber de qué distribuciones dispone R podemos escribir
> help.search("distribution")
y el resultado se puede ver en la Figura 1.5.
> set.seed(111)
> t<-sapply(1:10000,function(x){rnorm(1,3,2)+rnorm(1,5,3)})
> mean(t)
Práctica 2: Simulación con R 25
Histogram of t
0.20
0.15
Density
0.10
0.05
0.00
−4 −2 0 2 4 6 8 10
Figura 1.6: Histograma de datos simulados de una Normal junto con su función de
densidad de probabilidad.
[1] 7.998157
de manera que se cumple 7,998157 ' 3 + 5 (suma de medias). Algo similar ocurra
con las varianzas ya que
> var(t)
[1] 13.02742
> hist(t,freq=FALSE)
> curve(dnorm(x,8,sqrt(13)),-5,20,add=TRUE)
Histogram of t
0.10
0.08
0.06
Density
0.04
0.02
0.00
−5 0 5 10 15 20
Figura 1.7: Histograma de la suma de dos variables normales junto con la función de
densidad correspondiente.
> pexp(4,.2,lower.tail=FALSE)
[1] 0.449329
y P (X > 3) con
> pexp(3,.2,lower.tail=FALSE)
[1] 0.5488116
[1] 0.5488116