1 Inicialización del problema

1.1 Criterios para ser un SuperAger

De acuerdo a Harrison (2012; doi: 10.1017/S1355617712000847), los SuperAgers deben tener un rendimiento en la memoria igual o por encima de la norma establecida para individuos en sus 50-60 años (Schmidt, 2004). Los restantes dominios (denominación, fluencia semántica y atención alternante) requieren un rendimiento dentro de una desviación estándar de acuerdo a la edad real.

1.2 Datos normativos

Al día de la fecha, contamos con dos fuentes de datos normativos.

La primera de ellas:

  • Spreen & Strauss. Tercera Edición, año 2006. Utilizan la media y la desviación como estimadores. Cuando las normas están divididas por sexo y edad, el grupo etario es 70+. Tiene un tamaño muestral de 11 personas para hombres y 10 personas para mujeres. Parece bajo.

  • Normas publicadas en 2026 (Fleni). Son datos normativos basados en regresión. Incluyeron 393 personas, clasificadas como cognitivamente sanas, de acuerdo a MoCA y Craft Story 21. Incluyen ajuste por edad, sexo y escolaridad. La muestra utilizada tampoco muestra una gran extensión para la franja > 70 aunque es considerablemente más grande.

1.3 Función-que-estima-normas

Vamos a crear una función que calcule el z-score basándose tanto en Spreen&Strauss como en RegNorm.

# Tablas Spreen & Strauss
#grupos que vamo a usar --> "50-59", "60-69" y "70+"
Spreen_mujer <- list(media=c(10.0,10.2,8.3),
                      desvio=c(3.4,2.5,2.1))
Spreen_hombre <- list(media=c(8.7, 6.8, 5.6),
                      desvio=c(3.0, 3.7, 2.6))

# Fórmula de RegNorm
#Formula <- 4.70-0.13*(edad-71.28)+(sexo*1.40)+(0.10*educacion)

# Creamos la función
CalcularRAVLT <- function(edad, sexo, educacion, score,
                          criterio = "ambos") {
  resultado <- list()
  
  # Spreen & Strauss
  if (criterio %in% c("ambos", "spreen")) {
    grupo <- findInterval(edad, c(50, 60, 70))
    
    tabla <- if (sexo == "mujer") Spreen_mujer else Spreen_hombre
    
    media <- tabla$media[grupo]
    desvio <- tabla$desvio[grupo]
    z <- (score - media) / desvio
    resultado[["Spreen"]] <- data.frame(
      metodo = "Spreen",
      media = media,
      desvio = desvio,
      z = z)
  }
  
  # RegNorm
  if (criterio %in% c("ambos", "regresion")) {
    mujer <- ifelse(sexo == "mujer", 1, 0)
    media <-  4.70312693329672 - 0.130680713065757 *(edad - 71.28)+
      1.40115774955016 * mujer+0.109981059825642 * educacion
    desvio <- 2.804785
    z <- (score - media) / desvio
    resultado[["Regresion"]] <- data.frame(
      metodo = "Regresion",media = media,desvio = desvio,z = z)
  }
  
  # Unificación
  resultado <- do.call(rbind, resultado)
  rownames(resultado) <- NULL
  return(resultado)
}

# Testeamos.
CalcularRAVLT(edad = 65,sexo = "mujer",educacion = 12,score = 9,
  criterio = "ambos")
##      metodo     media   desvio          z
## 1    Spreen 10.200000 2.500000 -0.4800000
## 2 Regresion  8.244732 2.804785  0.2692783

1.4 Simulamos

Acá lo que se hizo fue lo siguiente. Empecé creando una población imaginaria y asigné probabilidades equivalentes. Mala idea. Porque un 15 en el diferido era igual de probable que un 1. Así que descargué la base de datos de Fleni. Como no se puede descargar todo, solamente logré obtener 200 pacientes. No tengo idea diagnósticos. Lo único que me va a preocupar es que sean adultos mayores.

# Población real
library(dplyr)
library(lubridate)
archivos <- read.csv("C:/Users/nicor/OneDrive/Desktop/1.csv")
fleni<- archivos %>%
  mutate(
    nacimiento = ymd(paciente_nacimiento),
    fecha_evaluacion = dmy_hm(RAVLT.Diferido..7._fecha_creacion_test),
    edad = floor(time_length(interval(nacimiento, fecha_evaluacion),"years")))%>%
  select(
    paciente_dni,paciente_escolaridad,paciente_sexo,
    nacimiento,fecha_evaluacion,edad,RAVLT.Diferido..7._valor_pb)
df <- fleni %>%
  transmute(id = paciente_dni,edad = as.numeric(edad),
    sexo = tolower(paciente_sexo),educacion = as.numeric(paciente_escolaridad),
    score = as.numeric(RAVLT.Diferido..7._valor_pb))%>%
  filter(!is.na(edad),!is.na(sexo),!is.na(educacion),!is.na(score),
    edad >= 50,edad <= 90,sexo %in% c("mujer", "hombre"),score >= 0,score <= 15)

