1 Introducción en construcción

Bajo la colaboración y supervisión de la profesora Natalia Henríquez, pretendo escribir una guía mucho más práctica que teórica, utilizando un lenguaje amigable e informal, en la cual aplicaré los conceptos estadísticos y lo que he ido aprendiendo sobre R para realizar análisis básico de datos, crear ejemplos, y resolver ejercicios. El siguiente trabajo no tiene por intención ser un apunte de estadística o un manual de R.

Añadidos de la nueva versión

  • Traspasé todo lo del documento Latex a R Markdown, que está basado en HTML creo. Como es un lenguaje creado para escribir texto de R, todo es mucho más sencillo y estético que en Latex. Lo recomiendo. Sigo aprendiendo a usarlo pero lo básico lo entendí en un fin de semana.

  • Incorporé paquetes. Antes solo estaba usando los que venían de base en R, pero descubrí el mundo de los paquetes y creo que sin duda hay que aprovecharlo. Principalmente añadí el uso del paquete dplyr y ggplot2, el primero para escribir código de forma más intuitiva (a mi juicio) y el segundo para hacer gráficos más bonitos. No tienen nada que envidiarle a los paquetes base, los cuales no dejé de lado.

  • No estoy usando pantallazos para las instalaciones, estoy usando GIFS. Creo que es mejor. No he podido crear el apartado de instalación de R, ya que me pidió que lo hiciera en windows pero yo tengo ubuntu. Me estoy consiguiendo un computador con windows para hacerlo :-) muy pronto. Lo tendré listo para la siguiente versión.

  • Intento seguir la misma estructura para cada sección: hago una introducción de ellas y añado los conceptos principales a trabajar y breves explicaciones para cada uno. Luego, el uso de ellos en R mediante las funciones base y también usando dplyr.

  • Creé la sección “Tablas de frecuencia”. Antes estaba unida a “Medidas descriptivas” y no profundizaba mucho en ellas. Aprendí a crear tablas de frecuencia mejores así que valía la pena ponerles su propia sección, con frecuencias acumuladas y todo.

  • Añadí los gráficos solicitados al apartado de “Medidas de correlación”, pero aún estoy aprendiendo a alinearlos bien. Se ven muy pequeños. Además, enchulé los histogramas de la sección “Medidas de dispersión” para que se entendiera mejor la idea.

  • Creé tablas resumen para cada base de datos, con ejemplos y todo. Las escondí con un botón de mostrar tabla/esconder tabla para que no ocupara tanto espacio. La tabla de las zarigueyas está lista pero estoy teniendo un pequeño problema con el botón.

Pendientes

  • Hacer el anexo.

  • Aparecen algunos errores al cargar ciertas librerias. Eso debo quitarlo. Listo para la siguiente reunión

  • Al parecer, la forma de abrir los enlaces es dando click derecho y luego abrir nueva pestaña. Parece que no funciona con click izquierdo directo.

2 Estadística descriptiva

La estadística descriptiva es una poderosa herramienta para comprender y resumir conjuntos de datos. Nos permite explorar la estructura, las tendencias y las características de los datos de manera sistemática y cuantitativa. En lugar de simplemente mirar números y cifras, la estadística descriptiva nos brinda un marco analítico para interpretar y extraer información significativa de los datos.

En este tutorial, exploraremos la estadística descriptiva utilizando RStudio. Para hacerlo, descargaremos bases de datos que contienen información sobre enfermedades cardíacas en humanos y zarigüeyas. A través de ejemplos prácticos, aprenderemos a aplicar técnicas estadísticas descriptivas utilizando el lenguaje de programación R y obtener conclusiones de estas.

Al utilizar estas bases de datos, por un lado, podremos analizar cómo se relacionan diferentes variables, como la edad, el sexo, los síntomas y los resultados de las pruebas médicas respecto a enfermedades cardiacas. Para el caso de las zarigüeyas, además de su edad y sexo, analizaremos las medidas de partes de su cuerpo, como el tamaño de sus patas, orejas, pecho y más. A su vez, exploraremos cómo estas técnicas descriptivas pueden ayudarnos a identificar patrones, tendencias y relaciones en los datos.

2.1 Importación de bases de datos

El siguiente enlace nos llevará a la plataforma Kaggle, en donde está alojada base de datos sobre enfermedades cardiacas. Una vez abierto, solo debemos pinchar en “Download” y guardar el documento en donde se prefiera. Posteriormente, ejecutaremos RStudio y procederemos a importar la base de datos.

La extensión de la base de datos descargada es .csv, lo cual significa que está escrita en un documento de texto, y cada está dato separado por comas. RStudio nos hace bastante simple el trabajo, solo debemos seleccionar las siguientes opciones:

\[ \textbf{File} \rightarrow \textbf{Import Dataset} \rightarrow \textbf{From Text (base)} \rightarrow \textbf{Seleccionar base de datos} \rightarrow \textbf{Import} \]

Importación de la base de datos desde \(\textsf{RStudio}\)


Ya tenemos lista para usar nuestra base de datos sobre enfermedades cardiacas. Para la base de datos de zarigüeyas, debemos abrir el siguiente enlace y repetir los pasos anteriores.

La siguiente tabla es un resumen de nuestra base de datos sobre enfermedades cardiacas.


Mientras que la siguiente tabla es un resumen de la base de datos sobre zarigüeyas

2.2 Medidas descriptivas

Las medidas descriptivas nos proporcionan información sobre diferentes aspectos de los datos, como su tendencia central, dispersión, posición y correlación. Entre las medidas descriptivas más comunes se incluyen la media, la mediana, la moda, el rango, la varianza, desviación estándar, el rango intercuartílico y la correlación de Pearson. Si no te suena alguna de las medidas mencionadas, no te preocupes porque en las siguientes subsecciones daremos más detalles de cada una.

Gracias a R y sus paquetes de base, podemos calcular fácilmente medidas descriptivas utilizando funciones integradas. Estas herramientas nos permitirán analizar y visualizar rápidamente la distribución y las características de los datos.

Antes de comenzar a calcular estadísticas, calentemos los motores en la consola de RStudio. Utilizando la función head(), e introduciéndole como argumento el nombre de nuestra base de datos de enfermedades cardiacas, heart, podremos ver las primeras filas de datos.

head(heart)


También podemos chequear el número de observaciones que presenta nuestra base de datos mediante la función length() poniéndole como argumento cualquier variable.

length(heart$Sexo)
## [1] 918

