Sarcopenia y necesidades de cuidados paliativos

Análisis de datos SARC-F y SPARC-Sp

Autor/a

JA Calvache

Objetivos

Objetivo general. Estimar la asociación entre sarcopenia, medida con el instrumento SARC-F, y las necesidades holísticas no satisfechas de cuidados paliativos, determinadas con SPARC, en pacientes con enfermedades crónicas no transmisibles oncológicas y no oncológicas del Hospital Universitario San José entre 2021 y 2022. Este objetivo es exploratorio y no causal.

Objetivos específicos

  1. Describir las características sociodemográficas de los pacientes con enfermedades crónicas no transmisibles oncológicas y no oncológicas.
  2. Describir la prevalencia de sarcopenia, definida por un puntaje SARC-F > 4 puntos.
  3. Determinar la prevalencia de necesidades holísticas no satisfechas y estratificarla por dominio de la herramienta SPARC-Sp.
  4. Diseñar una estrategia de visualización apropiada para reportar las necesidades holísticas no satisfechas valoradas con SPARC-Sp.

Pregunta de investigación (PECO). En pacientes con enfermedades crónicas no transmisibles, ¿existe asociación entre la presencia de sarcopenia (SARC-F) y las necesidades no satisfechas (SPARC)?

1. Configuración

Todas las librerías se cargan aquí, una sola vez. También se definen los objetos que se reutilizan en el documento: la definición de los dominios SPARC y las paletas de colores.

Código
library(readxl)
library(tidyverse)     # dplyr, tidyr, ggplot2, forcats, purrr
library(summarytools)  # dfSummary
library(gtsummary)     # tablas descriptivas y de regresión
library(gt)
library(binom)         # IC de Wilson
library(performance)   # check_model, model_performance
library(see)           # gráficos de check_model
library(ggpubr)        # stat_compare_means
library(fmsb)          # radarchart

# Definición de los 6 dominios SPARC presentes en la base:
# ítems que lo componen y puntaje máximo posible (n ítems × 3)
dominios <- tribble(
  ~var,         ~nombre,                            ~items,
  "sparc_fis",  "Síntomas físicos",                 paste0("s", 2:22),
  "sparc_psic", "Temas psicológicos",               paste0("s", 23:31),
  "sparc_rel",  "Temas religiosos y espirituales",  paste0("s", 32:33),
  "sparc_inde", "Independencia y actividad",        paste0("s", 34:36),
  "sparc_fami", "Asuntos familiares y vida social", paste0("s", 37:40),
  "sparc_tra",  "Tratamiento",                      paste0("s", 41:42)
) %>%
  mutate(
    var_p  = paste0(var, "_p"),          # nombre de la versión ponderada (0–100)
    maximo = lengths(items) * 3
  )

# Etiquetas legibles: c(sparc_fis_p = "Síntomas físicos", ...)
etiquetas_dominio <- set_names(dominios$nombre, dominios$var_p)

items_sparc <- paste0("s", 2:42)
items_sarcf <- paste0("sarc", 1:5)

# Paletas
col_dominios <- c("#1F77B4", "#D62728", "#2CA02C", "#9467BD", "#FF7F0E", "#8C564B")
col_sarc     <- c("Sin Sarcopenia" = "steelblue", "Con Sarcopenia" = "firebrick")
col_likert   <- c("Nada" = "#2166AC", "Un poco" = "#67A9CF",
                  "Bastante" = "#F4A582", "Mucho" = "#B2182B")

theme_set(theme_minimal(base_size = 12))

2. Importación de datos

La ruta es relativa a la carpeta del proyecto para que el documento renderice en cualquier equipo. El resumen inicial excluye docum (documento de identidad), porque este informe se publica como sitio web.

Código
data <- read_excel("SPARC_data_labels.xlsx", .name_repair = "unique_quiet")

data_resumen <- select(data, -docum)
print(
  dfSummary(data_resumen, graph.magnif = 0.75, valid.col = FALSE),
  method = "render"
)

Data Frame Summary

data_resumen

