Primero debemos cargar las librerias necesesarias:
library(snpar)
library(dplyr)
library(ggplot2)
library(readr)
library(lubridate)
library(tidyverse)
Luego debemos cargar la base de datos.
flights <- read_csv("data/flights.csv")
Debemos verificar que todos los campos tengan el formato correcto:
str(flights)
## Classes 'spec_tbl_df', 'tbl_df', 'tbl' and 'data.frame': 227496 obs. of 14 variables:
## $ date : POSIXct, format: "2011-01-01 12:00:00" "2011-01-02 12:00:00" ...
## $ hour : num 14 14 13 14 14 13 13 13 14 14 ...
## $ minute : num 0 1 52 3 5 59 59 55 43 43 ...
## $ dep : num 1400 1401 1352 1403 1405 ...
## $ arr : num 1500 1501 1502 1513 1507 ...
## $ dep_delay: num 0 1 -8 3 5 -1 -1 -5 43 43 ...
## $ arr_delay: num -10 -9 -8 3 -3 -7 -1 -16 44 43 ...
## $ carrier : chr "AA" "AA" "AA" "AA" ...
## $ flight : num 428 428 428 428 428 428 428 428 428 428 ...
## $ dest : chr "DFW" "DFW" "DFW" "DFW" ...
## $ plane : chr "N576AA" "N557AA" "N541AA" "N403AA" ...
## $ cancelled: num 0 0 0 0 0 0 0 0 0 0 ...
## $ time : num 40 45 48 39 44 45 43 40 41 45 ...
## $ dist : num 224 224 224 224 224 224 224 224 224 224 ...
## - attr(*, "spec")=
## .. cols(
## .. date = col_datetime(format = ""),
## .. hour = col_double(),
## .. minute = col_double(),
## .. dep = col_double(),
## .. arr = col_double(),
## .. dep_delay = col_double(),
## .. arr_delay = col_double(),
## .. carrier = col_character(),
## .. flight = col_double(),
## .. dest = col_character(),
## .. plane = col_character(),
## .. cancelled = col_double(),
## .. time = col_double(),
## .. dist = col_double()
## .. )
Podemos observar que todos los campos tienen un tipo de dato adecuado, la mayoría son numéricos, un tipo fecha y el resto son de tipo caracter. No existen variables de tipo factor debido a que no hay variables ordinales.
Notemos que en la base de datos solo se propociona información de la hora y minutos en los que salió el avión, sin embargo no se da información sobre la hora planificada del vuelo. Por esta razón se crea una nueva columna con este dato. Para esto se utiliza el dato de retraso de salida. Utilizamos el siguiente código:
flights <- flights %>% mutate(minutos_plan = minute-dep_delay)
flights <- flights %>% mutate(hora_min_plan = paste(hour, minutos_plan))
flights <- flights %>% mutate(tiempo_plan = hm(hora_min_plan,roll=TRUE,quiet=TRUE))
flights <- flights %>% mutate(hora_plan = hour(tiempo_plan), min_plan = minute(tiempo_plan))
Notemos que con este procedimiento hemos obtenido horas planificadas negativas, ninguna menor a -24. Para corregir esto, debemos quitar un día a la fecha y esta sería la fecha planificada y aumentar 24 horas a la columna hora_plan.
flights %>% dplyr::filter(hora_plan<0) %>% select(date,hour,minute,hora_plan,min_plan)
## # A tibble: 145 x 5
## date hour minute hora_plan min_plan
## <dttm> <dbl> <dbl> <dbl> <dbl>
## 1 2011-01-27 12:00:00 0 11 -3 23
## 2 2011-01-20 12:00:00 6 35 -7 35
## 3 2011-01-01 12:00:00 0 1 -1 59
## 4 2011-01-04 12:00:00 0 5 -3 5
## 5 2011-01-09 12:00:00 0 22 -3 30
## 6 2011-01-28 12:00:00 2 26 -1 0
## 7 2011-01-27 12:00:00 0 17 -3 12
## 8 2011-01-21 12:00:00 0 4 -1 0
## 9 2011-02-25 12:00:00 0 6 -1 59
## 10 2011-02-09 12:00:00 0 7 -3 39
## # ... with 135 more rows
Ninguna es menor a -24 horas:
flights %>% dplyr::filter(hora_plan< -24) %>% select(date,hour,minute,hora_plan,min_plan) %>% count()
## # A tibble: 1 x 1
## n
## <int>
## 1 0
Por lo tanto creamos ahora una columna que se llame date_plan donde esté la fecha planificada para el vuelo:
flights <- flights %>% mutate(date_plan = date)
Entonces se cambia los valores de date_plan y hora_plan para aquellos vuelos cuya hora planificada fue negativa.
for(i in 1:length(flights$date)){
if(flights$hora_plan[i]<0 && !is.na(flights$hora_plan[i])){
flights$hora_plan[i] = flights$hora_plan[i]+24
flights$date_plan[i] = flights$date[i]-(3600*24)
}
}
Para comprobar se presenta:
flights %>% dplyr::filter(tiempo_plan<0) %>% select(date,hour,minute,date_plan,hora_plan,min_plan)
## # A tibble: 145 x 6
## date hour minute date_plan hora_plan min_plan
## <dttm> <dbl> <dbl> <dttm> <dbl> <dbl>
## 1 2011-01-27 12:00:00 0 11 2011-01-26 12:00:00 21 23
## 2 2011-01-20 12:00:00 6 35 2011-01-19 12:00:00 17 35
## 3 2011-01-01 12:00:00 0 1 2010-12-31 12:00:00 23 59
## 4 2011-01-04 12:00:00 0 5 2011-01-03 12:00:00 21 5
## 5 2011-01-09 12:00:00 0 22 2011-01-08 12:00:00 21 30
## 6 2011-01-28 12:00:00 2 26 2011-01-27 12:00:00 23 0
## 7 2011-01-27 12:00:00 0 17 2011-01-26 12:00:00 21 12
## 8 2011-01-21 12:00:00 0 4 2011-01-20 12:00:00 23 0
## 9 2011-02-25 12:00:00 0 6 2011-02-24 12:00:00 23 59
## 10 2011-02-09 12:00:00 0 7 2011-02-08 12:00:00 21 39
## # ... with 135 more rows
Ahora se pueden borrar las columnas extras que no se necesitan (minutos_plan, hora_min_plan y tiempo_plan).
flights <- select(flights, -minutos_plan, -hora_min_plan, -tiempo_plan)
Así ya tenemos información de la fecha, hora y minuto en el que fue planificado cada vuelo:
flights %>% select(date_plan,hora_plan,min_plan,date_plan)
## # A tibble: 227,496 x 3
## date_plan hora_plan min_plan
## <dttm> <dbl> <dbl>
## 1 2011-01-01 12:00:00 14 0
## 2 2011-01-02 12:00:00 14 0
## 3 2011-01-03 12:00:00 14 0
## 4 2011-01-04 12:00:00 14 0
## 5 2011-01-05 12:00:00 14 0
## 6 2011-01-06 12:00:00 14 0
## 7 2011-01-07 12:00:00 14 0
## 8 2011-01-08 12:00:00 14 0
## 9 2011-01-09 12:00:00 14 0
## 10 2011-01-10 12:00:00 14 0
## # ... with 227,486 more rows
Para el desarrollo de los ejercicios no se eliminaron los valores NA´s de la base de datos porque no sabemos si son errores o no. Para comprobar esto deberíamos preguntar a las personas que nos proporcionaron la base de datos que en este caso serían los dueños de la aerolínea. Para mi criterio, deberían haber valores NA únicamente en los vuelos que fueron cancelados, puesto que si el vuelo no fue cancelado, entonces se debería desplegar toda la información. Así podemos ver que en la base de datos existen vuelos que no han sido cancelados y tienen valores de NA.
flights %>% dplyr::filter_all(any_vars(is.na(.))) %>% dplyr::filter(cancelled==0) %>% select(date, hour, minute, dep_delay, arr_delay, cancelled)
## # A tibble: 649 x 6
## date hour minute dep_delay arr_delay cancelled
## <dttm> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 2011-01-11 12:00:00 5 53 -7 NA 0
## 2 2011-01-11 12:00:00 18 20 -5 NA 0
## 3 2011-01-29 12:00:00 14 34 4 NA 0
## 4 2011-01-22 12:00:00 12 27 10 NA 0
## 5 2011-01-18 12:00:00 9 27 2 NA 0
## 6 2011-01-12 12:00:00 15 58 8 NA 0
## 7 2011-01-10 12:00:00 21 32 9 NA 0
## 8 2011-01-10 12:00:00 13 26 6 NA 0
## 9 2011-01-09 12:00:00 16 58 3 NA 0
## 10 2011-01-06 12:00:00 9 9 4 NA 0
## # ... with 639 more rows
¿A qué hora del día debo volar (cualquier destino) para evitar, lo más posible, retrasos de salida?
Se realiza primero un conteo de cuantos vuelos tienen hora de retraso igual a 0. Notemos que se toma la hora planificada puesto que no se puede decidir sobre el retraso de salida de los aviones, sino sobre la hora planificada al comprar el pasaje de avión.
ej1_a <- flights %>% select(hora_plan) %>% dplyr::filter(flights$dep_delay==0) %>% group_by(hora_plan) %>% count()
ej1_a
## # A tibble: 19 x 2
## # Groups: hora_plan [19]
## hora_plan n
## <dbl> <int>
## 1 5 75
## 2 6 762
## 3 7 1617
## 4 8 927
## 5 9 1310
## 6 10 1612
## 7 11 1211
## 8 12 1018
## 9 13 1365
## 10 14 1335
## 11 15 1351
## 12 16 719
## 13 17 1090
## 14 18 834
## 15 19 1354
## 16 20 526
## 17 21 734
## 18 22 16
## 19 23 31
Contamos el número de vuelos planificados a cada hora:
ej1_b <- flights %>% select(hora_plan) %>% group_by(hora_plan) %>% count()
ej1_b <- na.omit(ej1_b)
ej1_b
## # A tibble: 19 x 2
## # Groups: hora_plan [19]
## hora_plan n
## <dbl> <int>
## 1 5 696
## 2 6 6710
## 3 7 17101
## 4 8 9897
## 5 9 15641
## 6 10 18104
## 7 11 13612
## 8 12 11543
## 9 13 16928
## 10 14 17685
## 11 15 16835
## 12 16 10920
## 13 17 15031
## 14 18 13551
## 15 19 19985
## 16 20 8619
## 17 21 10924
## 18 22 219
## 19 23 590
Se calcula las probabilidades:
ej1_p <- ej1_a %>% mutate(prob=n)
for(i in 1:length(ej1_a$hora_plan)){
ej1_p$prob[i] = round(ej1_a$n[i]/ej1_b$n[i],5)
}
ej1_p
## # A tibble: 19 x 3
## # Groups: hora_plan [19]
## hora_plan n prob
## <dbl> <int> <dbl>
## 1 5 75 0.108
## 2 6 762 0.114
## 3 7 1617 0.0946
## 4 8 927 0.0937
## 5 9 1310 0.0838
## 6 10 1612 0.0890
## 7 11 1211 0.0890
## 8 12 1018 0.0882
## 9 13 1365 0.0806
## 10 14 1335 0.0755
## 11 15 1351 0.0802
## 12 16 719 0.0658
## 13 17 1090 0.0725
## 14 18 834 0.0616
## 15 19 1354 0.0678
## 16 20 526 0.0610
## 17 21 734 0.0672
## 18 22 16 0.0731
## 19 23 31 0.0525
Se toma la hora del dia que tenga probabilidad maxima.
ej1_res <- ej1_p %>% select(hora_plan,prob) %>% dplyr::filter(prob==max(ej1_p$prob))
ej1_res
## # A tibble: 1 x 2
## # Groups: hora_plan [1]
## hora_plan prob
## <dbl> <dbl>
## 1 6 0.114
Encuentra los destinos que se vuelan por al menos dos compañías(carriers).
Contamos el número de vuelos por destino y compañía
ej2 <- flights %>% select(dest,carrier) %>% group_by(dest,carrier) %>% count()
ej2
## # A tibble: 241 x 3
## # Groups: dest, carrier [241]
## dest carrier n
## <chr> <chr> <int>
## 1 ABQ CO 101
## 2 ABQ OO 709
## 3 ABQ WN 1019
## 4 ABQ XE 983
## 5 AEX XE 724
## 6 AGS CO 1
## 7 AMA XE 1297
## 8 ANC CO 125
## 9 ASE OO 125
## 10 ATL CO 927
## # ... with 231 more rows
ej2 <- spread(ej2, key = carrier, value = n)
ej2
## # A tibble: 116 x 16
## # Groups: dest [116]
## dest AA AS B6 CO DL EV F9 FL MQ OO UA
## <chr> <int> <int> <int> <int> <int> <int> <int> <int> <int> <int> <int>
## 1 ABQ NA NA NA 101 NA NA NA NA NA 709 NA
## 2 AEX NA NA NA NA NA NA NA NA NA NA NA
## 3 AGS NA NA NA 1 NA NA NA NA NA NA NA
## 4 AMA NA NA NA NA NA NA NA NA NA NA NA
## 5 ANC NA NA NA 125 NA NA NA NA NA NA NA
## 6 ASE NA NA NA NA NA NA NA NA NA 125 NA
## 7 ATL NA NA NA 927 2396 611 NA 2029 NA 1054 NA
## 8 AUS NA NA NA 2645 NA NA NA NA NA 320 NA
## 9 AVL NA NA NA NA NA NA NA NA NA NA NA
## 10 BFL NA NA NA NA NA NA NA NA NA 504 NA
## # ... with 106 more rows, and 4 more variables: US <int>, WN <int>,
## # XE <int>, YV <int>
Ahora los detinos que se vuelan por al menos dos compañías son aquellas filas que tienen 2 o más valores distintos de NA, o equivalentemente, que no tengan 14 o 15 valores NA
ej2$na_conteo <- rowSums(is.na(ej2))
ej2
## # A tibble: 116 x 17
## # Groups: dest [116]
## dest AA AS B6 CO DL EV F9 FL MQ OO UA
## <chr> <int> <int> <int> <int> <int> <int> <int> <int> <int> <int> <int>
## 1 ABQ NA NA NA 101 NA NA NA NA NA 709 NA
## 2 AEX NA NA NA NA NA NA NA NA NA NA NA
## 3 AGS NA NA NA 1 NA NA NA NA NA NA NA
## 4 AMA NA NA NA NA NA NA NA NA NA NA NA
## 5 ANC NA NA NA 125 NA NA NA NA NA NA NA
## 6 ASE NA NA NA NA NA NA NA NA NA 125 NA
## 7 ATL NA NA NA 927 2396 611 NA 2029 NA 1054 NA
## 8 AUS NA NA NA 2645 NA NA NA NA NA 320 NA
## 9 AVL NA NA NA NA NA NA NA NA NA NA NA
## 10 BFL NA NA NA NA NA NA NA NA NA 504 NA
## # ... with 106 more rows, and 5 more variables: US <int>, WN <int>,
## # XE <int>, YV <int>, na_conteo <dbl>
Nos quedamos solo con los destinos con menos de 14 valores NA
ej2 <- ej2 %>% dplyr::filter(na_conteo <14)
ej2
## # A tibble: 60 x 17
## # Groups: dest [60]
## dest AA AS B6 CO DL EV F9 FL MQ OO UA
## <chr> <int> <int> <int> <int> <int> <int> <int> <int> <int> <int> <int>
## 1 ABQ NA NA NA 101 NA NA NA NA NA 709 NA
## 2 ATL NA NA NA 927 2396 611 NA 2029 NA 1054 NA
## 3 AUS NA NA NA 2645 NA NA NA NA NA 320 NA
## 4 BHM NA NA NA 5 NA NA NA NA NA NA NA
## 5 BNA NA NA NA NA NA NA NA NA NA NA NA
## 6 BWI NA NA NA 1324 NA NA NA NA NA NA NA
## 7 CHS NA NA NA NA NA NA NA NA NA NA NA
## 8 CLT NA NA NA 356 NA NA NA NA NA 546 NA
## 9 CMH NA NA NA 117 NA NA NA NA NA 267 NA
## 10 COS NA NA NA NA NA NA NA NA NA 1335 NA
## # ... with 50 more rows, and 5 more variables: US <int>, WN <int>,
## # XE <int>, YV <int>, na_conteo <dbl>
Finalmente, quitamos la columna que cuenta los NA y regresamos la tabla a como estaba antes:
ej2 <- select(ej2,-na_conteo)
aux <- colnames(ej2)
aux <- aux[-1]
aux
## [1] "AA" "AS" "B6" "CO" "DL" "EV" "F9" "FL" "MQ" "OO" "UA" "US" "WN" "XE"
## [15] "YV"
ej2 <- ej2 %>% gather(aux, key=carrier, value=n) %>% na.omit
ej2 <- ej2 %>% arrange(dest)
ej2 <- select(ej2, -n)
Así tenemos los destinos que se vuelan por al menos dos compañías.
ej2
## # A tibble: 185 x 2
## # Groups: dest [60]
## dest carrier
## <chr> <chr>
## 1 ABQ CO
## 2 ABQ OO
## 3 ABQ WN
## 4 ABQ XE
## 5 ATL CO
## 6 ATL DL
## 7 ATL EV
## 8 ATL FL
## 9 ATL OO
## 10 ATL XE
## # ... with 175 more rows
Con respecto a la pregunta 1, ¿Cuál es la probabilidad de que se retrase más de 2 minutos en el arribo de un vuelo?, sabiendo que salió puntual.
Calculamos el número de vuelos que salieron puntuales pero tienen retraso en el arribo por más de 2 minutos
ej3 <- flights %>% select(hora_plan) %>% dplyr::filter(flights$dep_delay==0 & flights$arr_delay>2) %>% group_by(hora_plan) %>% count()
ej3
## # A tibble: 19 x 2
## # Groups: hora_plan [19]
## hora_plan n
## <dbl> <int>
## 1 5 10
## 2 6 148
## 3 7 466
## 4 8 190
## 5 9 346
## 6 10 473
## 7 11 330
## 8 12 224
## 9 13 446
## 10 14 400
## 11 15 350
## 12 16 192
## 13 17 273
## 14 18 207
## 15 19 339
## 16 20 84
## 17 21 218
## 18 22 4
## 19 23 10
Aumentamos una columna para las probabilidades:
ej3 <- ej3 %>% mutate(prob = n)
El número de vuelo que tienen retraso igual a 0 es:
ej1_a
## # A tibble: 19 x 2
## # Groups: hora_plan [19]
## hora_plan n
## <dbl> <int>
## 1 5 75
## 2 6 762
## 3 7 1617
## 4 8 927
## 5 9 1310
## 6 10 1612
## 7 11 1211
## 8 12 1018
## 9 13 1365
## 10 14 1335
## 11 15 1351
## 12 16 719
## 13 17 1090
## 14 18 834
## 15 19 1354
## 16 20 526
## 17 21 734
## 18 22 16
## 19 23 31
Luego se calculan las probabilidades:
for(i in 1:length(ej3$hora_plan)){
ej3$prob[i] = round(ej3$n[i]/ej1_a$n[i],5)
}
ej3
## # A tibble: 19 x 3
## # Groups: hora_plan [19]
## hora_plan n prob
## <dbl> <int> <dbl>
## 1 5 10 0.133
## 2 6 148 0.194
## 3 7 466 0.288
## 4 8 190 0.205
## 5 9 346 0.264
## 6 10 473 0.293
## 7 11 330 0.272
## 8 12 224 0.220
## 9 13 446 0.327
## 10 14 400 0.300
## 11 15 350 0.259
## 12 16 192 0.267
## 13 17 273 0.250
## 14 18 207 0.248
## 15 19 339 0.250
## 16 20 84 0.160
## 17 21 218 0.297
## 18 22 4 0.25
## 19 23 10 0.323
La forma en la que se calculó las probabilidades se debe a que, por hora planificada:
\[ \text{P(arr_delay>2 min | dep_delay=0)} = \frac{\text{P(arr_delay>2 min ^ dep_delay=0)}}{\text{P(dep_delay=0)}} \]
Para cada destino calcula el promedio de minutos de retraso de salida y determina un intervalo de confianza al 95%. Para cada vuelo calcula su proporción del total de retrasos de su destino y realiza un intervalo de confianza.
Nota: Para la pregunta 4, considerar primero la comporbación de los supuestos de homogeneidad (normalidad) e independencia.
a) Promedio de minutos de retraso de salida por destino:
ej4_1 <- flights %>% select(dest,arr_delay) %>% group_by(dest) %>% summarise(prom = mean(arr_delay, na.rm=T))
ej4_1
## # A tibble: 116 x 2
## dest prom
## <chr> <dbl>
## 1 ABQ 7.23
## 2 AEX 5.84
## 3 AGS 4
## 4 AMA 6.84
## 5 ANC 26.1
## 6 ASE 6.79
## 7 ATL 8.23
## 8 AUS 7.45
## 9 AVL 9.97
## 10 BFL -13.2
## # ... with 106 more rows
Consideremos primero la comprobación de los supuestos de homogeneidad (normalidad) e independencia.
Para verificar la normalidad realizamos una prueba de Kolmogorov_Smirnov
ks.test(ej4_1$prom, "pnorm", mean=mean(ej4_1$prom), sd=sd(ej4_1$prom))
##
## One-sample Kolmogorov-Smirnov test
##
## data: ej4_1$prom
## D = 0.15313, p-value = 0.008678
## alternative hypothesis: two-sided
Como el p-valor es muy pequeño, podemos afirmar que los datos no provienen de una distribución normal.
Realicemos una prueba para la aleatoriedad de los datos. Se utiliza la función runs.test del paquete: snpar.
snpar::runs.test(ej4_1$prom)
##
## Approximate runs rest
##
## data: ej4_1$prom
## Runs = 60, p-value = 0.852
## alternative hypothesis: two.sided
Como el valor p es mayor que 0.05 se puede afirmar con un 95% de confianza que los datos son aleatorios.
Notemos que como el tamaño de la muestra es grande, entonces se puede usar la t de student para el intervalo de confianza.
Tenemos que:
n1 <- length(ej4_1$prom)
m1 <- mean(ej4_1$prom)
s1 <- sd(ej4_1$prom)
t1 <- qt(p=0.975,df=n1-1)
Por lo tanto, el intervalo de confianza es:
res <- c(m1-t1*s1/sqrt(n1),m1+t1*s1/sqrt(n1))
res
## [1] 6.031107 7.876739
\[ \mu \in [6.031107, 7.876739] \]
b) Para cada vuelo calcula su proporción del total de retrasos de su destino y realiza un intervalo de confianza.
Calculamos:
ej4_2 <- flights %>% select(flight, arr_delay) %>% group_by(flight) %>% summarise(suma= sum(arr_delay, na.rm=T))
ej4_2
## # A tibble: 3,740 x 2
## flight suma
## <dbl> <dbl>
## 1 1 4054
## 2 2 -392
## 3 3 586
## 4 4 -704
## 5 5 3317
## 6 6 1522
## 7 7 1123
## 8 8 5495
## 9 9 1269
## 10 10 -149
## # ... with 3,730 more rows
Entonces las proporciones buscadas son:
ej4_21 <- ej4_2 %>% mutate(proporcion=round(suma/sum(ej4_2$suma),4))
ej4_21
## # A tibble: 3,740 x 3
## flight suma proporcion
## <dbl> <dbl> <dbl>
## 1 1 4054 0.0026
## 2 2 -392 -0.0002
## 3 3 586 0.0004
## 4 4 -704 -0.0004
## 5 5 3317 0.0021
## 6 6 1522 0.001
## 7 7 1123 0.0007
## 8 8 5495 0.0035
## 9 9 1269 0.0008
## 10 10 -149 -0.0001
## # ... with 3,730 more rows
Verifiquemos si los datos siguen una distribución normal
ks.test(ej4_21$proporcion, "pnorm", mean=mean(ej4_21$proporcion), sd=sd(ej4_21$proporcion))
## Warning in ks.test(ej4_21$proporcion, "pnorm", mean =
## mean(ej4_21$proporcion), : ties should not be present for the Kolmogorov-
## Smirnov test
##
## One-sample Kolmogorov-Smirnov test
##
## data: ej4_21$proporcion
## D = 0.25287, p-value < 2.2e-16
## alternative hypothesis: two-sided
Como el p-valor es muy pequeño, podemos afirmar que los datos no provienen de una distribución normal.
Realicemos una prueba para la aleatoriedad de los datos. Se utiliza la función runs.test del paquete: snpar.
snpar::runs.test(ej4_21$proporcion)
##
## Approximate runs rest
##
## data: ej4_21$proporcion
## Runs = 1602, p-value = 8.224e-10
## alternative hypothesis: two.sided
Notemos que como el tamaño de la muestra es grande, entonces se puede usar la t de student para el intervalo de confianza de la media.
Tenemos que:
n2 <- length(ej4_21$proporcion)
m2 <- mean(ej4_21$proporcion)
s2 <- sd(ej4_21$proporcion)
t2 <- qt(p=0.975,df=n2-1)
Por lo tanto, el intervalo de confianza para la media de los datos es:
res2 <- c(m2-t2*s2/sqrt(n2),m2+t2*s2/sqrt(n2))
res2
## [1] 0.0002506975 0.0002847570