2.2.1 Medidas de tendencia central

Podemos entender las medidas de tendencia central como estadísticas que representan la ubicación central o típica de un conjunto de datos. Las tres medidas de tendencia central más comunes son la media, la mediana y la moda.

  • Media: La media es el promedio aritmético de todos los valores en un conjunto de datos. Se calcula sumando todos los valores y dividiendo por el número total de valores.

  • Mediana: La mediana es el valor que divide al conjunto de datos en dos partes iguales, es decir, el valor medio cuando los datos están ordenados de manera ascendente o descendente.

  • Moda: La moda es el valor que ocurre con mayor frecuencia en un conjunto de datos.

Estas medidas son útiles para resumir y comprender la distribución de los datos. En R, puedes calcular estas medidas fácilmente utilizando funciones como mean() y median(), para la media y la mediana respectivamente.

Podemos, por ejemplo, obtener la edad media de nuestra muestra:

mean(heart$Edad) # Escogemos la variable Edad de la base de datos heart con "$"
## [1] 53.51089

Usando el paquete dplyr podemos obtener el mismo resultado

library(dplyr)
## 
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
heart %>% # Escogemos la base de datos y luego usamos el pipe %>% 
  pull(Edad) %>% # Obtenemos la variable Edad como vector
  mean() # Calculamos el promedio de la edad
## [1] 53.51089

O se puede ser más específicos en nuestro cálculo, y obtener la edad media de las personas que tienen alguna enfermedad cardiaca y las que no.

Primero calculemos la edad media de los que tienen enfermedad cardiaca usando las funciones base de R. Usando las herramientas lógicas, definiremos las variables de las personas que tienen una enfermedad cardiaca

tiene_enfermedad_cardiaca <- heart$EnfCard == 1 # Guardamos como variable todos los que tengan como observación de enfermedad cardiaca = 1
mean(heart[tiene_enfermedad_cardiaca, 1])
## [1] 55.89961

Por otro lado, usando el paquete dplyr podemos calcular el promedio de la edad los que no tienen enfermedad cardiaca.

heart %>% 
  filter(EnfCard == 0) %>% # Filtramos las filas que tengan la variable EnfCard = 0
  pull(Edad) %>% 
  mean()
## [1] 50.55122

Podemos decir entonces que en promedio, los pacientes de nuestra muestra que presentan alguna enfermedad cardiaca son cinco años mayor a las que no.

Otro ejercicio sería calcular la mediana de alguna variable que nos interese, por ejemplo, del colesterol.

median(heart$Col)
## [1] 223

O usando dplyr

heart %>% 
  pull(Col) %>% 
  median()
## [1] 223

Nos dio como resultado una mediana de 223 mm/dl para la variable del colesterol. Ahora, notemos que podemos usar la función que sirve crear histogramas,hist(), para crear una tabla de frecuencia agrupada en intervalos. Para ello, dentro de los argumentos opcionales que nos brinda la función, debemos desactivar plot con plot = FALSE. Una vez creada nuestra tabla de frecuencia, obtendremos intervalos de la forma [a,b) para nuestros datos. Para efectos prácticos, le pediremos a R que solo nos lea las primeras dos líneas del output de la función hist que usaremos, finalizando con [1:2].

hist(heart$Col, plot = FALSE)[1:2] # Graficamos una tabla de frecuencia, y solo pedimos las primeras dos líneas del output del comando.
## $breaks
##  [1]   0  50 100 150 200 250 300 350 400 450 500 550 600 650
## 
## $counts
##  [1] 172   3  17 130 291 202  76  14   5   4   2   1   1

Tenemos un llamativo intervalo [0,50) con 172 datos. Significa que hay 172 pacientes con niveles de colesterol sérico entre 0 y 50 mm/dl, números demasiado bajos para niveles de colesterol sérico en seres humanos. ¿Qué está ocurriendo? Hagamos una filtración de nuestra variable colesterol, pidiéndole a R que nos muestre específicamente los valores de cada paciente que tenga los niveles de colesterol sérico por debajo de 50 mm/dl.

heart %>% 
  filter(Col < 50) %>%  
# Filtramos los datos para tener una columna de valores de colesterol bajo a 50. 
  
# Solicitamos a R los valores específicos de cada observación que haya -
# cumplido el filtro anterior.  
  pull(Col) 
##   [1] 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
##  [38] 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
##  [75] 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
## [112] 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
## [149] 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

Por las observaciones anteriores, podemos entender que nuestra base de datos nos está diciendo que a 172 pacientes no se les midió el colesterol total en su sangre al momento de examinarlos (o sus niveles de colesterol en la sangre realmente eran 0 mm/dl, pero omitiremos esta posibilidad ya que es imposible que ocurra). Por tanto, nuestros cálculos anteriores para obtener la mediana están incluyendo una cantidad considerable de valores iguales a 0, los cuales más nos vale ignorar o podríamos realizar un análisis sesgado.

Teniendo en cuenta lo anterior, presentamos los valores de la mediana solo considerando los valores de colesterol mayores que 0.

# Calculamos la mediana de la variable colesterol, aunque necesitamos-
# introducirle como argumento a la función median() un vector. -
# Para ello, filtramos de la variable colesterol el vector que contiene -
# los valores de colesterol mayores que 0.
median(heart$Col[heart$Col > 0]) 
## [1] 237

O usando dplyr

heart %>% 
  filter(Col > 0) %>% # Primero filtramos los valores de colesterol mayores a 0.
  pull(Col) %>% # De aquel filtro, solicitamos a R el vector con las observaciones
  median() # Introducimos a la función median() el vector anterior.
## [1] 237

La mediana varió 14 mg/dL respecto a la anterior con la muestra sesgada. ¿Cuánto variará el promedio, en un análisis no sesgado?

Calculando el promedio del colesterol sérico incluyendo las observaciones iguales a 0, es decir, en un cálculo sesgado, obtenemos

mean(heart$Col)
## [1] 198.7996

Hacemos lo mismo usando dplyr para los datos mayores que 0

heart %>% 
  filter(Col > 0) %>% 
  pull(Col) %>% 
  mean()
## [1] 244.6354

Varió 46 mg/dL, lo que es un gran diferencia. Valió la pena ser cuidadosos.

Para calcular la moda no tenemos una función que venga de base en \(\textsf{R}\), pero en internet podemos encontrar un montón de soluciones a este problema. Para no descargar un paquete, usaremos una función creada por un usuario del foro stackoverflow. En este enlace encontraremos la función creada y más opciones programadas por otros usuarios.