Dimensions: 546 x 107
Duplicates: 0
No Variable Stats / Values Freqs (% of Valid) Graph Missing
1 id [numeric]
Mean (sd) : 273.5 (157.8)
min ≤ med ≤ max:
1 ≤ 273.5 ≤ 546
IQR (CV) : 272.5 (0.6)
546 distinct values 0 (0.0%)
2 ...2 [numeric]
Mean (sd) : 270.7 (157.5)
min ≤ med ≤ max:
1 ≤ 271 ≤ 543
IQR (CV) : 272.5 (0.6)
537 distinct values 0 (0.0%)
3 fecha [POSIXct, POSIXt]
min : 2021-11-09
med : 2022-06-09
max : 2022-07-13
range : 8m 4d
109 distinct values 0 (0.0%)
4 sitio [character]
1. Hospital San José Popayán
2. Otro hospital
545 ( 99.8% )
1 ( 0.2% )
0 (0.0%)
5 invest [character]
1. Camilo Cortes
2. Cindy Mendieta
3. Isabela Bolaños
4. Javier Orozco
5. Karen Rivera
79 ( 14.5% )
239 ( 43.8% )
57 ( 10.4% )
97 ( 17.8% )
74 ( 13.6% )
0 (0.0%)
6 sitio_hos [character]
1. Atención ambulatoria de O
2. Atención ambulatoria del
3. Otra área hospitalaria
4. Salas de hospitalización
63 ( 11.5% )
4 ( 0.7% )
69 ( 12.6% )
410 ( 75.1% )
0 (0.0%)
7 etnia [character]
1. Afrocolombiano
2. Blanco
3. Indígena
4. Mestizo
28 ( 5.1% )
71 ( 13.0% )
36 ( 6.6% )
411 ( 75.3% )
0 (0.0%)
8 genero [character]
1. Femenino
2. Masculino
329 ( 60.3% )
217 ( 39.7% )
0 (0.0%)
9 edad [numeric]
Mean (sd) : 65 (14.8)
min ≤ med ≤ max:
18 ≤ 66 ≤ 95
IQR (CV) : 20 (0.2)
72 distinct values 0 (0.0%)
10 civil [character]
1. Casado
2. Separado
3. Soltero
4. Unión libre
5. Viudo
198 ( 36.3% )
24 ( 4.4% )
105 ( 19.2% )
136 ( 24.9% )
83 ( 15.2% )
0 (0.0%)
11 religion [character]
1. Agnóstico
2. Ateo
3. Católico
4. Cristiano
5. Otro
4 ( 0.7% )
3 ( 0.5% )
450 ( 82.4% )
63 ( 11.5% )
26 ( 4.8% )
0 (0.0%)
12 g_religion [numeric]
Mean (sd) : 3.7 (1.1)
min ≤ med ≤ max:
0 ≤ 4 ≤ 5
IQR (CV) : 2 (0.3)
0 : 9 ( 1.6% )
1 : 8 ( 1.5% )
2 : 53 ( 9.7% )
3 : 171 ( 31.3% )
4 : 147 ( 26.9% )
5 : 158 ( 28.9% )
0 (0.0%)
13 educa [character]
1. Bachillerato
2. Ninguno
3. Primaria
4. Técnico
5. Universitario
166 ( 30.4% )
88 ( 16.1% )
230 ( 42.1% )
31 ( 5.7% )
31 ( 5.7% )
0 (0.0%)
14 ocupa [character]
1. AMA DE CASA
2. CESANTE
3. AGRICULTOR
4. PENSIONADO
5. COMERCIANTE
6. AGRICULTURA
7. INDEPENDIENTE
8. DESEMPLEADO
9. OFICIOS VARIOS
10. PENSIONADA
[ 70 others ]
221 ( 40.5% )
80 ( 14.7% )
36 ( 6.6% )
35 ( 6.4% )
21 ( 3.8% )
20 ( 3.7% )
13 ( 2.4% )
9 ( 1.6% )
8 ( 1.5% )
8 ( 1.5% )
95 ( 17.4% )
0 (0.0%)
15 procede [character]
1. Rural
2. Urbana
202 ( 37.0% )
344 ( 63.0% )
0 (0.0%)
16 convivi [numeric]
Mean (sd) : 3.5 (1.6)
min ≤ med ≤ max:
1 ≤ 3 ≤ 13
IQR (CV) : 2 (0.5)
11 distinct values 0 (0.0%)
17 transpor [character]
1. 0.5
2. 1
3. 0.25
4. 0.17
5. 0.08
6. 0.3
7. 2
8. 1.5
9. 0.2
10. 0.33
[ 31 others ]
115 ( 21.1% )
88 ( 16.1% )
59 ( 10.8% )
46 ( 8.4% )
32 ( 5.9% )
27 ( 4.9% )
23 ( 4.2% )
21 ( 3.8% )
17 ( 3.1% )
16 ( 2.9% )
102 ( 18.7% )
0 (0.0%)
18 ...19 [character]
1. Algunas veces
2. Nunca
3. Siempre
135 ( 24.7% )
42 ( 7.7% )
369 ( 67.6% )
0 (0.0%)
19 ...20 [character]
1. Algunas veces
2. Nunca
3. Siempre
152 ( 27.8% )
31 ( 5.7% )
363 ( 66.5% )
0 (0.0%)
20 ...21 [character]
1. Algunas veces
2. Nunca
3. Siempre
212 ( 38.8% )
58 ( 10.6% )
276 ( 50.5% )
0 (0.0%)
21 dx1 [character]
1. HIPERTENSION ARTERIAL
2. DIABETES MELLITUS
3. DIABETES MELLITUS TIPO II
4. OSTEOPOROSIS
5. HIPERTENSIÓN ARTERIAL
6. ENFERMEDAD PULMONAR OBSTR
7. CANCER DE PROSTATA
8. ENFERMEDAD RENAL CRONICA
9. CANCER DE MAMA
10. DIABETES MELLITUS TIPO II
[ 156 others ]
195 ( 35.7% )
42 ( 7.7% )
34 ( 6.2% )
16 ( 2.9% )
15 ( 2.7% )
11 ( 2.0% )
10 ( 1.8% )
8 ( 1.5% )
5 ( 0.9% )
5 ( 0.9% )
205 ( 37.5% )
0 (0.0%)
22 dx2 [character]
1. HIPERTENSION ARTERIAL
2. ENFERMEDAD RENAL CRONICA
3. DIABETES MELLITUS
4. HIPOTIROIDISMO
5. DIABETES MELLITUS TIPO II
6. ENFERMEDAD PULMONAR OBSTR
7. OSTEOPOROSIS
8. ASMA
9. GASTRITIS
10. OBESIDAD
[ 216 others ]
54 ( 14.5% )
18 ( 4.8% )
16 ( 4.3% )
11 ( 3.0% )
9 ( 2.4% )
7 ( 1.9% )
7 ( 1.9% )
4 ( 1.1% )
4 ( 1.1% )
4 ( 1.1% )
238 ( 64.0% )
174 (31.9%)
23 dx_oms [character]
1. Diabetes mellitus
2. Enfermedad cardiovascular
3. Enfermedad neoplásica
4. Enfermedad respiratoria c
102 ( 21.0% )
260 ( 53.6% )
104 ( 21.4% )
19 ( 3.9% )
61 (11.2%)
24 dx_oms_ca [character]
1. Cancer
2. No oncologica
104 ( 19.0% )
442 ( 81.0% )
0 (0.0%)
25 fecha_dx [numeric]
Mean (sd) : 2011.5 (10.4)
min ≤ med ≤ max:
1960 ≤ 2014 ≤ 2022
IQR (CV) : 11 (0)
42 distinct values 0 (0.0%)
26 charlson [numeric]
Mean (sd) : 1.2 (1.2)
min ≤ med ≤ max:
0 ≤ 1 ≤ 8
IQR (CV) : 2 (1)
0 : 169 ( 31.0% )
1 : 173 ( 31.7% )
2 : 148 ( 27.1% )
3 : 39 ( 7.1% )
4 : 9 ( 1.6% )
6 : 6 ( 1.1% )
7 : 1 ( 0.2% )
8 : 1 ( 0.2% )
0 (0.0%)
27 tratam [character]
1. No
2. Si tengo tratamiento
36 ( 6.6% )
510 ( 93.4% )
0 (0.0%)
28 onco [character]
1. No
2. Si
426 ( 78.0% )
120 ( 22.0% )
0 (0.0%)
29 onco_estad [character]
1. Desconocido
2. I
3. II
4. III
5. IV
6. No aplica
32 ( 26.7% )
7 ( 5.8% )
18 ( 15.0% )
18 ( 15.0% )
33 ( 27.5% )
12 ( 10.0% )
426 (78.0%)
30 onco_meta [character]
1. Ausentes
2. Desconocido
3. No aplica
4. Presentes
33 ( 27.5% )
51 ( 42.5% )
3 ( 2.5% )
33 ( 27.5% )
426 (78.0%)
31 onco_qx [character]
1. Checked
2. Unchecked
53 ( 9.7% )
493 ( 90.3% )
0 (0.0%)
32 onco_radio [character]
1. Checked
2. Unchecked
20 ( 3.7% )
526 ( 96.3% )
0 (0.0%)
33 onco_cp [character]
1. Checked
2. Unchecked
26 ( 4.8% )
520 ( 95.2% )
0 (0.0%)
34 onco_cx [character]
1. Checked
2. Unchecked
44 ( 8.1% )
502 ( 91.9% )
0 (0.0%)
35 onco_inm [character]
1. Checked
2. Unchecked
10 ( 1.8% )
536 ( 98.2% )
0 (0.0%)
36 onco_alt [character]
1. Checked
2. Unchecked
19 ( 3.5% )
527 ( 96.5% )
0 (0.0%)
37 onco_no [character]
1. Checked
2. Unchecked
25 ( 4.6% )
521 ( 95.4% )
0 (0.0%)
38 ecog [character]
1. 0
2. 1
3. 2
4. 3
5. 4
6. Desconocido
7. No aplica
11 ( 9.2% )
32 ( 26.7% )
30 ( 25.0% )
32 ( 26.7% )
13 ( 10.8% )
1 ( 0.8% )
1 ( 0.8% )
426 (78.0%)
39 karno [numeric]
Mean (sd) : 74.5 (18.6)
min ≤ med ≤ max:
10 ≤ 80 ≤ 100
IQR (CV) : 30 (0.2)
14 distinct values 0 (0.0%)
40 sarc1 [character]
1. Alguna
2. Mucha o incapaz
3. Ninguna
190 ( 34.8% )
150 ( 27.5% )
206 ( 37.7% )
0 (0.0%)
41 sarc2 [character]
1. Alguna
2. Mucha, usando auxiliares
3. Ninguna
168 ( 30.8% )
132 ( 24.2% )
246 ( 45.1% )
0 (0.0%)
42 sarc3 [character]
1. Alguna
2. Mucha, o incapaz sin ayud
3. Ninguna
181 ( 33.2% )
117 ( 21.4% )
248 ( 45.4% )
0 (0.0%)
43 sarc4 [character]
1. Alguna
2. Mucha o incapaz
3. Ninguna
214 ( 39.2% )
177 ( 32.4% )
155 ( 28.4% )
0 (0.0%)
44 sarc5 [character]
1. 1 a 3 caídas
2. 4 o más caídas
3. Ninguna
199 ( 36.4% )
22 ( 4.0% )
325 ( 59.5% )
0 (0.0%)
45 sarcf [logical]
All NA's
546 (100.0%)
46 ...47 [character]
1. No
2. Si
70 ( 12.8% )
476 ( 87.2% )
0 (0.0%)
47 ...48 [character]
1. No
2. Si
314 ( 57.5% )
232 ( 42.5% )
0 (0.0%)
48 ...49 [character]
1. No
2. Si
276 ( 50.5% )
270 ( 49.5% )
0 (0.0%)
49 ...50 [character]
1. No
2. Si
399 ( 73.1% )
147 ( 26.9% )
0 (0.0%)
50 ...51 [character]
1. No
2. Si
462 ( 84.6% )
84 ( 15.4% )
0 (0.0%)
51 ...52 [character]
1. No
2. Si
49 ( 9.0% )
495 ( 91.0% )
2 (0.4%)
52 ...53 [character]
1. No
2. Si
167 ( 53.5% )
145 ( 46.5% )
234 (42.9%)
53 s2 [character]
1. Bastante
2. Mucho
3. Nada
4. Un poco
188 ( 34.4% )
124 ( 22.7% )
123 ( 22.5% )
111 ( 20.3% )
0 (0.0%)
54 s3 [character]
1. Bastante
2. Mucho
3. Nada
4. Un poco
53 ( 9.7% )
10 ( 1.8% )
326 ( 59.7% )
157 ( 28.8% )
0 (0.0%)
55 s4 [character]
1. Bastante
2. Mucho
3. Nada
4. Un poco
64 ( 11.7% )
27 ( 4.9% )
293 ( 53.7% )
162 ( 29.7% )
0 (0.0%)
56 s5 [character]
1. Bastante
2. Mucho
3. Nada
4. Un poco
88 ( 16.2% )
31 ( 5.7% )
284 ( 52.2% )
141 ( 25.9% )
2 (0.4%)
57 s6 [character]
1. Bastante
2. Mucho
3. Nada
4. Un poco
27 ( 4.9% )
4 ( 0.7% )
474 ( 86.8% )
41 ( 7.5% )
0 (0.0%)
58 s7 [character]
1. Bastante
2. Mucho
3. Nada
4. Un poco
80 ( 14.7% )
16 ( 2.9% )
310 ( 56.8% )
140 ( 25.6% )
0 (0.0%)
59 s8 [character]
1. Bastante
2. Mucho
3. Nada
4. Un poco
75 ( 13.8% )
13 ( 2.4% )
311 ( 57.1% )
146 ( 26.8% )
1 (0.2%)
60 s9 [character]
1. Bastante
2. Mucho
3. Nada
4. Un poco
78 ( 14.3% )
21 ( 3.8% )
287 ( 52.6% )
160 ( 29.3% )
0 (0.0%)
61 s10 [character]
1. Bastante
2. Mucho
3. Nada
4. Un poco
52 ( 9.5% )
22 ( 4.0% )
353 ( 64.7% )
119 ( 21.8% )
0 (0.0%)
62 s11 [character]
1. Bastante
2. Mucho
3. Nada
4. Un poco
99 ( 18.1% )
36 ( 6.6% )
232 ( 42.5% )
179 ( 32.8% )
0 (0.0%)
63 s12 [character]
1. Bastante
2. Mucho
3. Nada
4. Un poco
45 ( 8.2% )
20 ( 3.7% )
380 ( 69.6% )
101 ( 18.5% )
0 (0.0%)
64 s13 [character]
1. Bastante
2. Mucho
3. Nada
4. Un poco
156 ( 28.6% )
48 ( 8.8% )
167 ( 30.6% )
174 ( 31.9% )
1 (0.2%)
65 s14 [character]
1. Bastante
2. Mucho
3. Nada
4. Un poco
181 ( 33.2% )
55 ( 10.1% )
118 ( 21.6% )
192 ( 35.2% )
0 (0.0%)
66 s15 [character]
1. Bastante
2. Mucho
3. Nada
4. Un poco
134 ( 24.5% )
63 ( 11.5% )
174 ( 31.9% )
175 ( 32.1% )
0 (0.0%)
67 s16 [character]
1. Bastante
2. Mucho
3. Nada
4. Un poco
101 ( 18.5% )
24 ( 4.4% )
223 ( 40.8% )
198 ( 36.3% )
0 (0.0%)
68 s17 [character]
1. Bastante
2. Mucho
3. Nada
4. Un poco
105 ( 19.3% )
26 ( 4.8% )
263 ( 48.3% )
151 ( 27.7% )
1 (0.2%)
69 s18 [character]
1. Bastante
2. Mucho
3. Nada
4. Un poco
124 ( 22.7% )
35 ( 6.4% )
207 ( 37.9% )
180 ( 33.0% )
0 (0.0%)
70 s19 [character]
1. Bastante
2. Mucho
3. Nada
4. Un poco
22 ( 4.0% )
11 ( 2.0% )
426 ( 78.0% )
87 ( 15.9% )
0 (0.0%)
71 s20 [character]
1. Bastante
2. Mucho
3. Nada
4. Un poco
91 ( 16.7% )
32 ( 5.9% )
297 ( 54.4% )
126 ( 23.1% )
0 (0.0%)
72 s21 [character]
1. Bastante
2. Mucho
3. Nada
4. Un poco
122 ( 22.3% )
32 ( 5.9% )
199 ( 36.4% )
193 ( 35.3% )
0 (0.0%)
73 s22 [character]
1. Bastante
2. Mucho
3. Nada
4. Un poco
149 ( 27.3% )
58 ( 10.6% )
221 ( 40.5% )
118 ( 21.6% )
0 (0.0%)
74 s23 [character]
1. Bastante
2. Mucho
3. Nada
4. Un poco
157 ( 28.8% )
41 ( 7.5% )
143 ( 26.2% )
205 ( 37.5% )
0 (0.0%)
75 s24 [character]
1. Bastante
2. Mucho
3. Nada
4. Un poco
135 ( 24.7% )
61 ( 11.2% )
152 ( 27.8% )
198 ( 36.3% )
0 (0.0%)
76 s25 [character]
1. Bastante
2. Mucho
3. Nada
4. Un poco
83 ( 15.2% )
19 ( 3.5% )
304 ( 55.7% )
140 ( 25.6% )
0 (0.0%)
77 s26 [character]
1. Bastante
2. Mucho
3. Nada
4. Un poco
55 ( 10.1% )
19 ( 3.5% )
354 ( 64.8% )
118 ( 21.6% )
0 (0.0%)
78 s27 [character]
1. Bastante
2. Mucho
3. Nada
4. Un poco
65 ( 11.9% )
29 ( 5.3% )
343 ( 62.9% )
108 ( 19.8% )
1 (0.2%)
79 s28 [character]
1. Bastante
2. Mucho
3. Nada
4. Un poco
91 ( 16.7% )
32 ( 5.9% )
266 ( 48.7% )
157 ( 28.8% )
0 (0.0%)
80 s29 [character]
1. Bastante
2. Mucho
3. Nada
4. Un poco
38 ( 7.0% )
13 ( 2.4% )
436 ( 79.9% )
59 ( 10.8% )
0 (0.0%)
81 s30 [character]
1. Bastante
2. Mucho
3. Nada
4. Un poco
20 ( 3.7% )
3 ( 0.6% )
483 ( 88.8% )
38 ( 7.0% )
2 (0.4%)
82 s31 [character]
1. Bastante
2. Mucho
3. Nada
4. Un poco
41 ( 7.5% )
46 ( 8.4% )
394 ( 72.3% )
64 ( 11.7% )
1 (0.2%)
83 s32 [character]
1. Bastante
2. Mucho
3. Nada
4. Un poco
84 ( 15.4% )
22 ( 4.0% )
281 ( 51.5% )
159 ( 29.1% )
0 (0.0%)
84 s33 [character]
1. Bastante
2. Mucho
3. Nada
4. Un poco
31 ( 5.7% )
9 ( 1.6% )
372 ( 68.1% )
134 ( 24.5% )
0 (0.0%)
85 s34 [character]
1. Bastante
2. Mucho
3. Nada
4. Un poco
190 ( 34.8% )
73 ( 13.4% )
151 ( 27.7% )
132 ( 24.2% )
0 (0.0%)
86 s35 [character]
1. Bastante
2. Mucho
3. Nada
4. Un poco
172 ( 31.5% )
86 ( 15.8% )
164 ( 30.0% )
124 ( 22.7% )
0 (0.0%)
87 s36 [character]
1. Bastante
2. Mucho
3. Nada
4. Un poco
145 ( 26.6% )
86 ( 15.8% )
181 ( 33.2% )
134 ( 24.5% )
0 (0.0%)
88 s37 [character]
1. Bastante
2. Mucho
3. Nada
4. Un poco
84 ( 15.4% )
29 ( 5.3% )
232 ( 42.5% )
201 ( 36.8% )
0 (0.0%)
89 s38 [character]
1. Bastante
2. Mucho
3. Nada
4. Un poco
165 ( 30.2% )
92 ( 16.8% )
146 ( 26.7% )
143 ( 26.2% )
0 (0.0%)
90 s39 [character]
1. Bastante
2. Mucho
3. Nada
4. Un poco
44 ( 8.1% )
28 ( 5.1% )
373 ( 68.3% )
101 ( 18.5% )
0 (0.0%)
91 s40 [character]
1. Bastante
2. Mucho
3. Nada
4. Un poco
55 ( 10.1% )
33 ( 6.0% )
314 ( 57.5% )
144 ( 26.4% )
0 (0.0%)
92 s41 [character]
1. Bastante
2. Mucho
3. Nada
4. Un poco
123 ( 22.5% )
53 ( 9.7% )
195 ( 35.7% )
175 ( 32.1% )
0 (0.0%)
93 s42 [character]
1. Bastante
2. Mucho
3. Nada
4. Un poco
122 ( 22.3% )
52 ( 9.5% )
209 ( 38.3% )
163 ( 29.9% )
0 (0.0%)
94 ...95 [character]
1. No
2. Si
281 ( 51.5% )
265 ( 48.5% )
0 (0.0%)
95 ...96 [character]
1. No
2. Si
251 ( 46.1% )
294 ( 53.9% )
1 (0.2%)
96 ...97 [character]
1. No
2. Si
123 ( 22.5% )
423 ( 77.5% )
0 (0.0%)
97 ...98 [character]
1. No
2. Si
135 ( 24.7% )
411 ( 75.3% )
0 (0.0%)
98 ...99 [character]
1. No
2. Si
116 ( 21.3% )
429 ( 78.7% )
1 (0.2%)
99 ...100 [character]
1. No
2. Si
246 ( 45.2% )
298 ( 54.8% )
2 (0.4%)
100 ...101 [character]
1. No
2. Si
309 ( 56.8% )
235 ( 43.2% )
2 (0.4%)
101 ...102 [character]
1. No
2. Si
198 ( 64.1% )
111 ( 35.9% )
237 (43.4%)
102 ...103 [character]
1. NINGUNO
2. NO
3. NINGUNA
4. NO. A VECES ME PREOCUPA Q
5. ¿CÓMO VA A TERMINAR ESTO?
6. ¿CUAL ES MI PRONTOSTICO?
7. ¿QUÉ IMPACTO HAN TENIDO E
8. ¿QUÉ PASA CON LA ENFERMED
9. ¿QUE VA A PASAR CONMIGO?
10. A LOS PACIENTES LES VULNE
[ 202 others ]
87 ( 23.1% )
58 ( 15.4% )
22 ( 5.8% )
2 ( 0.5% )
1 ( 0.3% )
1 ( 0.3% )
1 ( 0.3% )
1 ( 0.3% )
1 ( 0.3% )
1 ( 0.3% )
202 ( 53.6% )
169 (31.0%)
103 ...104 [character]
1. NINGUNO
2. NINGUNA
3. ME GUSTARÍA SABER MÁS SOB
4. ¿ CUÁNDO VOLVERÉ A TRABAJ
5. ¿A FUTURO QUÉ VA A PASAR?
6. ¿CÓMO COSTEAR LOS GASTOS
7. ¿CÓMO QUEDÓ FUNCIONANDO M
8. ¿CÓMO SALIERON LOS EXAMEN
9. ¿CÓMO SALIERON LOS EXAMEN
10. ¿COMO SERÁ LA CIRUGÍA?
[ 102 others ]
133 ( 46.0% )
45 ( 15.6% )
2 ( 0.7% )
1 ( 0.3% )
1 ( 0.3% )
1 ( 0.3% )
1 ( 0.3% )
1 ( 0.3% )
1 ( 0.3% )
1 ( 0.3% )
102 ( 35.3% )
257 (47.1%)
104 ...105 [character]
1. ¿CÓMO HAN SALIDO LOS EXAM
2. ¿CÓMO PUEDO CAMBIAR DE PO
3. ¿CUÁL ES MI DIAGNÓSTICO?
4. ¿CUÁL VA A SER EL TRATAMI
5. ¿CUANDO LE DARÁN SALIDA?
6. ¿LE VAN A RETIRAR ALGUNO
7. ¿POR QUÉ PASÓ TANTO TIEMP
8. ¿QUE PODRÍA HACER EN LA C
9. ¿SI EL MEDICAMENTE NO SE
10. A DONDE LLEVO EL TENSIOME
[ 14 others ]
1 ( 4.2% )
1 ( 4.2% )
1 ( 4.2% )
1 ( 4.2% )
1 ( 4.2% )
1 ( 4.2% )
1 ( 4.2% )
1 ( 4.2% )
1 ( 4.2% )
1 ( 4.2% )
14 ( 58.3% )
522 (95.6%)
105 ...106 [character]
1. ¿CUÁL ES LA MÁS QUE LE AC
2. CUAL ES EL PROPOSITO DE L
3. CUAL SERIA EL PROCESO A S
4. EL PIE ESTÁ VOLANDO, NO L
5. LA TERAPEUTA LE PREOCUPAB
6. QUE TODO SER HUMANO QUE E
1 ( 16.7% )
1 ( 16.7% )
1 ( 16.7% )
1 ( 16.7% )
1 ( 16.7% )
1 ( 16.7% )
540 (98.9%)
106 ...107 [numeric]
Mean (sd) : 5.6 (2.9)
min ≤ med ≤ max:
0 ≤ 6 ≤ 10
IQR (CV) : 4 (0.5)
11 distinct values 1 (0.2%)
107 ...108 [character] 1. Complete
545 ( 100.0% )
1 (0.2%)

