En esta actividad realizaremos el análisis exploratorio y el preproceso del conjunto de datos Titanic (archivo titanic_dataset.xlsx), que contiene información de pasajeros/as del RMS Titanic. El objetivo es preparar los datos para posteriores análisis estadísticos.
Pregunta: Cargad el fichero titanic_dataset.xlsx, examinad el tipo de datos y verificad la consistencia del identificador único.
# Cargar los datos
titanic <- read_excel("titanic_dataset.xlsx")
# Examinar los tipos de datos iniciales
str(titanic)
## tibble [1,309 × 12] (S3: tbl_df/tbl/data.frame)
## $ PassengerId: num [1:1309] 1 2 3 4 5 6 7 8 9 10 ...
## $ Survived : num [1:1309] 0 1 1 1 0 0 0 0 1 1 ...
## $ Pclass : num [1:1309] 3 1 3 1 3 3 1 3 3 2 ...
## $ Name : chr [1:1309] "Braund, Mr. Owen Harris" "Cumings, Mrs. John Bradley (Florence Briggs Thayer)" "Heikkinen, Miss. Laina" "Futrelle, Mrs. Jacques Heath (Lily May Peel)" ...
## $ Sex : chr [1:1309] "male" "female" "female" "female" ...
## $ Age : num [1:1309] 22 38 26 35 35 NA 54 2 27 14 ...
## $ SibSp : num [1:1309] 1 1 0 1 0 0 0 3 0 1 ...
## $ Parch : num [1:1309] 0 0 0 0 0 0 0 1 2 0 ...
## $ Ticket : chr [1:1309] "A/5 21171" "PC 17599" "STON/O2. 3101282" "113803" ...
## $ Fare : chr [1:1309] "7.25" "71.2833" "7.925" "53.1" ...
## $ Cabin : chr [1:1309] NA "C85" NA "C123" ...
## $ Embarked : chr [1:1309] "S" "C" "S" "S" ...
# Verificar identificador único
duplicados <- titanic %>% filter(duplicated(PassengerId))
Explicación: Se ha cargado el archivo. Si el número
de filas de duplicados es 0, significa que el identificador
de pasajero es único, cumpliendo el criterio de normalización. En caso
de haber duplicados exactos, se eliminarían con la función
distinct().
En este apartado revisamos las variables cuantitativas, corrigiendo
formatos y valores perdidos. Los valores perdidos o erróneos se
sustituirán por NA.
Pregunta: La variable Age debe ser de tipo cuantitativa discreta (entero).
titanic <- titanic %>%
mutate(Age = as.integer(Age))
head(titanic$Age)
## [1] 22 38 26 35 35 NA
Pregunta: Las variables SibSp y Parch deben ser de tipo numérico.
titanic <- titanic %>%
mutate(
SibSp = as.numeric(SibSp),
Parch = as.numeric(Parch)
)
Pregunta: La variable Fare debe ser de tipo numérico continuo y redondearse a dos decimales.
titanic <- titanic %>%
mutate(
Fare = as.numeric(gsub(",", ".", Fare)), # Asegurar punto como separador
Fare = round(Fare, 2)
)
head(titanic$Fare)
## [1] 7.25 71.28 7.92 53.10 8.05 8.46
Pregunta: Cread una variable FamS (FamilySize) que contenga el total de SibSp y Parch (+1) y mostrad su distribución gráficamente.
titanic <- titanic %>%
mutate(FamS = SibSp + Parch + 1)
ggplot(titanic, aes(x = FamS)) +
geom_histogram(binwidth = 1, fill = "steelblue", color = "black") +
theme_minimal() +
labs(title = "Distribución del Tamaño Familiar (FamS)", x = "Tamaño Familiar", y = "Frecuencia")
Pregunta: Transformar a Yes/No en lugar de 1/0.
titanic <- titanic %>%
mutate(Survived = factor(ifelse(Survived == 1, "Yes", "No")))
Pregunta: La variable Pclass debe ser de tipo ordinal.
titanic <- titanic %>%
mutate(Pclass = factor(Pclass, levels = c(1, 2, 3), ordered = TRUE))
Pregunta: Tipo categórico con valores “Female”, “Male”.
titanic <- titanic %>%
mutate(
Sex = str_to_title(Sex), # Asegura que empiece en mayúscula
Sex = factor(Sex, levels = c("Female", "Male"))
)
Pregunta: Debe contener el nombre completo: Cherbourg (C)/Queenstown (Q)/Southampton (S).
titanic <- titanic %>%
mutate(Embarked = case_when(
Embarked == "C" ~ "Cherbourg (C)",
Embarked == "Q" ~ "Queenstown (Q)",
Embarked == "S" ~ "Southampton (S)",
TRUE ~ as.character(Embarked)
)) %>%
mutate(Embarked = factor(Embarked))
Pregunta: Variables Name, Ticket y Cabin. Eliminar espacios al inicio y final.
titanic <- titanic %>%
mutate(across(c(Name, Ticket, Cabin), str_trim))
Pregunta: Visualizad la distribución de Age. Identificad posibles valores extremos e interpretad.
ggplot(titanic, aes(y = Age)) +
geom_boxplot(fill = "lightblue") +
theme_minimal() +
labs(title = "Boxplot de Edad")
Explicación: Se observan valores por encima de los
65-70 años. En el contexto del Titanic, estos valores son plausibles
(pasajeros ancianos), por lo que se consideran extremos biológicamente
posibles, no errores. No se sustituyen por NA salvo que
hubiese edades negativas o imposibles.
Pregunta: Revisad outliers. Mostrad pasajeros con las 10 tarifas más altas.
ggplot(titanic, aes(y = Fare)) +
geom_boxplot(fill = "lightgreen") +
theme_minimal() +
labs(title = "Boxplot de Tarifas (Fare)")
# 10 tarifas más altas
titanic %>%
arrange(desc(Fare)) %>%
select(Name, Pclass, Fare) %>%
head(10) %>%
kable() %>%
kable_styling(bootstrap_options = c("striped", "hover"))
| Name | Pclass | Fare |
|---|---|---|
| Ward, Miss. Anna | 1 | 512.33 |
| Cardeza, Mr. Thomas Drake Martinez | 1 | 512.33 |
| Lesurer, Mr. Gustave J | 1 | 512.33 |
| Cardeza, Mrs. James Warburton Martinez (Charlotte Wardle Drake) | 1 | 512.33 |
| Fortune, Mr. Charles Alexander | 1 | 263.00 |
| Fortune, Miss. Mabel Helen | 1 | 263.00 |
| Fortune, Miss. Alice Elizabeth | 1 | 263.00 |
| Fortune, Mr. Mark | 1 | 263.00 |
| Fortune, Miss. Ethel Flora | 1 | 263.00 |
| Fortune, Mrs. Mark (Mary McDougald) | 1 | 263.00 |
Explicación: Hay valores atípicos muy elevados. Dado que los billetes de primera clase podían ser extremadamente caros y a menudo comprados para familias enteras bajo un mismo billete, no se tratan de errores de digitación, sino de extremos reales.
Pregunta: Calculad matriz de correlaciones entre variables cuantitativas (incluyendo FamS y Survived numérico) y mostrad las más correlacionadas con supervivencia.
# Preparar datos numéricos
datos_cor <- titanic %>%
mutate(Survived_num = ifelse(Survived == "Yes", 1, 0)) %>%
select(Age, SibSp, Parch, Fare, FamS, Survived_num) %>%
na.omit()
matriz_cor <- cor(datos_cor)
corrplot(matriz_cor, method = "circle", type = "upper")
# Variables más correlacionadas con Survived
cor_surv <- as.data.frame(matriz_cor) %>%
select(Survived_num) %>%
arrange(desc(abs(Survived_num)))
cor_surv %>% kable() %>% kable_styling()
| Survived_num | |
|---|---|
| Survived_num | 1.0000000 |
| Fare | 0.2406628 |
| Parch | 0.1157049 |
| FamS | 0.0741649 |
| Age | -0.0519486 |
| SibSp | 0.0115932 |
Pregunta: Imputad Age usando kNN (VIM), predictores numéricos/ordinales, vecinos = 5.
titanic_imp <- kNN(titanic, variable = "Age",
dist_var = c("Pclass", "SibSp", "Parch", "Fare", "FamS"),
k = 5, imp_var = FALSE)
# Mostrar algunos valores imputados
titanic_imp %>% select(PassengerId, Age) %>% head() %>% kable() %>% kable_styling()
| PassengerId | Age |
|---|---|
| 1 | 22 |
| 2 | 38 |
| 3 | 26 |
| 4 | 35 |
| 5 | 35 |
| 6 | 21 |
Pregunta: Calculad medidas de tendencia central y dispersión y presentad dos tablas agrupadas por Pclass y Sex. Guardad en titanic_dataset_clean.xlsx.
# Tabla resumen de tendencia central y dispersión agrupada
tabla_resumen <- titanic_imp %>%
group_by(Pclass, Sex) %>%
summarise(
Age_Mean = round(mean(Age, na.rm = TRUE), 2),
Age_Median = median(Age, na.rm = TRUE),
Age_SD = round(sd(Age, na.rm = TRUE), 2),
Age_MAD = mad(Age, na.rm = TRUE),
Fare_Mean = round(mean(Fare, na.rm = TRUE), 2),
Fare_Median = median(Fare, na.rm = TRUE),
Fare_SD = round(sd(Fare, na.rm = TRUE), 2),
Fare_MAD = mad(Fare, na.rm = TRUE),
.groups = "drop"
)
# Mostrar la tabla formateada
tabla_resumen %>% kable() %>% kable_styling()
| Pclass | Sex | Age_Mean | Age_Median | Age_SD | Age_MAD | Fare_Mean | Fare_Median | Fare_SD | Fare_MAD |
|---|---|---|---|---|---|---|---|---|---|
| 1 | Female | 36.44 | 35.5 | 13.53 | 17.0499 | 110.03 | 82.015 | 83.29 | 44.989497 |
| 1 | Male | 41.42 | 42.0 | 13.63 | 11.8608 | 70.28 | 49.750 | 74.10 | 34.396320 |
| 1 | NA | 54.00 | 47.0 | 19.47 | 11.8608 | 43.80 | 52.550 | 40.15 | 38.992380 |
| 2 | Female | 28.16 | 28.0 | 14.15 | 10.3782 | 23.33 | 23.000 | 11.25 | 10.748850 |
| 2 | Male | 32.41 | 30.0 | 15.41 | 11.8608 | 19.91 | 13.000 | 14.78 | 3.706500 |
| 2 | NA | 32.00 | 32.0 | NA | 0.0000 | 13.00 | 13.000 | NA | 0.000000 |
| 3 | Female | 23.89 | 23.0 | 12.64 | 10.3782 | 15.44 | 11.130 | 11.83 | 5.011188 |
| 3 | Male | 26.58 | 25.0 | 11.30 | 8.1543 | 12.33 | 7.900 | 11.01 | 0.963690 |
| 3 | NA | 31.00 | 31.0 | 10.89 | 13.3434 | 20.52 | 8.660 | 27.41 | 0.934038 |
| NA | Female | 29.50 | 29.5 | 21.92 | 22.9803 | 7.54 | 7.535 | 0.45 | 0.467019 |
| NA | Male | 25.00 | 25.0 | NA | 0.0000 | 7.05 | 7.050 | NA | 0.000000 |
# Guardar el fichero preprocesado
write_xlsx(titanic_imp, "titanic_dataset_clean.xlsx")