Mode <- function(x) {
  ux <- unique(x)
  ux[which.max(tabulate(match(x, ux)))]
}

Usémosla para comprobar cuál es el tipo de dolor de pecho más frecuente

Mode(heart$TDP)
## [1] ASY
## Levels: ASY ATA NAP TA

La observación que más se repite para la variable tipo de dolor de pecho es que la mayoría de los pacientes no presentan dolor de pecho. Podremos ver a detalle los valores de las otras observaciones en la sección Tablas de frecuencia.

2.2.2 Medidas de posición

Los cuartiles, deciles y percentiles son medidas estadísticas utilizadas para dividir un conjunto de datos ordenados en partes iguales o proporcionales. Estas medidas son importantes en la estadística descriptiva porque proporcionan información sobre la distribución de todos los datos.

  • Cuartiles: Los cuartiles dividen un conjunto de datos ordenados en cuatro partes iguales, es decir, en tres puntos que dividen los datos en cuatro grupos de igual tamaño. Los cuartiles más comúnmente utilizados son el primer cuartil (Q1), que representa el 25% de los datos, el segundo cuartil (Q2) que es igual a la mediana y divide los datos en dos partes iguales, y el tercer cuartil (Q3) que representa el 75% de los datos.

  • Deciles: Los deciles dividen un conjunto de datos en diez partes iguales, es decir, en nueve puntos que dividen los datos en diez grupos de igual tamaño. El primer decil (D1) representa el 10% de los datos, el segundo decil (D2) representa el 20% de los datos, y así sucesivamente.

  • Percentiles: Los percentiles dividen un conjunto de datos en cien partes iguales, es decir, en 99 puntos que dividen los datos en cien grupos de igual tamaño. El percentil P25 representa el 25% de los datos, el percentil P50 es igual a la mediana y representa el 50% de los datos, y el percentil P75 representa el 75% de los datos.

En R, podemos calcular cuartiles, deciles y percentiles utilizando las funciones base quantile() y summary()

Creemos un vector de datos de edad y con él calculemos cuartiles, deciles y percentiles.

datos_edad <- c(10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60)

# Calcular cuartiles
cuartiles <- quantile(datos_edad, probs = c(0.25, 0.5, 0.75)) 
# Con la opción props le pedimos que nos calcule el 25%, 50% y 75%

print(cuartiles)
##  25%  50%  75% 
## 22.5 35.0 47.5
# Calcular deciles
deciles <- quantile(datos_edad, probs = seq(0.1, 0.9, by = 0.1)) 
# Esta vez le pedimos que nos calcule desde el 10% al 90% de los datos, -
# cada uno separado por un 10%

print(deciles)
## 10% 20% 30% 40% 50% 60% 70% 80% 90% 
##  15  20  25  30  35  40  45  50  55
# Calcular percentiles
percentiles <- quantile(datos_edad, probs = seq(0.01, 0.99, by = 0.01)) 
print(percentiles)
##   1%   2%   3%   4%   5%   6%   7%   8%   9%  10%  11%  12%  13%  14%  15%  16% 
## 10.5 11.0 11.5 12.0 12.5 13.0 13.5 14.0 14.5 15.0 15.5 16.0 16.5 17.0 17.5 18.0 
##  17%  18%  19%  20%  21%  22%  23%  24%  25%  26%  27%  28%  29%  30%  31%  32% 
## 18.5 19.0 19.5 20.0 20.5 21.0 21.5 22.0 22.5 23.0 23.5 24.0 24.5 25.0 25.5 26.0 
##  33%  34%  35%  36%  37%  38%  39%  40%  41%  42%  43%  44%  45%  46%  47%  48% 
## 26.5 27.0 27.5 28.0 28.5 29.0 29.5 30.0 30.5 31.0 31.5 32.0 32.5 33.0 33.5 34.0 
##  49%  50%  51%  52%  53%  54%  55%  56%  57%  58%  59%  60%  61%  62%  63%  64% 
## 34.5 35.0 35.5 36.0 36.5 37.0 37.5 38.0 38.5 39.0 39.5 40.0 40.5 41.0 41.5 42.0 
##  65%  66%  67%  68%  69%  70%  71%  72%  73%  74%  75%  76%  77%  78%  79%  80% 
## 42.5 43.0 43.5 44.0 44.5 45.0 45.5 46.0 46.5 47.0 47.5 48.0 48.5 49.0 49.5 50.0 
##  81%  82%  83%  84%  85%  86%  87%  88%  89%  90%  91%  92%  93%  94%  95%  96% 
## 50.5 51.0 51.5 52.0 52.5 53.0 53.5 54.0 54.5 55.0 55.5 56.0 56.5 57.0 57.5 58.0 
##  97%  98%  99% 
## 58.5 59.0 59.5

También podemos obtener un resumen rápido usando summary()

summary(datos_edad)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##    10.0    22.5    35.0    35.0    47.5    60.0

Podemos sacar algunas conclusiones con el resumen:

  • La edad mínima observada es de 10 años, y la máxima de 60 años.

  • La edad promedio entre los datos es de 35 años, que coincide con la mediana.

  • El 25% de las personas tiene 22.5 años o menos, la mitad tiene 35 años o menos, y el 75% tiene 47.5 años o menos.

2.2.3 Medidas de dispersión

En el análisis estadístico, las medidas de dispersión o variabilidad son fundamentales para comprender qué tanto varían o cuanto se diferencian respecto de su media. Mientras que las medidas de tendencia central, como la media, la mediana y la moda, proporcionan información sobre el valor típico o central de un conjunto de datos, las medidas de dispersión revelan la amplitud y la variabilidad de esos datos.

  • Rango: El rango es la diferencia entre el valor máximo y el valor mínimo en un conjunto de datos. Es la medida más simple de dispersión y proporciona una idea de la amplitud total de los datos, representando la máxima variabilidad presente en los datos.

  • Rango intercuartil (IQR): El rango intercuartil es la diferencia entre el tercer cuartil (Q3) y el primer cuartil (Q1). Representa la dispersión de los datos dentro del 50% central de la distribución y es una medida robusta que no se ve afectada por valores atípicos.

  • Varianza: La varianza es una medida de dispersión que describe cuánto varían los datos respecto a la media. Se calcula como la media de los cuadrados de las diferencias entre cada valor y la media del conjunto de datos.

  • Desviación estándar: La desviación estándar es la raíz cuadrada de la varianza y es una medida de dispersión más interpretable que la varianza. Indica cuánto se alejan, en promedio, los datos de la media y se expresa en las mismas unidades que los datos originales.