Generated by summarytools 1.1.5 (R version 4.5.2)
2026-10-26

3. Recodificación

SARC-F

Cada ítem del SARC-F se puntúa de 0 a 2: Ninguna = 0, Alguna o 1 a 3 caídas = 1, y las categorías de mayor dificultad (Mucha o incapaz, 4 o más caídas) = 2.

Código
data <- data %>%
  mutate(across(
    all_of(items_sarcf),
    ~ case_when(
      .x == "Ninguna"                     ~ 0,
      .x %in% c("Alguna", "1 a 3 caídas") ~ 1,
      !is.na(.x)                          ~ 2
    )
  ))

SPARC

Los ítems SPARC (s2–s42) se convierten a una escala numérica de 0 a 3: Nada = 0, Un poco = 1, Bastante = 2, Mucho = 3.

Código
data <- data %>%
  mutate(across(
    all_of(items_sparc),
    ~ case_match(.x, "Nada" ~ 0, "Un poco" ~ 1, "Bastante" ~ 2, "Mucho" ~ 3)
  ))

Covariables

Las variables categóricas se convierten a factor y se fija su categoría de referencia para los modelos. transpor viene como texto y se pasa a número.

Código
data <- data %>%
  mutate(
    dx_oms_ca = relevel(factor(dx_oms_ca), ref = "No oncologica"),
    educa     = relevel(factor(educa),     ref = "Ninguno"),
    genero    = relevel(factor(genero),    ref = "Masculino"),
    procede   = relevel(factor(procede),   ref = "Urbana"),
    transpor  = as.numeric(transpor)
  )

