Estos son los paquetes con los que estaremos trabajando
#instalar paquetes
install.packages("tidyverse")
## Installing package into '/cloud/lib/x86_64-pc-linux-gnu-library/4.3'
## (as 'lib' is unspecified)
install.packages("lubridate")
## Installing package into '/cloud/lib/x86_64-pc-linux-gnu-library/4.3'
## (as 'lib' is unspecified)
install.packages("readxl")
## Installing package into '/cloud/lib/x86_64-pc-linux-gnu-library/4.3'
## (as 'lib' is unspecified)
install.packages("gtsummary")
## Installing package into '/cloud/lib/x86_64-pc-linux-gnu-library/4.3'
## (as 'lib' is unspecified)
# Carga de librerías
library(tidyverse)
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr 1.1.3 ✔ readr 2.1.4
## ✔ forcats 1.0.0 ✔ stringr 1.5.0
## ✔ ggplot2 3.4.4 ✔ tibble 3.2.1
## ✔ lubridate 1.9.3 ✔ tidyr 1.3.0
## ✔ purrr 1.0.2
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag() masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(lubridate)
library(readxl)
library(gtsummary)
Análisis exploratorio
df %>% select(GESTAS,EDAD, PESO,PESO2,ganancia_peso,MENARCA,IVSA,CEFALEA,MAREOS,NAUSEA,MASTALGIA,MOTIVOS,motivo_categoria) %>% tbl_summary()
| Characteristic |
N = 93 |
| GESTAS |
|
| multigesta |
29 (31%) |
| nuligesta |
22 (24%) |
| primigesta |
42 (45%) |
| EDAD |
27 (24, 30) |
| PESO |
63 (55, 69) |
| PESO2 |
66 (59, 71) |
| Unknown |
26 |
| ganancia_peso |
1.6 (0.0, 5.2) |
| Unknown |
26 |
| MENARCA |
|
| 9 |
1 (1.1%) |
| 10 |
5 (5.4%) |
| 11 |
11 (12%) |
| 12 |
28 (30%) |
| 13 |
14 (15%) |
| 14 |
22 (24%) |
| 15 |
8 (8.6%) |
| 16 |
3 (3.2%) |
| 17 |
1 (1.1%) |
| IVSA |
18.00 (17.00, 19.00) |
| CEFALEA |
|
| NO |
88 (95%) |
| SI |
5 (5.4%) |
| MAREOS |
|
| NO |
89 (96%) |
| SI |
4 (4.3%) |
| NAUSEA |
|
| NO |
93 (100%) |
| MASTALGIA |
|
| NO |
86 (92%) |
| SI |
7 (7.5%) |
| MOTIVOS |
|
| ANSIEDAD Y DEPRESION |
2 (2.2%) |
| AUMENTO DE PESO |
2 (2.2%) |
| CADUCIDAD |
26 (28%) |
| CAMBIO DE METODO |
1 (1.1%) |
| CEFALEA INTENSA |
18 (19%) |
| DESEO DE EMBARAZO |
13 (14%) |
| HISTERECTOMIA |
1 (1.1%) |
| OTROS MOTIVOS |
3 (3.2%) |
| RECAMBIO |
15 (16%) |
| TRANSTORNO MENSTRUAL |
10 (11%) |
| TRANSTORNO MESTRUAL |
2 (2.2%) |
| motivo_categoria |
|
| EFECTO SECUNDARIO |
34 (37%) |
| NO EFECTO SECUNDARIO |
59 (63%) |
# Calculando frecuencias y porcentajes
motivo_counts <- df %>%
count(motivo_categoria) %>%
mutate(percent = n / sum(n) * 100)
# Uniendo los valores de frecuencia y porcentaje en una sola etiqueta
motivo_counts <- motivo_counts %>%
mutate(label = paste(n, "(", sprintf("%.1f", percent), "%)", sep = ""))
# Generando la gráfica
ggplot(motivo_counts, aes(x = motivo_categoria, y = n, fill = motivo_categoria)) +
geom_bar(stat = "identity") +
geom_text(aes(label = label), vjust = -0.3, size = 3.5) +
labs(title = "Frecuencia y Porcentaje por Categoría de Motivo",
x = "Categoría de Motivo",
y = "Frecuencia") +
theme_minimal() +
theme(legend.title = element_blank()) # Oculta la leyenda de título si es necesario