Para comenzar a aplicar los conceptos en R, comencemos haciendo un cálculo sencillo. Veamos el rango de la edad de la muestra de pacientes.

rango_edad = max(heart$Edad) - min(heart$Edad) 
print(rango_edad)
## [1] 49

El rango de la edad por tanto es 49 años. Parece un número grande, y se podría pensar que la edad varía bastante en los pacientes de la muestra. Sin embargo, y valiéndonos nuevamente del comando hist(heart$Edad, plot=FALSE)[1:2] usado y explicado anteriormente, podremos crear una tabla de frecuencias agrupadas en intervalos

hist(heart$Edad, plot=FALSE)[1:2]
## $breaks
##  [1] 25 30 35 40 45 50 55 60 65 70 75 80
## 
## $counts
##  [1]   5  27  61 103 120 196 185 139  58  20   4

Así, nos damos cuenta que para el grueso de las observaciones la edad varía poco, pues la gran mayoría de las edades se concentran entre los 45 y 65 años, un rango de 20 años. El rango por tanto sí cumplió con su función de representar la máxima variabilidad de los datos, pero tenemos que tener cuidado con su interpretación.

Por otro lado, el rango intercuartil por lo general sí nos entrega una dispersión de datos más centralizada, a diferencia del rango. Podemos llamarla en R con la función IQR(), y nos calculará directamente qué tanto varían el 50% central de los datos.

IQR(heart$Edad)
## [1] 13

Según el rango intercuartil entonces, la dispersión de las edades dentro del 50% central de la distribución de datos es de 13 años.

Otra medida de variabilidad, usada por sus propiedades matemáticas y utilidad en comparación a las anteriores es la varianza, o mejor conocida por R por la función var(), la cual nos permite chequear rápidamente propiedades básicas de esta medida de dispersión. Observemos el siguiente comando, que involucra la variable de la presión arterial en reposo y la constante numérica 2.

var(2*heart$RepPA) == (2^2)*var(heart$RepPA)
## [1] TRUE

El output de la función, TRUE, nos confirma que si multiplicamos la constante numérica 2 por cada uno de los datos de la variable presión arterial en reposo, y calculamos su varianza, es lo mismo que multiplicar el cuadrado de la constante numérica 2 por la varianza de cada uno de los datos. Hay muchas otras propiedades que se pueden revisar fácilmente usando .

Un problema que le podríamos encontrar a la varianza es la poca interpretación que podemos obtener de los calculos realizados con ella. Por ejemplo, Dr. House difícilmente entenderá si le decimos que la varianza de la presión arterial en reposo de sus pacientes es de 342 \((mmHg)^2\). Un forma de evitar estas confusiones es usar la desviación estándar, que saca raíz cuadrada a la varianza, y por tanto, las unidades de nuestros resultados serán iguales a la unidades con la que se realizó la medida inicialmente. Basta con llamar desde R la función sd()

Como la desviación estándar trabaja de modo directo con la media de los datos, a modo de ejemplo, y para entender mejor su funcionamiento, primero tendremos que calcular la media de alguna variable a interés. Elegiremos la variable ritmo cardíaco máximo, aunque filtraremos los datos para los pacientes que sí presentan angina al realizar ejercicio usando funciones base de R

si_anginaejercicio_y_maxrc  <- subset(heart, subset = EjeAng == "S", select = MaxRC)[[1]] 
# Filtramos los pacientes que presentan angina con la función subset() y como argumentos -
# subset para filtramiento con herramientas lógicas, y select para escoger columnas, y -
# dentro de esta filtración solicitamos a R el vector numérico MaxRC con [1]

promedio_si_ang_ejercicio <- mean(si_anginaejercicio_y_maxrc) 
# Calculamos el promedio de la variable creada con la función mean(), -
# que necesita un vector numérico como argumento.

promedio_si_ang_ejercicio # Imprimimos el resultado
## [1] 125.3639

Y ahora calculemos el mismo promedio pero para los que no presentan angina, usando el paquete dplyr

heart %>% 
  filter(EjeAng == "N") %>% # Filtramos las filas que no presentan angina al hacer ejercicio
  pull(MaxRC) %>% # Le pedimos al dataframe que nos suelte la variable MaxRC como vector
  mean() 
## [1] 144.5722

Hay una diferencia considerable entre cada promedio. ¿Y qué nos dice la desviación estándar para cada caso? Veamos para el caso que sí presenta angina usando las funciones base

desv_estandar_si_angina <- sd(subset(heart, subset= EjeAng == "S", select = MaxRC)[[1]])
# Esta vez realizamos el cálculo de la desviación estándar directamente.
desv_estandar_si_angina # Imprimimos el resultado
## [1] 20.45099

Y ahora para el caso que no presenta angina usando dplyr, usando la misma lógica anterior.

heart %>% 
  filter(EjeAng == "N") %>% 
  pull(MaxRC) %>% 
  sd()
## [1] 25.6102

Es posible concluir entonces que las personas que no presentan angina al ejercitarse tienen 5 latidos más por minuto en promedio que las que si presentan angina.

Con los cálculos anteriores de promedios y desviaciones estándar, procedemos a mostrar un par de histogramas para visualizar mejor los datos obtenidos.

La barra donde se encuentra el promedio de cada uno de los casos la representamos con el color rosa, mientras que los datos que están siendo abarcados por una desviación estandar (es decir, si \(\overline{x}\) representa la media de los datos y \(\sigma\) el valor de la desviación estándar, entonces dentro de las barras de colores están los datos entre los valores \(\overline{x} - \sigma\) y \(\overline{x} + \sigma\)) están representados con las barras moradas.

Una observación a hacer, y a modo de adelanto, podemos afirmar que entre las barras coloreadas de cada caso, se debiese concentrar aproximadamente el 68% de los datos. Podremos conocer más detalles estudiando la distribución normal en las siguientes secciones.

2.2.4 Medidas de correlación

Las medidas de correlación son herramientas estadísticas utilizadas para cuantificar la relación entre dos variables. La correlación describe la dirección y la fuerza de la asociación entre las variables, lo que ayuda a comprender cómo cambian entre ellas.