4. Variables derivadas

Puntaje SARC-F y sarcopenia probable

sarc_tot es la suma de los 5 ítems (rango 0–10). sarc_tot_cat clasifica como Con Sarcopenia a los pacientes con sarc_tot > 4. Se crea como factor desde el inicio para que tablas, gráficos y modelos usen las mismas etiquetas.

Código
data <- data %>%
  mutate(
    sarc_tot     = rowSums(across(all_of(items_sarcf)), na.rm = TRUE),
    sarc_tot_cat = factor(
      if_else(sarc_tot > 4, "Con Sarcopenia", "Sin Sarcopenia"),
      levels = c("Sin Sarcopenia", "Con Sarcopenia")
    )
  )

count(data, sarc_tot_cat)

Puntajes SPARC por dominio

Para cada dominio se calcula:

  • el puntaje bruto (sparc_*): suma de sus ítems;
  • el puntaje ponderado (sparc_*_p): el bruto expresado como porcentaje de su máximo posible (0–100), para que los dominios sean comparables entre sí.

Los ítems faltantes (9 respuestas en toda la base) se tratan como 0.

Código
for (i in seq_len(nrow(dominios))) {
  bruto <- rowSums(data[dominios$items[[i]]], na.rm = TRUE)
  data[[dominios$var[i]]]   <- bruto
  data[[dominios$var_p[i]]] <- round(bruto / dominios$maximo[i] * 100, 1)
}

data %>%
  select(all_of(dominios$var_p)) %>%
  summary()
  sparc_fis_p     sparc_psic_p     sparc_rel_p      sparc_inde_p   
 Min.   : 0.00   Min.   : 0.000   Min.   :  0.00   Min.   :  0.00  
 1st Qu.:15.90   1st Qu.: 8.325   1st Qu.:  0.00   1st Qu.: 11.10  
 Median :25.40   Median :18.500   Median : 16.70   Median : 44.40  
 Mean   :26.87   Mean   :22.005   Mean   : 18.81   Mean   : 43.53  
 3rd Qu.:34.90   3rd Qu.:29.600   3rd Qu.: 33.30   3rd Qu.: 66.70  
 Max.   :79.40   Max.   :96.300   Max.   :100.00   Max.   :100.00  
  sparc_fami_p     sparc_tra_p    
 Min.   :  0.00   Min.   :  0.00  
 1st Qu.:  8.30   1st Qu.:  0.00  
 Median : 25.00   Median : 33.30  
 Mean   : 27.95   Mean   : 34.89  
 3rd Qu.: 41.70   3rd Qu.: 66.70  
 Max.   :100.00   Max.   :100.00  

Puntaje SPARC total

sparc_total_p es la suma de los 6 puntajes ponderados, de modo que cada dominio pesa lo mismo. sparc_total_st reescala ese total a 0–100 usando el mínimo y el máximo observados en la muestra. Este es el desenlace de los modelos de la sección 9.

Código
data <- data %>%
  mutate(
    sparc_total_p  = rowSums(across(all_of(dominios$var_p))),
    sparc_total_st = (sparc_total_p - min(sparc_total_p)) /
                     (max(sparc_total_p) - min(sparc_total_p)) * 100
  )

summary(data$sparc_total_st)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
   0.00   19.87   32.61   34.85   47.06  100.00 

Base en formato largo

sparc_largo tiene una fila por paciente y dominio ponderado. items_largo tiene una fila por paciente e ítem, con su respuesta Likert. Ambas se reutilizan en los gráficos y tablas siguientes.

Código
sparc_largo <- data %>%
  select(id, sarc_tot_cat, dx_oms_ca, all_of(dominios$var_p)) %>%
  pivot_longer(all_of(dominios$var_p), names_to = "dominio", values_to = "puntaje") %>%
  mutate(dominio = factor(dominio, levels = dominios$var_p, labels = dominios$nombre))

items_largo <- data %>%
  select(id, sarc_tot_cat, all_of(items_sparc)) %>%
  pivot_longer(all_of(items_sparc), names_to = "item", values_to = "valor") %>%
  filter(!is.na(valor)) %>%
  left_join(
    dominios %>% select(nombre, items) %>% unnest(items),
    by = c("item" = "items")
  ) %>%
  rename(dominio = nombre) %>%
  mutate(
    item      = factor(item, levels = items_sparc),
    valor     = factor(valor, levels = 0:3, labels = names(col_likert)),
    necesidad = factor(
      if_else(valor == "Nada", "Sin necesidades", "Presencia de necesidades"),
      levels = c("Sin necesidades", "Presencia de necesidades")
    )
  )

5. Exploración de los puntajes SPARC

Distribución de los puntajes ponderados de cada dominio: violín (forma de la distribución) con boxplot superpuesto (mediana y RIC).

Código
ggplot(sparc_largo, aes(x = dominio, y = puntaje, fill = dominio)) +
  geom_violin(trim = TRUE, color = "grey", linewidth = 0.4) +
  geom_boxplot(width = 0.15, fill = "white", outlier.shape = NA, linewidth = 0.3) +
  scale_fill_manual(values = col_dominios) +
  scale_y_continuous(limits = c(0, NA), expand = expansion(mult = c(0, 0.1))) +
  labs(x = NULL, y = "Puntaje ponderado (%)") +
  theme_classic(base_size = 12) +
  theme(legend.position = "none", axis.text.x = element_text(angle = 45, hjust = 1))
Figura 1

Comorbilidad: distribución del índice de Charlson.

Código
summary(data$charlson)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  0.000   0.000   1.000   1.233   2.000   8.000 
Código
ggplot(data, aes(x = charlson)) +
  geom_histogram(binwidth = 1, fill = "lightblue", color = "black") +
  labs(x = "Índice de Charlson", y = "Pacientes")
Figura 2

6. Objetivo 1 — Características sociodemográficas

Tabla 1, por grupo de sarcopenia. Las variables continuas se resumen con mediana (p25, p75).