# Creando los grupos de edad
df <- df %>%
mutate(grupo_edad = case_when(
EDAD < 25 ~ "< 25 AÑOS",
EDAD >= 25 & EDAD <= 35 ~ "25 A 35 AÑOS",
EDAD > 35 ~ "> 35 AÑOS",
TRUE ~ "EDAD NO ESPECIFICADA" # Para cualquier edad que no esté definida en los rangos
))
glimpse(df$grupo_edad)
## chr [1:93] "25 A 35 AÑOS" "25 A 35 AÑOS" "< 25 AÑOS" "25 A 35 AÑOS" ...
unique(df$grupo_edad)
## [1] "25 A 35 AÑOS" "< 25 AÑOS" "> 35 AÑOS"
str(df)
## tibble [93 × 22] (S3: tbl_df/tbl/data.frame)
## $ AÑO : num [1:93] 2018 2018 2018 2018 2018 ...
## $ NOMBRE DEL PACIENTE : chr [1:93] "ACOSTA HEREDIA CAREM SUJEY" "ALVAREZ VALENZUELA DIGNORA GPE." "GUILLEN OBESO MARGARITA" "VERDUGO VITAL CRISTAL VIANEY" ...
## $ F. APLIC. : Date[1:93], format: "2018-01-16" "2018-01-25" ...
## $ GESTAS : chr [1:93] "multigesta" "primigesta" "primigesta" "nuligesta" ...
## $ PESO : num [1:93] 68.7 79.4 63.3 68 57.6 59.5 69.1 65 55.1 63.8 ...
## $ MENARCA : num [1:93] 14 12 9 12 12 12 13 12 14 14 ...
## $ IVSA : num [1:93] 17 22 18 18 16 15 20 15 23 18 ...
## $ FRECUENCIA : chr [1:93] "NORMAL" "NORMAL" "PROLONGADO" "NORMAL" ...
## $ CANTIDAD : chr [1:93] "ESCASA" "ABUNDANTES" "ESCASA" "ESCASA" ...
## $ CEFALEA : chr [1:93] "NO" "NO" "NO" "NO" ...
## $ MAREOS : chr [1:93] "NO" "NO" "NO" "NO" ...
## $ NAUSEA : chr [1:93] "NO" "NO" "NO" "NO" ...
## $ MASTALGIA : chr [1:93] "NO" "NO" "NO" "NO" ...
## $ FECHA : Date[1:93], format: "2018-01-16" "2019-01-10" ...
## $ MOTIVOS : chr [1:93] "RECAMBIO" "TRANSTORNO MENSTRUAL" "AUMENTO DE PESO" "RECAMBIO" ...
## $ PESO2 : num [1:93] 70 76.2 76.4 NA NA 61.1 69 NA NA NA ...
## $ EDAD : num [1:93] 33 27 21 27 29 32 27 27 42 29 ...
## $ dias_transcurridos : num [1:93] 0 350 576 0 159 ...
## $ ganancia_peso : num [1:93] 1.3 -3.2 13.1 NA NA ...
## $ motivo_categoria : chr [1:93] "NO EFECTO SECUNDARIO" "EFECTO SECUNDARIO" "EFECTO SECUNDARIO" "NO EFECTO SECUNDARIO" ...
## $ codigo_efecto_secundario: num [1:93] 0 1 1 0 0 1 0 0 0 1 ...
## $ grupo_edad : chr [1:93] "25 A 35 AÑOS" "25 A 35 AÑOS" "< 25 AÑOS" "25 A 35 AÑOS" ...
# Calculando frecuencias y porcentajes
grupo_edadcounts <- df %>%
count(grupo_edad) %>%
mutate(percent = n / sum(n) * 100)
# Uniendo los valores de frecuencia y porcentaje en una sola etiqueta
grupo_edadcounts <- grupo_edadcounts %>%
mutate(label = paste(n, "(", sprintf("%.1f", percent), "%)", sep = ""))
# Convirtiendo la columna 'grupo_edad' a un factor con niveles ordenados
df$grupo_edad <- factor(df$grupo_edad, levels = c("< 25 AÑOS", "25 A 35 AÑOS", "> 35 AÑOS"))
# Generando la gráfica
ggplot(grupo_edadcounts, aes(x = grupo_edad, y = n, fill = grupo_edad)) +
geom_bar(stat = "identity") +
geom_text(aes(label = label), vjust = -0.3, size = 3.5) +
labs(title = "Frecuencia y Porcentaje por grupo de edad",
x = "Grupos de edad",
y = "Frecuencia") +
theme_minimal() +
theme(legend.title = element_blank()) # Oculta la leyenda de título si es necesario