Existen varias medidas de correlación, siendo la más común (y con la única que trabajaremos) la correlación de Pearson. Sin embargo, también se utilizan otras como la correlación de Spearman y la correlación de Kendall, especialmente cuando los datos no siguen una distribución normal o están en una escala ordinal.

  • Correlación de Pearson: La correlación de Pearson mide la relación lineal entre dos variables continuas. Toma valores entre -1 y 1, donde -1 indica una correlación negativa perfecta, 0 indica ninguna correlación y 1 indica una correlación positiva perfecta.

Pendiente: mejorar visual de los gráficos

## [1] 1
## `geom_smooth()` using formula = 'y ~ x'
## `geom_smooth()` using formula = 'y ~ x'

## `geom_smooth()` using formula = 'y ~ x'

En R, podemos calcular la correlación de Pearson utilizando la función cor(). Con la base de datos sobre zarigüeyas probaremos qué tanta correlación hay entre sus características físicas.

En una conversación interna con las zarigüeyas, nos dieron una pista de cuáles variables podrían llamarnos la atención para introducir como argumento a la función cor().

# Usaremos el argumento use = "complete.obs" para que cor() haga los cálculos
# a pesar de existir observaciones NA en ambas variables.
cor(possum$earconch, possum$footlgth, use = "complete.obs")
## [1] 0.7830499

El output anterior nos dice que hay una correlación positiva entre el tamaño de la oreja de la zarigüeya y el tamaño de su pata. Podemos interpretar el resultado como que en promedio mientras más grande la oreja de la zarigüeya, también su pata. En la siguiente sección veremos un gráfico de esta relación. Siguiendo esta idea, ¿qué tan fuerte podría ser la correlación entre la edad y el tamaño de las orejas?

cor(possum$earconch, possum$age, use = "complete.obs")
## [1] 0.05340463

Una correlación casi nula. Quizás sea buena idea considerar el crecimiento de la oreja hasta cierta edad, pues según Google, las zarigüeyas crecen físicamente hasta aproximadamente los 2 años. Intentemos obtener esta correlación usando dplyr

possum %>% 
  select(earconch, age) %>% 
  filter(age <= 2) %>% 
  cor() %>% 
  .[1, 2]
## [1] 0.2331032

La correlación aumentó, pero poco. Puede ser que no sean suficientes datos, o en verdad no hay una relación estrecha entre ambas variables.

2.3 Tablas de frecuencia

Las tablas de frecuencia son herramientas fundamentales en estadística que nos permiten presentar la información resumida y ordenadamente por variable. Estas tablas muestran la frecuencia de ocurrencia de cada categoría o valor en una variable, así como las frecuencias acumuladas, porcentajes y otras medidas descriptivas importantes. Son especialmente útiles para analizar y comprender la distribución de datos categóricos y para realizar comparaciones entre diferentes grupos.

En R, podemos generar fácilmente tablas de frecuencia utilizando la función base table(). Esta función cuenta la frecuencia de ocurrencia de cada valor único en una variable y crea una tabla de frecuencia. Además, podemos calcular frecuencias acumuladas, porcentajes y otras medidas descriptivas utilizando funciones como cumsum(), prop.table() y otras funciones de manipulación de datos en R, que vienen incluidas en el paquete dplyr.

Creemos nuestra primera tabla de frecuencia usando table() y la base de datos possum.

table(possum$sex, useNA = "always") #S eleccionamos la variable sexo y queremos que contabilice los "NA"
## 
##    f    m <NA> 
##   43   61    0

Podemos usar más de una variable como muestra la siguiente tabla

edad_y_sexo <- table(possum$age, possum$sex)
edad_y_sexo
##    
##      f  m
##   1  3  7
##   2  7  9
##   3 11 16
##   4  6  8
##   5  6  7
##   6  7  5
##   7  1  6
##   8  0  1
##   9  2  0

O pedirle a nuestra tabla que nos muestre los datos en términos porcentuales usando la función prop.table(), y luego (usando un pipe), redondeamos los decimales a 4 mediante la función round()

prop.table(edad_y_sexo) %>% round(2) # El argumento de prop.table siempre es una tabla.
##    
##        f    m
##   1 0.03 0.07
##   2 0.07 0.09
##   3 0.11 0.16
##   4 0.06 0.08
##   5 0.06 0.07
##   6 0.07 0.05
##   7 0.01 0.06
##   8 0.00 0.01
##   9 0.02 0.00

Como en la base de datos hay aproximadamente observaciones de 100 zarigüeyas, no era tan difícil predecir los porcentajes anteriores. En su mayoría, tenemos zarigüeyas de 3 años, principalmente machos.

Necesitaremos el paquete scales para lo siguiente.

library(scales)

Crear tablas más avanzadas usando dplyr puede parecer más laborioso, pero es solamente listar los pasos mediante pipes. Creemos una tabla (en estricto rigor, un dataframe) de frecuencia para los pacientes de sexo masculino que presentan colesterol alto. La siguiente puede parecer intimidante por su extensión, pero no es más que una serie de funciones que ya hemos usado antes, y alguna extra.

heart %>%  
   filter(Sexo == "M", Col >= 200) %>% # Filtramos las filas mediante argumentos lógicos
   count(TDP) %>% # Contamos los datos de la variable TDP y nos crea una nueva columna "n"
   arrange(n) %>% # Ordenamos los valores del conteo anterior
   mutate( # Creamos nuevas columnas
     frec_absoluta_p = scales::percent(n/sum(n)), # Calculamos el porcentaje de los datos contados por count()
     frec_acumulada_p = scales::percent(cumsum(n/sum(n))) # Usamos cumsum() para la frecuencia acumulada
   ) %>% 
   select( # Cambiamos el nombre a las variables para mayor estética
    "Tipo dolor pecho" = TDP,
    "Frecuencia absoluta" = n,
    "Frecuencia absoluta porcentual"  = frec_absoluta_p,
    "Frecuencia acumulada porcentual" = frec_acumulada_p,
    ) 

Básicamente, filtramos a los pacientes de sexo masculino y que tenían un colesterol alto, y de ellos, contabilizamos qué tipo de dolor de pecho presenta cada uno. En base a ese conteo, calculamos las frecuencias relativas y acumuladas.

Una conclusión interesante de la tabla anterior es que entre los pacientes de sexo masculino que poseen el colesterol alto, un porcentaje no menor de ellos (40% aproximadamente), presenta algún tipo de dolor en el pecho atípico, o no presenta dolor en el pecho pero sí en otra zona del cuerpo.