Código
data %>%
  tbl_summary(
    include   = c(genero, etnia, edad, charlson, dx_oms_ca, civil, religion,
                  educa, procede, convivi, transpor),
    by        = sarc_tot_cat,
    type      = list(charlson ~ "continuous"),
    statistic = list(all_continuous() ~ "{median} ({p25}, {p75})"),
    missing   = "no",
    sort      = all_categorical() ~ "frequency"
  ) %>%
  add_n() %>%
  add_overall()
Characteristic N Overall
N = 5461
Sin Sarcopenia
N = 3251
Con Sarcopenia
N = 2211
genero 546


    Femenino
329 (60%) 195 (60%) 134 (61%)
    Masculino
217 (40%) 130 (40%) 87 (39%)
etnia 546


    Mestizo
411 (75%) 246 (76%) 165 (75%)
    Blanco
71 (13%) 45 (14%) 26 (12%)
    Indígena
36 (6.6%) 19 (5.8%) 17 (7.7%)
    Afrocolombiano
28 (5.1%) 15 (4.6%) 13 (5.9%)
edad 546 66 (56, 76) 63 (54, 74) 71 (59, 81)
charlson 546 1.00 (0.00, 2.00) 1.00 (0.00, 2.00) 1.00 (0.00, 2.00)
dx_oms_ca 546


    No oncologica
442 (81%) 266 (82%) 176 (80%)
    Cancer
104 (19%) 59 (18%) 45 (20%)
civil 546


    Casado
198 (36%) 128 (39%) 70 (32%)
    Unión libre
136 (25%) 82 (25%) 54 (24%)
    Soltero
105 (19%) 66 (20%) 39 (18%)
    Viudo
83 (15%) 37 (11%) 46 (21%)
    Separado
24 (4.4%) 12 (3.7%) 12 (5.4%)
religion 546


    Católico
450 (82%) 265 (82%) 185 (84%)
    Cristiano
63 (12%) 39 (12%) 24 (11%)
    Otro
26 (4.8%) 17 (5.2%) 9 (4.1%)
    Agnóstico
4 (0.7%) 3 (0.9%) 1 (0.5%)
    Ateo
3 (0.5%) 1 (0.3%) 2 (0.9%)
educa 546


    Primaria
230 (42%) 123 (38%) 107 (48%)
    Bachillerato
166 (30%) 115 (35%) 51 (23%)
    Ninguno
88 (16%) 41 (13%) 47 (21%)
    Técnico
31 (5.7%) 20 (6.2%) 11 (5.0%)
    Universitario
31 (5.7%) 26 (8.0%) 5 (2.3%)
procede 546


    Urbana
344 (63%) 208 (64%) 136 (62%)
    Rural
202 (37%) 117 (36%) 85 (38%)
convivi 546 3.00 (2.00, 4.00) 3.00 (2.00, 4.00) 3.00 (2.00, 4.00)
transpor 546 0.50 (0.25, 1.00) 0.50 (0.25, 1.00) 0.50 (0.20, 1.00)
1 n (%); Median (Q1, Q3)

7. Objetivo 2 — Prevalencia de sarcopenia

Distribución del puntaje SARC-F

Código
ggplot(data, aes(x = sarc_tot)) +
  geom_histogram(aes(y = after_stat(density)), binwidth = 1,
                 fill = "lightblue", color = "black") +
  geom_density(color = "red", linewidth = 1) +
  geom_vline(xintercept = 4.5, linetype = "dashed") +
  scale_x_continuous(breaks = 0:10) +
  labs(x = "Puntaje SARC-F", y = "Densidad",
       caption = "Línea discontinua: punto de corte (> 4)")
Figura 3

Prevalencia global (IC95% de Wilson)

Código
data %>%
  tbl_summary(
    include   = sarc_tot_cat,
    missing   = "no",
    statistic = all_categorical() ~ "{n} ({p}%)"
  ) %>%
  add_ci(
    method  = list(all_categorical() ~ "wilson"),
    pattern = "{stat} (IC95%: {ci})"
  )
Characteristic N = 546 (IC95%: 95% CI)1
sarc_tot_cat
    Sin Sarcopenia 325 (60%) (IC95%: 55%, 64%)
    Con Sarcopenia 221 (40%) (IC95%: 36%, 45%)
1 n (%)
Abbreviation: CI = Confidence Interval

Prevalencia según tipo de diagnóstico

Código
data %>%
  tbl_summary(
    include   = c(sarc_tot, sarc_tot_cat),
    by        = dx_oms_ca,
    type      = list(sarc_tot ~ "continuous"),
    statistic = list(all_continuous() ~ "{median} ({p25}, {p75})",
                     all_categorical() ~ "{n} ({p}%)"),
    missing   = "no"
  ) %>%
  add_ci(method = list(all_categorical() ~ "wilson")) %>%
  add_n() %>%
  add_overall()
Characteristic N Overall
N = 5461
No oncologica
N = 4421
95% CI Cancer
N = 1041
95% CI
sarc_tot 546 4.00 (1.00, 6.00) 3.50 (1.00, 6.00) 3.6, 4.2 4.00 (2.00, 7.00) 3.6, 4.7
sarc_tot_cat 546




    Sin Sarcopenia
325 (60%) 266 (60%) 55%, 65% 59 (57%) 47%, 66%
    Con Sarcopenia
221 (40%) 176 (40%) 35%, 45% 45 (43%) 34%, 53%
1 Median (Q1, Q3); n (%)
Abbreviation: CI = Confidence Interval
Código
ggplot(data, aes(x = sarc_tot, fill = dx_oms_ca)) +
  geom_density(alpha = 0.5) +
  labs(x = "Puntaje SARC-F", y = "Densidad", fill = "Diagnóstico")
Figura 4

8. Objetivo 3 — Necesidades no satisfechas (SPARC)

Distribución de respuestas por ítem

Para cada ítem: n (%) de pacientes en cada nivel de respuesta.

Código
items_largo %>%
  count(item, valor, .drop = FALSE) %>%
  group_by(item) %>%
  mutate(stat = paste0(n, " (", round(100 * n / sum(n), 1), "%)")) %>%
  ungroup() %>%
  select(-n) %>%
  pivot_wider(names_from = valor, values_from = stat) %>%
  gt() %>%
  cols_label(item = "Ítem")
Ítem Nada Un poco Bastante Mucho
s2 123 (22.5%) 111 (20.3%) 188 (34.4%) 124 (22.7%)
s3 326 (59.7%) 157 (28.8%) 53 (9.7%) 10 (1.8%)
s4 293 (53.7%) 162 (29.7%) 64 (11.7%) 27 (4.9%)
s5 284 (52.2%) 141 (25.9%) 88 (16.2%) 31 (5.7%)
s6 474 (86.8%) 41 (7.5%) 27 (4.9%) 4 (0.7%)
s7 310 (56.8%) 140 (25.6%) 80 (14.7%) 16 (2.9%)
s8 311 (57.1%) 146 (26.8%) 75 (13.8%) 13 (2.4%)
s9 287 (52.6%) 160 (29.3%) 78 (14.3%) 21 (3.8%)
s10 353 (64.7%) 119 (21.8%) 52 (9.5%) 22 (4%)
s11 232 (42.5%) 179 (32.8%) 99 (18.1%) 36 (6.6%)
s12 380 (69.6%) 101 (18.5%) 45 (8.2%) 20 (3.7%)
s13 167 (30.6%) 174 (31.9%) 156 (28.6%) 48 (8.8%)
s14 118 (21.6%) 192 (35.2%) 181 (33.2%) 55 (10.1%)
s15 174 (31.9%) 175 (32.1%) 134 (24.5%) 63 (11.5%)
s16 223 (40.8%) 198 (36.3%) 101 (18.5%) 24 (4.4%)
s17 263 (48.3%) 151 (27.7%) 105 (19.3%) 26 (4.8%)
s18 207 (37.9%) 180 (33%) 124 (22.7%) 35 (6.4%)
s19 426 (78%) 87 (15.9%) 22 (4%) 11 (2%)
s20 297 (54.4%) 126 (23.1%) 91 (16.7%) 32 (5.9%)
s21 199 (36.4%) 193 (35.3%) 122 (22.3%) 32 (5.9%)
s22 221 (40.5%) 118 (21.6%) 149 (27.3%) 58 (10.6%)
s23 143 (26.2%) 205 (37.5%) 157 (28.8%) 41 (7.5%)
s24 152 (27.8%) 198 (36.3%) 135 (24.7%) 61 (11.2%)
s25 304 (55.7%) 140 (25.6%) 83 (15.2%) 19 (3.5%)
s26 354 (64.8%) 118 (21.6%) 55 (10.1%) 19 (3.5%)
s27 343 (62.9%) 108 (19.8%) 65 (11.9%) 29 (5.3%)
s28 266 (48.7%) 157 (28.8%) 91 (16.7%) 32 (5.9%)
s29 436 (79.9%) 59 (10.8%) 38 (7%) 13 (2.4%)
s30 483 (88.8%) 38 (7%) 20 (3.7%) 3 (0.6%)
s31 394 (72.3%) 64 (11.7%) 41 (7.5%) 46 (8.4%)
s32 281 (51.5%) 159 (29.1%) 84 (15.4%) 22 (4%)
s33 372 (68.1%) 134 (24.5%) 31 (5.7%) 9 (1.6%)
s34 151 (27.7%) 132 (24.2%) 190 (34.8%) 73 (13.4%)
s35 164 (30%) 124 (22.7%) 172 (31.5%) 86 (15.8%)
s36 181 (33.2%) 134 (24.5%) 145 (26.6%) 86 (15.8%)
s37 232 (42.5%) 201 (36.8%) 84 (15.4%) 29 (5.3%)
s38 146 (26.7%) 143 (26.2%) 165 (30.2%) 92 (16.8%)
s39 373 (68.3%) 101 (18.5%) 44 (8.1%) 28 (5.1%)
s40 314 (57.5%) 144 (26.4%) 55 (10.1%) 33 (6%)
s41 195 (35.7%) 175 (32.1%) 123 (22.5%) 53 (9.7%)
s42 209 (38.3%) 163 (29.9%) 122 (22.3%) 52 (9.5%)