# Me interesan los mayores a 75.
base_boost <- df %>%filter(edad >= 75)
nrow(base_boost)
## [1] 94
n_distinct(base_boost$id)
## [1] 94
set.seed(705117)
base_amplia <- base_boost %>%
  slice_sample(n = 1000, replace = TRUE) %>%
  mutate(id_original = id,id = 1:1000)

head(base_amplia)

Ya tenemos nuestra base de datos de mil sujetos vía boostrap.

Ahora es que estamos interesados en calcular nuestra función en estos datos.

library(dplyr)
library(tidyr)
resultados <- lapply(1:nrow(base_amplia), function(i) {
  calculo <- CalcularRAVLT(
    edad = base_amplia$edad[i],
    sexo = base_amplia$sexo[i],
    educacion = base_amplia$educacion[i],
    score = base_amplia$score[i],
    criterio = "ambos"
  )
  calculo$id <- base_amplia$id[i]
  return(calculo)
})
dataset <- bind_rows(resultados) %>%
  left_join(base_amplia, by = "id")

data<-dataset%>%
  select(id, edad, sexo, educacion, score, metodo, z) %>%
  pivot_wider(
    names_from = metodo,
    values_from = z,
    names_prefix = "z_"
  )
head(data)

2 Dos preguntas que hay que responder

2.1 Pregunta n° 1.

¿Cuál es el grado de acuerdo entre los z-scores que brindan ambos datos normativos?

Empecemos por una correlación.

# Calculamos Pearson
corr <- cor.test(data$z_Regresion,
                 data$z_Spreen,method = "pearson")
corr
## 
##  Pearson's product-moment correlation
## 
## data:  data$z_Regresion and data$z_Spreen
## t = 71.401, df = 998, p-value < 2.2e-16
## alternative hypothesis: true correlation is not equal to 0
## 95 percent confidence interval:
##  0.9037297 0.9240930
## sample estimates:
##       cor 
## 0.9144886

Después podemos mirar diferencia promedio.

comparativa <- data %>%
  mutate(
    diferencia = z_Regresion - z_Spreen,
    promedio = (z_Regresion + z_Spreen) / 2)
comparativa
acuerdo <- comparativa %>%
  summarise(
    sesgo = mean(diferencia),
    de_diferencias = sd(diferencia),

    limite_inferior = sesgo - 1.96 * de_diferencias,
    limite_superior = sesgo + 1.96 * de_diferencias
  )

acuerdo
comparativa %>%
  summarise(
    diferencia_media = mean(diferencia),

    diferencia_absoluta_media = mean(abs(diferencia)),

    porcentaje_05 = mean(abs(diferencia) >= 0.5) * 100,

    porcentaje_1 = mean(abs(diferencia) >= 1) * 100
  )

2.2 Pregunta n° 2.

¿Cuál es el grado de acuerdo entre en la forma de clasificar SA de ambos métodos?

superagers <- comparativa %>%
  filter(edad >= 75) %>%
  mutate(
    # Criterio de Harrison
    SA_Harrison = score >= 9,
    # Spreen: referencia de 60-69 años
    media_spreen = ifelse(sexo == "mujer", 10.2, 6.8),
    desvio_spreen = ifelse(sexo == "mujer", 2.5, 3.7),
    z_spreen_joven = (score - media_spreen) / desvio_spreen,
    SA_Spreen = z_spreen_joven >= 0,
    # RegNorm: referencia de 61 años
    media_regresion = 4.70 -
      0.13 * (61 - 71.28) +
      1.40 * (sexo == "mujer") +
      0.10 * educacion,
    z_regresion_joven = (score - media_regresion) / 2.804785,
    SA_Regresion = z_regresion_joven >= 0
  )
table(
  Spreen = superagers$SA_Spreen,
  RegNorm = superagers$SA_Regresion)
##        RegNorm
## Spreen  FALSE TRUE
##   FALSE   957   20
##   TRUE      0   23
# Calculamos de paso el índice de kappa
library(irr)

kappa2(
  superagers[, c("SA_Spreen", "SA_Regresion")],
  weight = "unweighted"
)
##  Cohen's Kappa for 2 Raters (Weights: unweighted)
## 
##  Subjects = 1000 
##    Raters = 2 
##     Kappa = 0.688 
## 
##         z = 22.9 
##   p-value = 0

En resumen, se identifican 43 personas como posibles SuperAgers (en base al criterio de memoria) –> o sea 4.3%. Mientras que Spreen clasificaría al 2.3% como SA. Sin haber utilizado el criterio del resto de los dominios cognitivos, claro está.