2.4 Gráficos

Los gráficos nos permiten representar de forma efectiva la información de manera visual, facilitando la comprensión y la identificación de patrones, tendencias y relaciones en los datos. Hay una gran variedad de gráficos que podemos crear, presentamos algunos de ellos a continuación.

  • Gráficos de Barra : Representan datos cualitativos o comparaciones de cantidades mediante barras verticales u horizontales.

  • Histograma: Muestra la distribución de frecuencia de datos numéricos mediante barras contiguas.

  • Boxplot (Diagrama de caja y bigotes): Representa la distribución de un conjunto de datos numéricos mediante cuartiles, mediana y valores atípicos.

  • Gráfico Circular: Muestra la proporción de diferentes categorías como segmentos de un círculo.

  • Ojiva: Muestra la acumulación o frecuencia acumulativa de datos ordenados.

  • Gráfico de Dispersión: Representa la relación entre dos variables numéricas mediante puntos en un plano cartesiano.

En R, existen múltiples paquetes y funciones para crear gráficos que se adaptan a diferentes tipos de datos y objetivos de visualización. Para esta sección, usaremos exclusivamente el paquete ggplot2, el cual ofrece una sintaxis amigable para crear gráficos estéticamente agradables, personalizables y la capacidad de trabajar con datos de forma más intuitiva que las funciones base de R.

La razón de por qué el paquete ggplot2 se considera más intuitivo a comparación de las funciones base de R, es porque construimos los gráficos sobreponiendo en orden diferentes “capas” creadas por funciones del paquete, y especificando cómo se deben mapear los datos a elementos visuales.

Mostramos un resumen de cómo graficar con ggplot2:

  1. Inicialización: Para comenzar a usar ggplot2, primero debemos cargar el paquete con library(ggplot2).

  2. Sintaxis básica: La función ggplot() se usa para iniciar la construcción de un gráfico. La sintaxis básica es ggplot(datos = <datos>), donde <datos> es el conjunto de datos que deseamos visualizar.

  3. Conector de capas: Si consideramos a la misma función ggplot() como una capa, para continuar con la siguiente capa debemos conectar con un + al final de nuestra última función usada.

  4. Capas geométricas: Luego del conector, debemos agregar capas geométricas para representar la forma de nuestros datos. Tenemos varias capas a elegir:

  • geom_bar() para un gráfico de barras.
  • geom_histogram() para un gráfico de histograma.
  • geom_boxplot() para un gráfico boxplot.
  • geom_bar() con coord_polar() para un gráfico circular.
  • geom_line() para un gráfico ojiva.
  • geom_point() para un gráfico de dispersion.
  1. Estética y atributos: Podemos personalizar la apariencia del gráfico escogido especificando atributos como color, tamaño, forma, etc., dentro de las capas geométricas.

Dentro de esta capa, se suele iniciar con la función aes(), que solo en caso de ser necesario, contiene las variables que se utilizarán para definir la estructura básica del gráfico escogido. Además, se utiliza para mapear cada variable seleccionada del conjunto de datos a propiedades visuales de los elementos gráficos, como color, tamaño, forma, posición, etc. Si las personalizaciones estéticas no están dentro de esta función, significa que están siendo aplicadas a todas las variables.

Hay muchas opciones para configurar para cada capa, las cuales pueden ser encontradas en manuales específicos de ggplot2. Presentamos un breve resumen con algunas de ellas.

  • Gráfico de barras:
    • Opciones de personalización:
      • fill: Define la variable asociada al color de las barras.
      • color: Establece el color del contorno de las barras.
      • width: Controla el ancho de las barras.
    • Ejemplo de personalización:
      ggplot(data = datos) +
      geom_bar(
      aes(x = variable, y = conteo),
      fill = "categoría escogida",
      color = "black",
      width = 0.7)
  • Gráfico de histograma:
    • Opciones de personalización:
      • fill:
      • color: Color del contorno de las barras.
      • bins: Número de intervalos/bins en el histograma.
    • Ejemplo de personalización:
      ggplot(data = datos) +
      geom_histogram(
      fill = ,
      color = "black",
      bins = 30)
  • Gráfico boxplot:
    • Opciones de personalización:
      • fill: Color de las cajas y los bigotes.
      • color: Color del contorno de las cajas y los bigotes.
      • notch: Si se muestra un indicador de la mediana.
    • Ejemplo de personalización:
      ggplot(data = datos) +
      geom_boxplot(
      fill = "lightpink",
      color = "darkred",
      notch = TRUE)
  • Gráfico circular:
    • Opciones de personalización:
      • fill: Color de las secciones del gráfico circular.
      • color: Color del contorno de las secciones.
      • width: Ancho de las secciones.
    • Ejemplo de personalización:
      ggplot(data = datos) +
      geom_bar(aes(x = variable, y = valores),
      fill = "lightblue",
      color = "black", width = 0.8) +
      coord_polar(theta = "y")
  • Gráfico de ojiva:
    • Opciones de personalización:
      • color: Color de la línea.
      • size: Grosor de la línea.
    • Ejemplo de personalización: ggplot(data = datos) + geom_line(aes(x = variable, y = frecuencia_acumulada), color = "purple", size = 1.5)
  • Ejes y etiquetas: Podemos agregar ejes X e Y con xlab("Etiqueta eje X") y ylab("Etiqueta eje Y"), respectivamente. Además, podemos cambiar el título del gráfico con ggtitle("Título del gráfico").

  • Facetas: Para dividir el gráfico en subgráficos según una variable, podemos usar facetas con facet_wrap(~variable) o facet_grid(variable1 ~ variable2).

  • Escalas y temas: Podemos ajustar las escalas de los ejes con scale_x_continuous() o scale_y_continuous() y aplicar temas visuales con theme() u otros temas predefinidos.

A cada función ggplot() al paquete ggplot2, el argumento <data> debe ser un dataframe. A causa de lo anterior, el paquete dplyr será un buen complemento a ggplot2, pues los outputs de sus funciones son precisamente dataframes.

Para comenzar a graficar, diseñaremos nuestro primer gráfico de barras usando ggplot2 y la base de datos heart. Tenemos que escoger una variable cualitativa que queramos representar. Para ello, crearemos un dataframe, por medio del paquete dplyr que nos contabilice qué tipo de electrocardiograma en reposo muestran los pacientes, por lo que la variable a utilizar será RepECG. Posteriormente, introduciremos el dataframe creado a la función ggplot(),