Prevalencia de necesidades por paciente

Un paciente tiene una necesidad en un dominio si responde algo distinto de Nada en al menos un ítem de ese dominio. Esta es la prevalencia que responde al objetivo 3: la unidad de análisis es el paciente.

Código
necesidades_paciente <- data %>%
  transmute(
    sarc_tot_cat,
    cualquier = rowSums(across(all_of(items_sparc)), na.rm = TRUE) > 0,
    across(all_of(dominios$var), ~ .x > 0)
  )

necesidades_paciente %>%
  tbl_summary(
    include = -sarc_tot_cat,
    label   = c(
      list(cualquier ~ "Cualquier dominio"),
      map2(dominios$var, dominios$nombre, ~ as.formula(paste0(.x, " ~ '", .y, "'")))
    ),
    statistic = all_categorical() ~ "{n} ({p}%)",
    missing   = "no"
  ) %>%
  add_ci(method = list(all_categorical() ~ "wilson")) %>%
  modify_header(label = "**Pacientes con al menos una necesidad**")
Pacientes con al menos una necesidad N = 5461 95% CI
Cualquier dominio 545 (100%) 99%, 100%
Síntomas físicos 543 (99%) 98%, 100%
Temas psicológicos 509 (93%) 91%, 95%
Temas religiosos y espirituales 319 (58%) 54%, 63%
Independencia y actividad 446 (82%) 78%, 85%
Asuntos familiares y vida social 483 (88%) 85%, 91%
Tratamiento 390 (71%) 67%, 75%
1 n (%)
Abbreviation: CI = Confidence Interval

Proporción de respuestas con necesidad (ítem × paciente)

Esta tabla usa como unidad cada respuesta (546 pacientes × 41 ítems). Indica qué fracción de todas las respuestas reporta alguna necesidad; no es una prevalencia por paciente.

Código
ic <- binom.confint(
  x      = sum(items_largo$necesidad == "Presencia de necesidades"),
  n      = nrow(items_largo),
  method = "wilson"
)

items_largo %>%
  count(necesidad) %>%
  mutate(
    `n (%)` = paste0(n, " (", round(100 * n / sum(n), 1), "%)"),
    IC95    = if_else(
      necesidad == "Presencia de necesidades",
      paste0(round(ic$lower * 100, 1), "–", round(ic$upper * 100, 1), "%"),
      ""
    )
  ) %>%
  select(Estado = necesidad, `n (%)`, IC95) %>%
  gt()
Estado n (%) IC95
Sin necesidades 11161 (49.9%)
Presencia de necesidades 11216 (50.1%) 49.5–50.8%

Distribución tipo Likert por dominio

Los dominios se ordenan de mayor a menor proporción de respuestas Nada.

Código
likert_dominio <- items_largo %>%
  count(dominio, valor) %>%
  group_by(dominio) %>%
  mutate(
    prop      = n / sum(n),
    prop_nada = sum(prop[valor == "Nada"])
  ) %>%
  ungroup() %>%
  mutate(dominio = fct_reorder(dominio, prop_nada, .desc = TRUE))

Todas las categorías de respuesta:

Código
ggplot(likert_dominio, aes(x = dominio, y = prop, fill = valor)) +
  geom_col(position = position_fill(reverse = TRUE), width = 0.7) +
  coord_flip() +
  scale_y_continuous(labels = scales::percent) +
  scale_fill_manual(values = col_likert) +
  labs(x = NULL, y = "Porcentaje de respuestas", fill = "Nivel",
       title = "Distribución tipo Likert por dominios SPARC") +
  theme(axis.text.y = element_text(size = 11), legend.position = "bottom")
Figura 5

Solo las respuestas con necesidad (Un poco, Bastante, Mucho). La longitud de cada barra es la proporción de respuestas con alguna necesidad:

Código
ggplot(
  filter(likert_dominio, valor != "Nada"),
  aes(x = dominio, y = prop, fill = valor)
) +
  geom_col(position = position_stack(reverse = TRUE), width = 0.7) +
  coord_flip() +
  scale_y_continuous(limits = c(0, 1), breaks = seq(0, 1, 0.2),
                     labels = scales::percent, expand = c(0, 0)) +
  scale_fill_manual(values = col_likert[-1]) +
  labs(x = NULL, y = "Porcentaje de respuestas", fill = "Nivel",
       title = "Respuestas con necesidad por dominio SPARC") +
  theme(axis.text.y = element_text(size = 11), legend.position = "bottom")
Figura 6

Tablas por dominio (unidad: respuesta)

Código
items_largo %>%
  tbl_summary(
    by        = dominio,
    include   = valor,
    statistic = all_categorical() ~ "{p}%",
    missing   = "no"
  ) %>%
  modify_header(label = "**Nivel**") %>%
  bold_labels()
Nivel Asuntos familiares y vida social
N = 2,1841
Independencia y actividad
N = 1,6381
Síntomas físicos
N = 11,4611
Temas psicológicos
N = 4,9101
Temas religiosos y espirituales
N = 1,0921
Tratamiento
N = 1,0921
valor





    Nada 49% 30% 49% 59% 60% 37%
    Un poco 27% 24% 27% 22% 27% 31%
    Bastante 16% 31% 18% 14% 11% 22%
    Mucho 8.3% 15% 6.2% 5.4% 2.8% 9.6%
1
Código
items_largo %>%
  tbl_summary(
    by        = dominio,
    include   = necesidad,
    statistic = all_categorical() ~ "{n} ({p}%)",
    missing   = "no"
  ) %>%
  modify_header(label = "**Estado**") %>%
  bold_labels()
Estado Asuntos familiares y vida social
N = 2,1841
Independencia y actividad
N = 1,6381
Síntomas físicos
N = 11,4611
Temas psicológicos
N = 4,9101
Temas religiosos y espirituales
N = 1,0921
Tratamiento
N = 1,0921
necesidad





    Sin necesidades 1,065 (49%) 496 (30%) 5,668 (49%) 2,875 (59%) 653 (60%) 404 (37%)
    Presencia de necesidades 1,119 (51%) 1,142 (70%) 5,793 (51%) 2,035 (41%) 439 (40%) 688 (63%)
1 n (%)

9. Objetivo 3.1 — Necesidades según sarcopenia

Puntajes por dominio según diagnóstico y sarcopenia

Medianas (p25, p75). Los valores p corresponden a la prueba de Wilcoxon (Mann-Whitney).

Código
tabla_dominios_por <- function(grupo) {
  data %>%
    tbl_summary(
      include   = all_of(dominios$var_p),
      by        = {{ grupo }},
      label     = as.list(etiquetas_dominio),
      type      = all_of(dominios$var_p) ~ "continuous",
      statistic = all_continuous() ~ "{median} ({p25}, {p75})",
      missing   = "no"
    ) %>%
    add_n() %>%
    add_p() %>%
    add_overall()
}

tabla_dominios_por(dx_oms_ca)
Characteristic N Overall
N = 5461
No oncologica
N = 4421
Cancer
N = 1041
p-value2
Síntomas físicos 546 25 (16, 35) 24 (14, 33) 32 (24, 44) <0.001
Temas psicológicos 546 19 (7, 30) 15 (7, 30) 22 (15, 37) <0.001
Temas religiosos y espirituales 546 17 (0, 33) 17 (0, 33) 17 (0, 33) 0.002
Independencia y actividad 546 44 (11, 67) 44 (11, 67) 50 (22, 67) 0.2
Asuntos familiares y vida social 546 25 (8, 42) 25 (8, 42) 25 (8, 42) 0.8
Tratamiento 546 33 (0, 67) 33 (0, 50) 33 (17, 67) 0.004
1 Median (Q1, Q3)
2 Wilcoxon rank sum test
Código
tabla_dominios_por(sarc_tot_cat)
Characteristic N Overall
N = 5461
Sin Sarcopenia
N = 3251
Con Sarcopenia
N = 2211
p-value2
Síntomas físicos 546 25 (16, 35) 22 (13, 32) 30 (22, 41) <0.001
Temas psicológicos 546 19 (7, 30) 15 (7, 26) 22 (11, 37) <0.001
Temas religiosos y espirituales 546 17 (0, 33) 17 (0, 33) 17 (0, 33) 0.018
Independencia y actividad 546 44 (11, 67) 33 (11, 56) 56 (33, 67) <0.001
Asuntos familiares y vida social 546 25 (8, 42) 25 (8, 33) 25 (17, 42) <0.001
Tratamiento 546 33 (0, 67) 33 (0, 50) 33 (17, 67) <0.001
1 Median (Q1, Q3)
2 Wilcoxon rank sum test
Código
ggplot(sparc_largo, aes(x = sarc_tot_cat, y = puntaje, fill = sarc_tot_cat)) +
  geom_boxplot() +
  facet_wrap(~ dominio, scales = "free_y") +
  stat_compare_means(method = "wilcox.test", label = "p.format") +
  scale_fill_manual(values = col_sarc) +
  labs(x = NULL, y = "Puntaje SPARC (%)", fill = NULL,
       title = "Dominios SPARC según sarcopenia") +
  theme(legend.position = "bottom", strip.text = element_text(face = "bold"),
        axis.text.x = element_blank())