df %>% select(grupo_edad, GESTAS, CEFALEA, MAREOS, NAUSEA, MASTALGIA, motivo_categoria, MOTIVOS) %>% tbl_summary(by=grupo_edad) %>% add_p() %>% add_overall()
## There was an error in 'add_p()/add_difference()' for variable 'NAUSEA', p-value omitted:
## Error in stats::chisq.test(x = c("NO", "NO", "NO", "NO", "NO", "NO", "NO", : 'x' and 'y' must have at least 2 levels
## There was an error in 'add_p()/add_difference()' for variable 'MOTIVOS', p-value omitted:
## Error in stats::fisher.test(c("RECAMBIO", "TRANSTORNO MENSTRUAL", "AUMENTO DE PESO", : FEXACT error 7(location). LDSTP=18630 is too small for this problem,
## (pastp=11.0031, ipn_0:=ipoin[itp=65]=4591, stp[ipn_0]=14.2989).
## Increase workspace or consider using 'simulate.p.value=TRUE'
| Characteristic |
Overall, N = 93 |
< 25 AÑOS, N = 24 |
25 A 35 AÑOS, N = 58 |
> 35 AÑOS, N = 11 |
p-value |
| GESTAS |
|
|
|
|
<0.001 |
| multigesta |
29 (31%) |
2 (8.3%) |
20 (34%) |
7 (64%) |
|
| nuligesta |
22 (24%) |
10 (42%) |
8 (14%) |
4 (36%) |
|
| primigesta |
42 (45%) |
12 (50%) |
30 (52%) |
0 (0%) |
|
| CEFALEA |
|
|
|
|
0.8 |
| NO |
88 (95%) |
22 (92%) |
55 (95%) |
11 (100%) |
|
| SI |
5 (5.4%) |
2 (8.3%) |
3 (5.2%) |
0 (0%) |
|
| MAREOS |
|
|
|
|
0.7 |
| NO |
89 (96%) |
22 (92%) |
56 (97%) |
11 (100%) |
|
| SI |
4 (4.3%) |
2 (8.3%) |
2 (3.4%) |
0 (0%) |
|
| NAUSEA |
|
|
|
|
|
| NO |
93 (100%) |
24 (100%) |
58 (100%) |
11 (100%) |
|
| MASTALGIA |
|
|
|
|
>0.9 |
| NO |
86 (92%) |
22 (92%) |
54 (93%) |
10 (91%) |
|
| SI |
7 (7.5%) |
2 (8.3%) |
4 (6.9%) |
1 (9.1%) |
|
| motivo_categoria |
|
|
|
|
>0.9 |
| EFECTO SECUNDARIO |
34 (37%) |
9 (38%) |
21 (36%) |
4 (36%) |
|
| NO EFECTO SECUNDARIO |
59 (63%) |
15 (63%) |
37 (64%) |
7 (64%) |
|
| MOTIVOS |
|
|
|
|
|
| ANSIEDAD Y DEPRESION |
2 (2.2%) |
0 (0%) |
2 (3.4%) |
0 (0%) |
|
| AUMENTO DE PESO |
2 (2.2%) |
2 (8.3%) |
0 (0%) |
0 (0%) |
|
| CADUCIDAD |
26 (28%) |
9 (38%) |
15 (26%) |
2 (18%) |
|
| CAMBIO DE METODO |
1 (1.1%) |
0 (0%) |
1 (1.7%) |
0 (0%) |
|
| CEFALEA INTENSA |
18 (19%) |
5 (21%) |
13 (22%) |
0 (0%) |
|
| DESEO DE EMBARAZO |
13 (14%) |
3 (13%) |
10 (17%) |
0 (0%) |
|
| HISTERECTOMIA |
1 (1.1%) |
0 (0%) |
0 (0%) |
1 (9.1%) |
|
| OTROS MOTIVOS |
3 (3.2%) |
0 (0%) |
2 (3.4%) |
1 (9.1%) |
|
| RECAMBIO |
15 (16%) |
3 (13%) |
9 (16%) |
3 (27%) |
|
| TRANSTORNO MENSTRUAL |
10 (11%) |
2 (8.3%) |
5 (8.6%) |
3 (27%) |
|
| TRANSTORNO MESTRUAL |
2 (2.2%) |
0 (0%) |
1 (1.7%) |
1 (9.1%) |
|
# Cargando las librerías necesarias
library(survival)
#install.packages("survminer")
library(survminer)
## Loading required package: ggpubr
##
## Attaching package: 'survminer'
## The following object is masked from 'package:survival':
##
## myeloma
# Ajustando el modelo de Kaplan-Meier
km_fit <- survfit(Surv(dias_transcurridos, codigo_efecto_secundario) ~ grupo_edad, data = df)
# Calculando el riesgo acumulado
risks <- summary(km_fit, times = c(1:max(df$dias_transcurridos)), censored = TRUE)
# Creando la gráfica del riesgo acumulado
ggsurvplot(km_fit,
fun = "cumhaz", # Cambiando la función de supervivencia por la de riesgo acumulado
data = df,
pval = FALSE,
risk.table = FALSE,
conf.int = FALSE,
palette = "Dark2",
title = "Curva de Riesgo Acumulado de Efectos Adversos según Grupo de Edad",
xlab = "Días hasta el retiro",
ylab = "Riesgo Acumulado de Efectos Adversos",
risk.table.height = 0.2, # Ajustando la altura de la tabla de riesgo
surv.median.line = "none", # No mostrar la línea de la mediana
break.time.by = 100) # Intervalos para la tabla de riesgo

# `codigo_efecto_secundario` debería ser un factor donde 1 indica un evento (efecto adverso) y 0 censura.
# Asegurándonos de que GESTAS es un factor
df$GESTAS <- factor(df$GESTAS, levels = c("nuligesta", "primigesta", "multigesta"))
# Ajustando el modelo de Kaplan-Meier por número de gestas
km_fit_gestas <- survfit(Surv(dias_transcurridos, codigo_efecto_secundario) ~ GESTAS, data = df)
# Creando la gráfica del riesgo acumulado por número de gestas
ggsurvplot(km_fit_gestas,
fun = "cumhaz", # Función de riesgo acumulado
data = df,
pval = FALSE,
risk.table = FALSE,
conf.int = FALSE,
palette = "Dark2",
title = "Curva de Riesgo Acumulado de Efectos Adversos según Número de Gestas",
xlab = "Días hasta el retiro",
ylab = "Riesgo Acumulado de Efectos Adversos",
risk.table.height = 0.2, # Ajuste de la altura de la tabla de riesgo
surv.median.line = "none", # No mostrar la línea de la mediana
break.time.by = 100) # Intervalos para la tabla de riesgo