# Creamos el dataframe que contabiliza la variable RepECG
conteo_RepECG <- heart %>% 
  count(RepECG)

# Imprimimos el dataframe
conteo_RepECG
# Creamos el gráfico de barras con ggplot2
ggplot(conteo_RepECG) +
  geom_bar(aes(x = RepECG, y = n, fill = RepECG), stat = "identity") + # Agregamos la capa geométrica de gráfico de barras. Agregamos el argumento stat = "identity"
  labs(x = "Tipo de electrocardiograma en reposo", y = "Número de observaciones", title = "Cantidad de observaciones para cada tipo de electrocardiograma en reposo") + # Añadimos etiquetas y título
  theme(axis.text.x = element_text(angle = 45, hjust = 1))  # Rotar etiquetas del eje x

Notemos que agregamos el argumento stat = "identity". la razón de por qué no lo mencionamos antes, es que la función geom_bar en ggplot2 no siempre debe llevar la función stat. La función geom_bar por defecto utiliza stat = "count", lo que significa que automáticamente cuenta el número de ocurrencias de cada categoría en el eje X y representa estas frecuencias como alturas de barras en el gráfico. También podemos especificar explícitamente una función stat diferente en geom_bar si necesitamos realizar otro tipo de manipulación de los datos antes de la representación visual. Por ejemplo, podemos usar stat = "sum" para sumar los valores de una variable dentro de cada categoría en el eje X y mostrar estas sumas como alturas de barras en el gráfico. O como acabamos de hacer, podemos usar stat = "identity" cuando ya tenemos los valores precalculados de las alturas de las barras y no necesitamos que ggplot2 realice ningún cálculo adicional.

Para el caso de la función theme(), axis.text.x = element_text(angle = 45, hjust = 1) rota las etiquetas del eje X (axis.text.x) en un ángulo de 45 grados y las alinea horizontalmente hacia la derecha (hjust = 1).

Ahora, volviendo al análisis del gráfico, es claro que el número de observaciones para el tipo de electrocardiograma en reposo “Normal” presentado por los pacientes es ampliamente superior a “LVH” y “ST”, los cuales son similares en su frecuencia.

Continuemos nuestro estudio de gráficos en ggplot2 con un histograma. Para ello, necesitamos un conjunto de datos cuantitativos, los cuales obtendremos de la variable colesterol de la base de datos heart. Realizaremos una comparativa entre la frecuencia para ciertos rangos de colesterol entre hombres y mujeres, por lo que necesitamos modelar dos histogramas. Además, ya mencionamos en la sección anterior que habían 172 observaciones para la variable colesterol iguales a 0, así que tendremos que realizar un filtrado de datos.

# Realizamos el filtrado, creando un dataframe llamado colesterol_pos
# que no contenga ningun valor de colesterol igual a 0.
colesterol_pos <- heart %>% 
  filter(Col > 0) 

# Comenzamos introduciendo como argumento a nuestra función ggplot
# el dataframe creado.
ggplot(colesterol_pos) + 
  
# Usamos las personalizaciones explicadas anteriormente.
  geom_histogram(aes(x = Col), bins = 10, fill="pink", colour="black") +
  theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
  
# Especificamos los puntos de quiebre en el eje x con la opción "breaks" 
# Dentro de c va cada quiebre.
  scale_x_continuous(breaks = c(0, 90, 140, 200, 260, 320, 370, 430, 490, 550,  max(colesterol_pos$Col))) +
  
  labs(
    title = "Frecuencia de niveles de colesterol entre hombres y mujeres ",
    x = "Niveles de colesterol [mg/dL]",
    y = "Frecuencia"
  ) +

  
# Dividimos el histograma en dos, en base a la variable Sexo.
  facet_grid(Sexo ~.)

Claramente hay un intervalo donde que agrupa la mayor frecuencia para las observaciones. La gran mayoría de los pacientes, tanto sexo masculino como femenino, tenían entre 220 a 260 mg/dL de colesterol sérico cuando se les tomó la muestra. La comparación entre las frecuencias tanto para sexo masculino y femenino parece seguir una misma tendencia, pese a que tengamos un número menor de observaciones para las pacientes de sexo femenino.
Según valores de la literatura médica, los niveles óptimos de colesterol sérico son por debajo de 200 mg/dL, por lo que sería una buena idea aumentar la cantidad de barras, y así tener una mayor claridad, al tener un histograma más detallado, de los valores que se presentan en los intervalos cercanos a niveles no recomendados. Bastaría con cambiar el número de bins.

Proseguimos el estudio de gráficos con un boxplot, esta vez usando la base de datos possum. Esta base de datos posee bastantes variables numéricas que podemos escoger como nuestro conjunto de datos para graficar. Observaremos visualmente, un hecho que difícilmente podríamos haber asimilado si hubiésemos tenido todos los datos dispersos frente a nuestros ojos. Grafiquemos un boxplot entre el tamaño del pie de las zarigüeya y su ubicación.

ggplot(possum, aes(x = Pop, y = footlgth)) +
  
  # Color de llenado como fill, color de bordes como color, 
  # alpha indica la transparencia de las cajas y bigote, va de 0 a 1,
  # width controla el ancho de las cajas y el bigote.
  geom_boxplot(fill = "lightblue", color = "darkblue", alpha = 0.7, width = 0.5, notch = FALSE) +
  
  # theme_minimal: diseño de gráfico minimalista
  theme_minimal() + 
  
  # Ajustamos las etiquetas y el título.
  labs(
    title = "Distribución de longitud de pies de zarigüeya por locación",
    x = "Locación",
    y = "Longitud del pie [cm]"
  )

Hagamos una interpretación de los boxplot:

explicar la longitud de los bigotes y su concentración, en particular, q el bigote inferior es más corto de ambos entonces entre el 25% de los pies más pequeños se concentran más que el 25% de los pies más grandes

explicar que en el boxplot derecho la mediana está más tirada hacia Q3, eso quiere decir que los tamaños de los pies entre el 25% y 50% de las zarigueyas está más disperso

mostrar rango intercuartilico

Se puede apreciar claramente que las zarigüeyas de Victoria tienen un pie más grande que las zarigüeyas de New South Wales or Queensland, y por una gran diferencia. Ciertamente hay casos extremos, que son los puntos aislados en ambos boxplot,

Gráfico de dispersión de datos para la correlación entre el tamaño de la pata y oreja de las zarigueyas.