Figura 7

Normalidad de los puntajes

Con n = 546, la prueba de Shapiro-Wilk detecta desviaciones mínimas de la normalidad. Conviene interpretarla junto con los histogramas.

Código
ggplot(sparc_largo, aes(x = puntaje, fill = dominio)) +
  geom_histogram(bins = 20, color = "white") +
  facet_wrap(~ dominio, scales = "free") +
  scale_fill_manual(values = col_dominios) +
  labs(x = "Puntaje ponderado (%)", y = "Pacientes") +
  theme(legend.position = "none")

sparc_largo %>%
  group_by(dominio) %>%
  summarise(
    W = shapiro.test(puntaje)$statistic,
    p = shapiro.test(puntaje)$p.value
  ) %>%
  gt() %>%
  fmt_number(W, decimals = 3) %>%
  fmt_scientific(p, decimals = 2)
dominio W p
Síntomas físicos 0.973 1.41 × 10−8
Temas psicológicos 0.902 3.27 × 10−18
Temas religiosos y espirituales 0.830 1.16 × 10−23
Independencia y actividad 0.927 1.30 × 10−15
Asuntos familiares y vida social 0.915 6.24 × 10−17
Tratamiento 0.889 2.21 × 10−19
Figura 8
Figura 9

Puntaje SPARC total

Código
ggplot(data, aes(x = sparc_total_st)) +
  geom_histogram(bins = 25, fill = "lightblue", color = "black") +
  labs(x = "Puntaje total SPARC estandarizado (%)", y = "Pacientes")

ggplot(data, aes(sample = sparc_total_st)) +
  stat_qq() +
  stat_qq_line(color = "red") +
  labs(title = "Q-Q plot del puntaje total SPARC",
       x = "Cuantiles teóricos", y = "Cuantiles observados")

ggplot(data, aes(x = sarc_tot_cat, y = sparc_total_st, fill = sarc_tot_cat)) +
  geom_boxplot() +
  scale_fill_manual(values = col_sarc) +
  labs(x = NULL, y = "Puntaje total SPARC (%)") +
  theme(legend.position = "none")

ggplot(data, aes(x = sarc_tot, y = sparc_total_st)) +
  geom_jitter(alpha = 0.5, width = 0.2, color = "steelblue") +
  geom_smooth(method = "lm", color = "red", se = FALSE) +
  scale_x_continuous(breaks = 0:10) +
  labs(x = "Puntaje SARC-F", y = "Puntaje total SPARC (%)")
Figura 10
Figura 11
Figura 12
Figura 13

10. Modelos de regresión lineal

Modelo 1: crudo (puntaje SPARC total)

El coeficiente de sarc_tot_cat estima la diferencia media en el puntaje SPARC total estandarizado entre pacientes con y sin sarcopenia.

Código
data %>%
  tbl_summary(
    include   = sparc_total_st,
    by        = sarc_tot_cat,
    type      = list(sparc_total_st ~ "continuous"),
    statistic = all_continuous() ~ "{median} ({p25}, {p75})",
    missing   = "no"
  ) %>%
  add_n() %>%
  add_p() %>%
  add_overall()
Characteristic N Overall
N = 5461
Sin Sarcopenia
N = 3251
Con Sarcopenia
N = 2211
p-value2
sparc_total_st 546 33 (20, 47) 28 (16, 41) 39 (28, 56) <0.001
1 Median (Q1, Q3)
2 Wilcoxon rank sum test
Código
model1 <- lm(sparc_total_st ~ sarc_tot_cat, data = data)
tbl_regression(model1)
Characteristic Beta 95% CI p-value
sarc_tot_cat


    Sin Sarcopenia — —
    Con Sarcopenia 12 9.0, 15 <0.001
Abbreviation: CI = Confidence Interval
Código
model_performance(model1)
Código
check_model(model1)

Modelo 2: ajustado (puntaje SPARC total)

Diferencias ajustadas por diagnóstico, edad, sexo, estado funcional (Karnofsky) y comorbilidad (Charlson).

Código
covariables <- "dx_oms_ca + edad + genero + karno + charlson"

model2 <- lm(as.formula(paste("sparc_total_st ~ sarc_tot_cat +", covariables)), data = data)
tbl_regression(model2)
Characteristic Beta 95% CI p-value
sarc_tot_cat


    Sin Sarcopenia — —
    Con Sarcopenia 9.6 5.7, 14 <0.001
dx_oms_ca


    No oncologica — —
    Cancer 2.5 -1.9, 6.9 0.3
edad -0.24 -0.34, -0.13 <0.001
genero


    Masculino — —
    Femenino 3.0 -0.06, 6.1 0.055
karno -0.17 -0.28, -0.06 0.002
charlson 2.0 0.54, 3.5 0.007
Abbreviation: CI = Confidence Interval
Código
model_performance(model2)
Código
check_model(model2)

Modelos por dominio: crudos y ajustados

Un modelo para cada dominio ponderado. La tabla muestra solo el efecto de la sarcopenia. La columna Ajustado usa las mismas covariables del modelo 2.

Código
ajustar_dominio <- function(var_p, ajustado) {
  rhs <- if (ajustado) paste("sarc_tot_cat +", covariables) else "sarc_tot_cat"
  lm(as.formula(paste(var_p, "~", rhs)), data = data)
}

tabla_modelos_dominio <- function(ajustado) {
  map(dominios$var_p, \(v) {
    tbl_regression(ajustar_dominio(v, ajustado), include = sarc_tot_cat)
  }) %>%
    tbl_stack(group_header = dominios$nombre)
}

tbl_merge(
  list(tabla_modelos_dominio(FALSE), tabla_modelos_dominio(TRUE)),
  tab_spanner = c("**Crudo**", "**Ajustado**")
)
Characteristic
Crudo
Ajustado
Group Beta 95% CI p-value Group Beta 95% CI p-value
sarc_tot_cat Síntomas físicos


Síntomas físicos


sarc_tot_cat Síntomas físicos


Temas psicológicos


sarc_tot_cat Síntomas físicos


Temas religiosos y espirituales


sarc_tot_cat Síntomas físicos


Independencia y actividad


sarc_tot_cat Síntomas físicos


Asuntos familiares y vida social


sarc_tot_cat Síntomas físicos


Tratamiento


    Sin Sarcopenia Síntomas físicos — —
Síntomas físicos — —
    Sin Sarcopenia Síntomas físicos — —
Temas psicológicos — —
    Sin Sarcopenia Síntomas físicos — —
Temas religiosos y espirituales — —
    Sin Sarcopenia Síntomas físicos — —
Independencia y actividad — —
    Sin Sarcopenia Síntomas físicos — —
Asuntos familiares y vida social — —
    Sin Sarcopenia Síntomas físicos — —
Tratamiento — —
    Con Sarcopenia Síntomas físicos 10 7.8, 12 <0.001 Síntomas físicos 6.0 3.3, 8.7 <0.001
    Con Sarcopenia Síntomas físicos 10 7.8, 12 <0.001 Temas psicológicos 5.2 1.6, 8.7 0.005
    Con Sarcopenia Síntomas físicos 10 7.8, 12 <0.001 Temas religiosos y espirituales 5.2 0.70, 9.6 0.023
    Con Sarcopenia Síntomas físicos 10 7.8, 12 <0.001 Independencia y actividad 15 8.7, 22 <0.001
    Con Sarcopenia Síntomas físicos 10 7.8, 12 <0.001 Asuntos familiares y vida social 4.8 0.11, 9.5 0.045
    Con Sarcopenia Síntomas físicos 10 7.8, 12 <0.001 Tratamiento 12 5.3, 18 <0.001
sarc_tot_cat Temas psicológicos


Síntomas físicos


sarc_tot_cat Temas psicológicos


Temas psicológicos


sarc_tot_cat Temas psicológicos


Temas religiosos y espirituales


sarc_tot_cat Temas psicológicos


Independencia y actividad


sarc_tot_cat Temas psicológicos


Asuntos familiares y vida social


sarc_tot_cat Temas psicológicos


Tratamiento


    Sin Sarcopenia Temas psicológicos — —
Síntomas físicos — —
    Sin Sarcopenia Temas psicológicos — —
Temas psicológicos — —
    Sin Sarcopenia Temas psicológicos — —
Temas religiosos y espirituales — —
    Sin Sarcopenia Temas psicológicos — —
Independencia y actividad — —
    Sin Sarcopenia Temas psicológicos — —
Asuntos familiares y vida social — —
    Sin Sarcopenia Temas psicológicos — —
Tratamiento — —
    Con Sarcopenia Temas psicológicos 8.3 5.4, 11 <0.001 Síntomas físicos 6.0 3.3, 8.7 <0.001
    Con Sarcopenia Temas psicológicos 8.3 5.4, 11 <0.001 Temas psicológicos 5.2 1.6, 8.7 0.005
    Con Sarcopenia Temas psicológicos 8.3 5.4, 11 <0.001 Temas religiosos y espirituales 5.2 0.70, 9.6 0.023
    Con Sarcopenia Temas psicológicos 8.3 5.4, 11 <0.001 Independencia y actividad 15 8.7, 22 <0.001
    Con Sarcopenia Temas psicológicos 8.3 5.4, 11 <0.001 Asuntos familiares y vida social 4.8 0.11, 9.5 0.045
    Con Sarcopenia Temas psicológicos 8.3 5.4, 11 <0.001 Tratamiento 12 5.3, 18 <0.001
sarc_tot_cat Temas religiosos y espirituales


Síntomas físicos


sarc_tot_cat Temas religiosos y espirituales


Temas psicológicos


sarc_tot_cat Temas religiosos y espirituales


Temas religiosos y espirituales


sarc_tot_cat Temas religiosos y espirituales


Independencia y actividad


sarc_tot_cat Temas religiosos y espirituales


Asuntos familiares y vida social


sarc_tot_cat Temas religiosos y espirituales


Tratamiento


    Sin Sarcopenia Temas religiosos y espirituales — —
Síntomas físicos — —
    Sin Sarcopenia Temas religiosos y espirituales — —
Temas psicológicos — —
    Sin Sarcopenia Temas religiosos y espirituales — —
Temas religiosos y espirituales — —
    Sin Sarcopenia Temas religiosos y espirituales — —
Independencia y actividad — —
    Sin Sarcopenia Temas religiosos y espirituales — —
Asuntos familiares y vida social — —
    Sin Sarcopenia Temas religiosos y espirituales — —
Tratamiento — —
    Con Sarcopenia Temas religiosos y espirituales 4.0 0.52, 7.5 0.024 Síntomas físicos 6.0 3.3, 8.7 <0.001
    Con Sarcopenia Temas religiosos y espirituales 4.0 0.52, 7.5 0.024 Temas psicológicos 5.2 1.6, 8.7 0.005
    Con Sarcopenia Temas religiosos y espirituales 4.0 0.52, 7.5 0.024 Temas religiosos y espirituales 5.2 0.70, 9.6 0.023
    Con Sarcopenia Temas religiosos y espirituales 4.0 0.52, 7.5 0.024 Independencia y actividad 15 8.7, 22 <0.001
    Con Sarcopenia Temas religiosos y espirituales 4.0 0.52, 7.5 0.024 Asuntos familiares y vida social 4.8 0.11, 9.5 0.045
    Con Sarcopenia Temas religiosos y espirituales 4.0 0.52, 7.5 0.024 Tratamiento 12 5.3, 18 <0.001
sarc_tot_cat Independencia y actividad


Síntomas físicos


sarc_tot_cat Independencia y actividad


Temas psicológicos


sarc_tot_cat Independencia y actividad


Temas religiosos y espirituales


sarc_tot_cat Independencia y actividad


Independencia y actividad


sarc_tot_cat Independencia y actividad


Asuntos familiares y vida social


sarc_tot_cat Independencia y actividad


Tratamiento


    Sin Sarcopenia Independencia y actividad — —
Síntomas físicos — —
    Sin Sarcopenia Independencia y actividad — —
Temas psicológicos — —
    Sin Sarcopenia Independencia y actividad — —
Temas religiosos y espirituales — —
    Sin Sarcopenia Independencia y actividad — —
Independencia y actividad — —
    Sin Sarcopenia Independencia y actividad — —
Asuntos familiares y vida social — —
    Sin Sarcopenia Independencia y actividad — —
Tratamiento — —
    Con Sarcopenia Independencia y actividad 18 12, 23 <0.001 Síntomas físicos 6.0 3.3, 8.7 <0.001
    Con Sarcopenia Independencia y actividad 18 12, 23 <0.001 Temas psicológicos 5.2 1.6, 8.7 0.005
    Con Sarcopenia Independencia y actividad 18 12, 23 <0.001 Temas religiosos y espirituales 5.2 0.70, 9.6 0.023
    Con Sarcopenia Independencia y actividad 18 12, 23 <0.001 Independencia y actividad 15 8.7, 22 <0.001
    Con Sarcopenia Independencia y actividad 18 12, 23 <0.001 Asuntos familiares y vida social 4.8 0.11, 9.5 0.045
    Con Sarcopenia Independencia y actividad 18 12, 23 <0.001 Tratamiento 12 5.3, 18 <0.001
sarc_tot_cat Asuntos familiares y vida social


Síntomas físicos


sarc_tot_cat Asuntos familiares y vida social


Temas psicológicos


sarc_tot_cat Asuntos familiares y vida social


Temas religiosos y espirituales


sarc_tot_cat Asuntos familiares y vida social


Independencia y actividad


sarc_tot_cat Asuntos familiares y vida social


Asuntos familiares y vida social


sarc_tot_cat Asuntos familiares y vida social


Tratamiento


    Sin Sarcopenia Asuntos familiares y vida social — —
Síntomas físicos — —
    Sin Sarcopenia Asuntos familiares y vida social — —
Temas psicológicos — —
    Sin Sarcopenia Asuntos familiares y vida social — —
Temas religiosos y espirituales — —
    Sin Sarcopenia Asuntos familiares y vida social — —
Independencia y actividad — —
    Sin Sarcopenia Asuntos familiares y vida social — —
Asuntos familiares y vida social — —
    Sin Sarcopenia Asuntos familiares y vida social — —
Tratamiento — —
    Con Sarcopenia Asuntos familiares y vida social 7.2 3.5, 11 <0.001 Síntomas físicos 6.0 3.3, 8.7 <0.001
    Con Sarcopenia Asuntos familiares y vida social 7.2 3.5, 11 <0.001 Temas psicológicos 5.2 1.6, 8.7 0.005
    Con Sarcopenia Asuntos familiares y vida social 7.2 3.5, 11 <0.001 Temas religiosos y espirituales 5.2 0.70, 9.6 0.023
    Con Sarcopenia Asuntos familiares y vida social 7.2 3.5, 11 <0.001 Independencia y actividad 15 8.7, 22 <0.001
    Con Sarcopenia Asuntos familiares y vida social 7.2 3.5, 11 <0.001 Asuntos familiares y vida social 4.8 0.11, 9.5 0.045
    Con Sarcopenia Asuntos familiares y vida social 7.2 3.5, 11 <0.001 Tratamiento 12 5.3, 18 <0.001
sarc_tot_cat Tratamiento


Síntomas físicos


sarc_tot_cat Tratamiento


Temas psicológicos


sarc_tot_cat Tratamiento


Temas religiosos y espirituales


sarc_tot_cat Tratamiento


Independencia y actividad


sarc_tot_cat Tratamiento


Asuntos familiares y vida social


sarc_tot_cat Tratamiento


Tratamiento


    Sin Sarcopenia Tratamiento — —
Síntomas físicos — —
    Sin Sarcopenia Tratamiento — —
Temas psicológicos — —
    Sin Sarcopenia Tratamiento — —
Temas religiosos y espirituales — —
    Sin Sarcopenia Tratamiento — —
Independencia y actividad — —
    Sin Sarcopenia Tratamiento — —
Asuntos familiares y vida social — —
    Sin Sarcopenia Tratamiento — —
Tratamiento — —
    Con Sarcopenia Tratamiento 14 8.5, 19 <0.001 Síntomas físicos 6.0 3.3, 8.7 <0.001
    Con Sarcopenia Tratamiento 14 8.5, 19 <0.001 Temas psicológicos 5.2 1.6, 8.7 0.005
    Con Sarcopenia Tratamiento 14 8.5, 19 <0.001 Temas religiosos y espirituales 5.2 0.70, 9.6 0.023
    Con Sarcopenia Tratamiento 14 8.5, 19 <0.001 Independencia y actividad 15 8.7, 22 <0.001
    Con Sarcopenia Tratamiento 14 8.5, 19 <0.001 Asuntos familiares y vida social 4.8 0.11, 9.5 0.045
    Con Sarcopenia Tratamiento 14 8.5, 19 <0.001 Tratamiento 12 5.3, 18 <0.001
Abbreviation: CI = Confidence Interval

11. Objetivo 4 — Visualización: gráfico radar

Mediana del puntaje ponderado de cada dominio según sarcopenia.

Código
radar_group <- data %>%
  group_by(sarc_tot_cat) %>%
  summarise(across(all_of(dominios$var_p), ~ median(.x, na.rm = TRUE))) %>%
  rename_with(~ etiquetas_dominio[.x], all_of(dominios$var_p))

radar_group
Figura 14
Código
eje_max <- 50   # extremo del eje radial (las medianas observadas son < 50)

radar_df <- bind_rows(
  as_tibble(set_names(as.list(rep(eje_max, 6)), names(radar_group)[-1])),
  as_tibble(set_names(as.list(rep(0, 6)),       names(radar_group)[-1])),
  radar_group[-1]
) %>%
  as.data.frame()

radarchart(
  radar_df,
  axistype    = 1,
  seg         = 5,
  caxislabels = seq(0, eje_max, length.out = 6),
  pcol        = col_sarc,
  pfcol       = scales::alpha(col_sarc, 0.25),
  plwd        = 2,
  plty        = 1,
  cglcol      = "grey80",
  axislabcol  = "grey40",
  vlcex       = 0.9
)

legend("topright", legend = names(col_sarc), col = col_sarc, lwd = 3, bty = "n")
Figura 15