ggplot(data = possum, aes(x = footlgth, y = earconch)) + geom_point(alpha = 0.4, color = "blue", aes(shape = sex))
## Warning: Removed 1 rows containing missing values (`geom_point()`).

3 Problemas resueltos

Recopilación de problemas resueltos del libro Introducción a la probabilidad de Luis Rincón.

3.1 Probabilidad elemental

3.1.1 Análisis combinatorio

Comenzaremos con ejercicios de análisis combinatorio. Cargamos el paquete gtools que usaremos bastante.

library(gtools)

1.- (P.76, Corredores) ¿De cuántas maneras diferentes pueden clasificarse los tres primeros lugares de una carrera de n corredores?

Sí nos importa el orden de las personas, pero no vamos a reponer a ninguna, puesto que no queremos que la misma persona obtenga el primer y segundo lugar a la vez. Para el primer lugar pueden clasificarse \(n\), para el segundo \(n-1\) y para el tercero \(n-2\). Así, pueden clasificarse de \(n(n-1)(n-2)\) maneras.

La siguiente función nos creará una matriz con las posibles permutaciones para los 3 lugares, donde el argumento es los n corredores.

tres_lugares <- function(x) {
  resultado <- permutations(x, 3, 1:x)
  permutaciones <- x*(x-1)*(x-2)
  print(resultado)
  print(paste("El número de permutaciones es", permutaciones))
}

Veamos por ejemplo para n = 3

tres_lugares(3)
##      [,1] [,2] [,3]
## [1,]    1    2    3
## [2,]    1    3    2
## [3,]    2    1    3
## [4,]    2    3    1
## [5,]    3    1    2
## [6,]    3    2    1
## [1] "El número de permutaciones es 6"

2.- (P.77, Mesa circular) ¿De cuántas maneras diferentes pueden sentarse n personas en una mesa circular?

Si etiquetamos a cada persona con un número y consideramos que cada posible configuración tiene en cuenta cuál persona etiquetada está frente a cuál, y además cada asiento está separado a la misma distancia entre sí, tenemos n! maneras distintas. Por ejemplo, una configuración podría ser {1, 2, 3}, que sería distinta a {1, 3, 2}, porque en la primera configuración, 1 está frente a 3, mientras que en la segunda, 1 está frente a 2.

Una segunda forma de ver el problema sería nuevamente etiquetar a las personas con un número, pero solo consideramos quién está a la derecha de quién, por lo que tenemos n!/n maneras diferentes, ya que tenemos configuraciones que se repiten, por ejemplo, {1, 2, 3} es igual a {3, 1, 2}.

Un comando de R que nos muestre las posibles configuraciones para la segunda forma de ver el problema podría ser permutations(n, 3, 1:n)[1:(factorial(n)/n), ], para n a elección.

3.- (P.79, Rumores) Tengo dudas con este ejercicio En un pueblo de n + 1 habitantes, uno de ellos le rumorea algo a una segunda persona, ésta, a su vez, se lo cuenta a una tercera persona (que puede ser la primera persona), y así sucesivamente. Determine la probabilidad de que el rumor se transmita r veces sin que regrese a la primera persona.

  • Experimento: n + 1 personas se traspasan, una tras otra, un rumor r veces.

  • |Espacio muestral| = \(n^r\) = \(\Omega\)

  • Evento: El rumor no vuelve a la primera persona = E

Podemos restarle a los casos totales, el caso en el que el rumor sí vuelve a la primera persona después de r transmiciones. Hay \(n^{r-1}(n-1)\) formas de que este caso ocurra. Así,

\[\begin{equation*} \mathbb{P}(E) = \frac{n^r-n^{r-1}(n-1)}{n^r} \end{equation*}\]
library(ggplot2)

# Definir la función de probabilidad
probabilidad_rumor <- function(n, r) {
  return ((n^(r-1) * (n-1)) / (n^r))
}

# Crear un data frame con diferentes valores de n y r
n_valores <- seq(1, 10, 2)  # Valores de n de 1 a 10
r_valores <- seq(1, 10, 2)   # Valores de r de 1 a 5
df <- expand.grid(n = n_valores, r = r_valores)
df$probabilidad <- probabilidad_rumor(df$n, df$r)

# Crear el gráfico de puntos con ggplot2
ggplot(df, aes(x = n, y = r, color = probabilidad)) +
  geom_point(size = 3) +
  scale_color_gradient(low = "lightblue", high = "darkblue") +
  labs(x = "Valor de n", y = "Valor de r", title = "Probabilidad de que el rumor no vuelva a la primera persona") +
  theme_minimal()

4.- (P.92, Las cajas de cerillos de Banach). Una persona tiene dos cajas de cerillos, cada una de las cuales contiene n cerillos. La persona coloca una caja en cada uno de sus bolsillos izquierdo y derecho, y cada vez que requiere un cerillo elige uno de sus bolsillos al azar y toma de la caja correspondiente uno de los cerillos. ¿Cuál es la probabilidad de que en el momento en el que la persona se da cuenta de que la caja del bolsillo izquierdo está vacía, en la caja del bolsillo derecho haya exactamente r cerillos?

Experimento:

Espacio muestral:

Evento:

EStá difícil este. Me ha costado harto.

4 Anexo

4.1 Descarga e instalación de R

4.2 Descarga e instalación de paquetes

library(dplyr)
library(knitr)

Cargar el paquete dplyr. Seguir explicando

Uso básico del pipe (%>%): El pipe se utiliza para encadenar operaciones de manera secuencial, pasando el resultado de una operación como entrada a la siguiente operación. La sintaxis básica del pipe es la siguiente:

objeto_inicial %>% operacion1() %>% operacion2() %>% ... %>% operacionN()

En esta sintaxis:

  • objeto_inicial es el objeto inicial que deseamos transformar o manipular.
  • operacion1(), operacion2(), …, operacionN() son las operaciones que deseamos aplicar al objeto inicial en secuencia.

Ejemplo de uso:

# Creamos un vector de números
numeros <- c(1, 2, 3, 4, 5)

# Utilizamos el pipe para aplicar operaciones secuenciales
resultado <- numeros %>%
  sum() %>%           # Calculamos la suma de los números
  sqrt() %>%          # Calculamos la raíz cuadrada del resultado
  round(digits = 2)   # Redondeamos el resultado a 2 decimales

print(resultado)      # Imprimir el resultado
## [1] 3.87

Enseñar a instalar paquetes con gif