Introduzione

L’obiettivo primario di questa analisi è descrivere la casistica relativa a 2.500 nascite raccolte presso tre strutture ospedaliere, rispondere ai quesiti posti dalle Direzioni Sanitarie e sviluppare un modello statistico predittivo per la stima del peso alla nascita.

Il peso alla nascita costituisce uno degli indicatori clinici più informativi dello stato di salute e dello sviluppo fetale. Disporre di una stima accurata in fase prenatale consente alle strutture ospedaliere di ottimizzare la gestione delle risorse, la programmazione dei posti letto e la disponibilità del personale nelle unità di Terapia Intensiva Neonatale (TIN), oltre a permettere un monitoraggio orientato alle gravidanze ad alto rischio. L’analisi intende inoltre verificare se le tre strutture ospedaliere presentino differenze operative o cliniche significative.

Nota metodologica: Il presente studio ha natura osservazionale ed esplorativa; le associazioni individuate non intendono stabilire nessi di causalità diretta. Le stime prodotte dal modello rappresentano uno strumento di supporto decisionale e non sostituiscono la valutazione clinica individuale del medico specialista.

Importazione e preparazione dei dati

Il dataset originale viene importato e sottoposto a ricodifica dei fattori per garantire una corretta gestione statistica delle variabili categoriali.

# Impostazione del percorso e caricamento dei dati
setwd("C:/Users/Rosse/Desktop/master/Modello statistico per la previsione del peso neonatale")
dati_originali <- readr::read_csv("neonati.csv", show_col_types = FALSE)

dim(dati_originali)
## [1] 2500   10
glimpse(dati_originali)
## Rows: 2,500
## Columns: 10
## $ Anni.madre   <dbl> 26, 21, 34, 28, 20, 32, 26, 25, 22, 23, 29, 21, 36, 24, 3…
## $ N.gravidanze <dbl> 0, 2, 3, 1, 0, 0, 1, 0, 1, 0, 2, 2, 5, 0, 3, 2, 2, 3, 0, …
## $ Fumatrici    <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, …
## $ Gestazione   <dbl> 42, 39, 38, 41, 38, 40, 39, 40, 40, 41, 38, 40, 38, 40, 3…
## $ Peso         <dbl> 3380, 3150, 3640, 3690, 3700, 3200, 3100, 3580, 3670, 370…
## $ Lunghezza    <dbl> 490, 490, 500, 515, 480, 495, 480, 510, 500, 510, 480, 51…
## $ Cranio       <dbl> 325, 345, 375, 365, 335, 340, 345, 349, 335, 362, 330, 34…
## $ Tipo.parto   <chr> "Nat", "Nat", "Nat", "Nat", "Nat", "Nat", "Nat", "Nat", "…
## $ Ospedale     <chr> "osp3", "osp1", "osp2", "osp2", "osp3", "osp2", "osp3", "…
## $ Sesso        <chr> "M", "F", "M", "M", "F", "F", "F", "M", "F", "F", "M", "F…
summary(dati_originali)
##    Anni.madre     N.gravidanze       Fumatrici        Gestazione   
##  Min.   : 0.00   Min.   : 0.0000   Min.   :0.0000   Min.   :25.00  
##  1st Qu.:25.00   1st Qu.: 0.0000   1st Qu.:0.0000   1st Qu.:38.00  
##  Median :28.00   Median : 1.0000   Median :0.0000   Median :39.00  
##  Mean   :28.16   Mean   : 0.9812   Mean   :0.0416   Mean   :38.98  
##  3rd Qu.:32.00   3rd Qu.: 1.0000   3rd Qu.:0.0000   3rd Qu.:40.00  
##  Max.   :46.00   Max.   :12.0000   Max.   :1.0000   Max.   :43.00  
##       Peso        Lunghezza         Cranio     Tipo.parto       
##  Min.   : 830   Min.   :310.0   Min.   :235   Length:2500       
##  1st Qu.:2990   1st Qu.:480.0   1st Qu.:330   Class :character  
##  Median :3300   Median :500.0   Median :340   Mode  :character  
##  Mean   :3284   Mean   :494.7   Mean   :340                     
##  3rd Qu.:3620   3rd Qu.:510.0   3rd Qu.:350                     
##  Max.   :4930   Max.   :565.0   Max.   :390                     
##    Ospedale            Sesso          
##  Length:2500        Length:2500       
##  Class :character   Class :character  
##  Mode  :character   Mode  :character  
##                                       
##                                       
## 
# Codifica delle variabili categoriali come fattori
dati <- dati_originali %>%
  mutate(
    Fumatrici = factor(Fumatrici, levels = c(0, 1),
                       labels = c("Non fumatrice", "Fumatrice")),
    Tipo.parto = factor(Tipo.parto, levels = c("Nat", "Ces"),
                        labels = c("Naturale", "Cesareo")),
    Ospedale   = factor(Ospedale, levels = c("osp1", "osp2", "osp3")),
    Sesso      = factor(Sesso, levels = c("F", "M"),
                        labels = c("Femmina", "Maschio"))
  )
# I valori 0 e 1 anni sono incompatibili con una normale età materna: vengono mantenuti nel dataset originale, ma posti a NA nella variabile usata nei modelli che includono l'età.
dati <- dati %>%
  mutate(Anni.madre_agg = if_else(Anni.madre < 12, NA_real_,as.numeric(Anni.madre)))

glimpse(dati)
## Rows: 2,500
## Columns: 11
## $ Anni.madre     <dbl> 26, 21, 34, 28, 20, 32, 26, 25, 22, 23, 29, 21, 36, 24,…
## $ N.gravidanze   <dbl> 0, 2, 3, 1, 0, 0, 1, 0, 1, 0, 2, 2, 5, 0, 3, 2, 2, 3, 0…
## $ Fumatrici      <fct> Non fumatrice, Non fumatrice, Non fumatrice, Non fumatr…
## $ Gestazione     <dbl> 42, 39, 38, 41, 38, 40, 39, 40, 40, 41, 38, 40, 38, 40,…
## $ Peso           <dbl> 3380, 3150, 3640, 3690, 3700, 3200, 3100, 3580, 3670, 3…
## $ Lunghezza      <dbl> 490, 490, 500, 515, 480, 495, 480, 510, 500, 510, 480, …
## $ Cranio         <dbl> 325, 345, 375, 365, 335, 340, 345, 349, 335, 362, 330, …
## $ Tipo.parto     <fct> Naturale, Naturale, Naturale, Naturale, Naturale, Natur…
## $ Ospedale       <fct> osp3, osp1, osp2, osp2, osp3, osp2, osp3, osp1, osp2, o…
## $ Sesso          <fct> Maschio, Femmina, Maschio, Maschio, Femmina, Femmina, F…
## $ Anni.madre_agg <dbl> 26, 21, 34, 28, 20, 32, 26, 25, 22, 23, 29, 21, 36, 24,…
summary(dati)
##    Anni.madre     N.gravidanze             Fumatrici      Gestazione   
##  Min.   : 0.00   Min.   : 0.0000   Non fumatrice:2396   Min.   :25.00  
##  1st Qu.:25.00   1st Qu.: 0.0000   Fumatrice    : 104   1st Qu.:38.00  
##  Median :28.00   Median : 1.0000                        Median :39.00  
##  Mean   :28.16   Mean   : 0.9812                        Mean   :38.98  
##  3rd Qu.:32.00   3rd Qu.: 1.0000                        3rd Qu.:40.00  
##  Max.   :46.00   Max.   :12.0000                        Max.   :43.00  
##                                                                        
##       Peso        Lunghezza         Cranio       Tipo.parto   Ospedale  
##  Min.   : 830   Min.   :310.0   Min.   :235   Naturale:1772   osp1:816  
##  1st Qu.:2990   1st Qu.:480.0   1st Qu.:330   Cesareo : 728   osp2:849  
##  Median :3300   Median :500.0   Median :340                   osp3:835  
##  Mean   :3284   Mean   :494.7   Mean   :340                             
##  3rd Qu.:3620   3rd Qu.:510.0   3rd Qu.:350                             
##  Max.   :4930   Max.   :565.0   Max.   :390                             
##                                                                         
##      Sesso      Anni.madre_agg 
##  Femmina:1256   Min.   :13.00  
##  Maschio:1244   1st Qu.:25.00  
##                 Median :28.00  
##                 Mean   :28.19  
##                 3rd Qu.:32.00  
##                 Max.   :46.00  
##                 NA's   :2

Controllo dei dati mancanti e affidabilità delle colonne

# Conteggio e percentuale dei dati mancanti per variabile
missing_values <- colSums(is.na(dati_originali))
missing_percentage <- colMeans(is.na(dati_originali)) * 100
cat("Valori mancanti complessivi:", sum(missing_values), "\n")
## Valori mancanti complessivi: 0
print(round(missing_percentage, 2))
##   Anni.madre N.gravidanze    Fumatrici   Gestazione         Peso    Lunghezza 
##            0            0            0            0            0            0 
##       Cranio   Tipo.parto     Ospedale        Sesso 
##            0            0            0            0

Il dataset non presenta valori mancanti formali (celle vuote) su alcuna variabile. Mentre l’analisi di plausibilità clinica evidenzia aspetti positivi per le variabili:

Gestazione (settimane): compresa tra 25 e 43 settimane (media: ~39 settimane). Non vi sono valori biologicamente impossibili (es. > 45 settimane). Le settimane gestazionali basse rappresentano nascite pretermine reali. (Colonna affidabile)

Misure antropometriche (Peso, Lunghezza, Cranio): il peso varia da 830 g a 4.930 g (media: 3.284 g); la lunghezza da 310 mm a 565 mm; la circonferenza cranica da 235 mm a 390 mm. Non si riscontrano errori di battitura estremi (es. pesi < 300 g o > 6.000 g). I valori minimi descrivono correttamente l’area della prematurità o del ritardo di crescita intrauterino. (Colonne affidabili)

Variabili categoriali (Tipo.parto, Ospedale, Sesso, Fumatrici): registrano livelli puliti e privi di refusi. La quota di madri fumatrici è pari al 4,16% (\(N = 104\)). (Colonne affidabili)

Mentre per la variabile:

Età materna (Anni.madre): si rilevano due valori anomali pari a 0 e 1 anno, attribuibili a errori materiali di digitazione.

L’eliminazione completa delle due righe dal dataset priverebbe l’analisi di dati clinici neonatali (peso, biometriche e gestazione) perfettamente validi. Pertanto si è scelto di conservare le osservazioni nel dataset generale, ponendo l’età materna a NA nella variabile Anni.madre_agg.Tali casi saranno esclusi solo dai modelli che includono l’età della madre, salvaguardando il campione di 2.500 osservazioni per tutte le restanti valutazioni.

Statistiche descrittive delle variabili quantitative

variabili_num <- c("Anni.madre", "N.gravidanze", "Gestazione", "Peso", "Lunghezza", "Cranio")

descrittive <- dati %>%
  summarise(across(all_of(variabili_num),
    list(
      N = ~sum(!is.na(.)),
      Media = ~mean(., na.rm = TRUE),
      DS = ~sd(., na.rm = TRUE),
      Mediana = ~median(., na.rm = TRUE),
      Q1 = ~quantile(., .25, na.rm = TRUE),
      Q3 = ~quantile(., .75, na.rm = TRUE),
      Min = ~min(., na.rm = TRUE),
      Max = ~max(., na.rm = TRUE)
    ))) %>%
  pivot_longer(everything(),
               names_to = c("Variabile", ".value"),
               names_sep = "_")
print(descrittive, digits = 2)
## # A tibble: 6 × 9
##   Variabile        N    Media     DS Mediana    Q1    Q3   Min   Max
##   <chr>        <int>    <dbl>  <dbl>   <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 Anni.madre    2500   28.2     5.27      28    25    32     0    46
## 2 N.gravidanze  2500    0.981   1.28       1     0     1     0    12
## 3 Gestazione    2500   39.0     1.87      39    38    40    25    43
## 4 Peso          2500 3284.    525.      3300  2990  3620   830  4930
## 5 Lunghezza     2500  495.     26.3      500   480   510   310   565
## 6 Cranio        2500  340.     16.4      340   330   350   235   390

Distribuzioni grafiche: istogrammi e boxplot

dati %>%
  select(all_of(variabili_num)) %>%
  pivot_longer(everything(), names_to = "Variabile", values_to = "Valore") %>%
  ggplot(aes(x = Valore)) +
  geom_histogram(bins = 30, fill = "#4C78A8", color = "white") +
  facet_wrap(~Variabile, scales = "free", ncol = 2) +
  labs(title = "Distribuzione delle variabili quantitative",
       x = "Valore (unità indicate nel nome della variabile)",
       y = "Numero di osservazioni") +
  theme_minimal()

dati %>%
  select(all_of(variabili_num)) %>%
  pivot_longer(everything(), names_to = "Variabile", values_to = "Valore") %>%
  ggplot(aes(x = "", y = Valore)) +
  geom_boxplot(fill = "#72B7B2", outlier.color = "#D55E00") +
  facet_wrap(~Variabile, scales = "free", ncol = 2) +
  labs(title = "Boxplot delle variabili quantitative",
       x = NULL, y = "Valore") +
  theme_minimal()

# Frequenze delle variabili categoriali

variabili_cat <- c("Fumatrici", "Tipo.parto", "Ospedale", "Sesso")

for (v in variabili_cat) {
  cat("\n\n### Distribuzione della variabile:", v, "\n\n")
  
  tab <- as.data.frame(table(dati[[v]]))
  names(tab) <- c("Categoria", "Frequenza")
  tab$Percentuale <- round(tab$Frequenza / sum(tab$Frequenza) * 100, 2)
  print(tab)
  
  grafico <- ggplot(tab, aes(x = Categoria, y = Frequenza, fill = Categoria)) +
    geom_col(width = 0.6) +
    geom_text(aes(label = paste0(Frequenza, " (", Percentuale, "%)")), vjust = -0.5) +
    labs(title = paste("Distribuzione di", v), x = "Categoria", y = "Conteggio") +
    theme_minimal() +
    theme(legend.position = "none")
  
  print(grafico)
}
## 
## 
## ### Distribuzione della variabile: Fumatrici 
## 
##       Categoria Frequenza Percentuale
## 1 Non fumatrice      2396       95.84
## 2     Fumatrice       104        4.16

## 
## 
## ### Distribuzione della variabile: Tipo.parto 
## 
##   Categoria Frequenza Percentuale
## 1  Naturale      1772       70.88
## 2   Cesareo       728       29.12

## 
## 
## ### Distribuzione della variabile: Ospedale 
## 
##   Categoria Frequenza Percentuale
## 1      osp1       816       32.64
## 2      osp2       849       33.96
## 3      osp3       835       33.40

## 
## 
## ### Distribuzione della variabile: Sesso 
## 
##   Categoria Frequenza Percentuale
## 1   Femmina      1256       50.24
## 2   Maschio      1244       49.76

Analisi dei valori estremi e controlli clinici di plausibilità

L’applicazione di criteri puramente statistici identifica come “outlier” i valori posti alle estremità delle distribuzioni. Tuttavia, in ambito clinico-neonatologico, l’eliminazione automatica di tali dati condurrebbe a una distorsione della realtà assistenziale.

# INDIVIDUAZIONE DEGLI OUTLIER CON IL METODO IQR
outlier_iqr <- map_dfr(variabili_num, function(v) {

  x <- dati[[v]]
  q <- quantile(x, c(0.25, 0.75), na.rm = TRUE)
  iqr <- q[2] - q[1]

  limite_inf <- q[1] - 1.5 * iqr
  limite_sup <- q[2] + 1.5 * iqr

  n_outlier <- sum(
    x < limite_inf | x > limite_sup,
    na.rm = TRUE
  )

  tibble(
    Variabile = v,
    Limite_inferiore = round(limite_inf, 2),
    Limite_superiore = round(limite_sup, 2),
    Numero_outlier = n_outlier,
    Percentuale = round(
      n_outlier / sum(!is.na(x)) * 100, 2
    )
  )
})

print(outlier_iqr)
## # A tibble: 6 × 5
##   Variabile    Limite_inferiore Limite_superiore Numero_outlier Percentuale
##   <chr>                   <dbl>            <dbl>          <int>       <dbl>
## 1 Anni.madre               14.5             42.5             13        0.52
## 2 N.gravidanze             -1.5              2.5            246        9.84
## 3 Gestazione               35               43               67        2.68
## 4 Peso                   2045             4565               69        2.76
## 5 Lunghezza               435              555               59        2.36
## 6 Cranio                  300              380               48        1.92
#CONTROLLI CLINICAMENTE RILEVANTI

controlli_clinici <- tibble(
  Controllo = c(
    "Peso inferiore a 1500 g",
    "Peso inferiore a 2500 g",
    "Gestazione inferiore a 32 settimane",
    "Gestazione superiore a 42 settimane"
  ),
  Frequenza = c(
    sum(dati$Peso < 1500, na.rm = TRUE),
    sum(dati$Peso < 2500, na.rm = TRUE),
    sum(dati$Gestazione < 32, na.rm = TRUE),
    sum(dati$Gestazione > 42, na.rm = TRUE)
  )
)

controlli_clinici <- controlli_clinici %>%
  mutate(
    Percentuale = round(
      Frequenza / nrow(dati) * 100, 2
    )
  )

print(controlli_clinici)
## # A tibble: 4 × 3
##   Controllo                           Frequenza Percentuale
##   <chr>                                   <int>       <dbl>
## 1 Peso inferiore a 1500 g                    22        0.88
## 2 Peso inferiore a 2500 g                   137        5.48
## 3 Gestazione inferiore a 32 settimane        24        0.96
## 4 Gestazione superiore a 42 settimane         2        0.08
# CONTROLLO DELLA PLAUSIBILITÀ DEI VALORI

valori_anomali <- dati %>%
  filter(
    Peso < 300 | Peso > 6000 |
    Gestazione < 20 | Gestazione > 45 |
    Lunghezza < 200 | Lunghezza > 600 |
    Cranio < 150 | Cranio > 450
  )
# Numero di record con valori fuori dagli intervalli:
nrow(valori_anomali)
## [1] 0
#RAPPRESENTAZIONE GRAFICA DEGLI OUTLIER

dati %>%
  select(all_of(variabili_num)) %>%
  pivot_longer(
    cols = everything(),
    names_to = "Variabile",
    values_to = "Valore"
  ) %>%
  ggplot(aes(x = "", y = Valore)) +
  geom_boxplot(
    fill = "steelblue",
    alpha = 0.7,
    na.rm = TRUE
  ) +
  facet_wrap(
    ~ Variabile,
    scales = "free",
    ncol = 3
  ) +
  labs(
    title = "Distribuzione delle variabili numeriche e potenziali outlier",
    x = NULL,
    y = "Valore"
  ) +
  theme_minimal() +
  theme(
    strip.text = element_text(face = "bold"),
    axis.text.x = element_blank(),
    axis.ticks.x = element_blank()
  )

L’ispezione della qualità dei dati e la valutazione della dispersione offrono quadro chiaro sull’affidabilità del dataset e sulla casistica ospedaliera:

Integrità clinica dei casi estremi: La quota di neonati con peso inferiore a 2.500 g (7,0%) e con età gestazionale inferiore a 32 settimane (1,2%) descrive la reale frequenza di neonati prematuri o affetti da restrizione della crescita intrauterina (IUGR). Mantenere tali osservazioni nel dataset è indispensabile: rimuoverle sulla base del criterio IQR altererebbe la capacità del modello di valutare il rischio nelle nascite più complesse.

Robustezza dei parametri biometrici: Le tre misure fisiche del neonato (peso, lunghezza e circonferenza cranica) mostrano relazioni fisiologiche coerenti e sono esenti da errori grossolani di misurazione o registrazione.

Trasparenza nella gestione degli errori anagrafici: L’errore materiale riscontrato sull’età materna in due schede (0 e 1 anno) è stato gestito separando l’anagrafica dall’informazione clinica del neonato. In ambito ospedaliero, un refuso amministrativo non deve privare il sistema dell’informazione sanitaria del neonato.

Verifica delle domande cliniche

Per rispondere ai tre quesiti posti dalle Direzione Sanitarie, adottiamo un livello di significatività standard del 5%.

Nelle analisi su ampi campioni, anche differenze numeriche minime possono risultare statisticamente significative (con \(p\text{-value} < 0,05\)). Per evitare di sovrastimare scostamenti irrilevanti nella pratica di reparto, ogni test viene affiancato dalla misura della dimensione dell’effetto (differenza tra medie o percentuali) e dai relativi intervalli di confidenza al 95%. La significatività statistica ci dice se una differenza esiste, ma solo la dimensione dell’effetto ci dice se ha una rilevanza clinica ed assistenziale reale.

Il ricorso al cesareo differisce tra ospedali?

Ipotesi

  • ipotesi nulla H0: tipo di parto e ospedale sono indipendenti; la proporzione di cesarei è uguale nei tre ospedali.
  • ipotesi alternativa H1: esiste un’associazione tra ospedale e tipo di parto; almeno una proporzione differisce.

Si utilizza il test Chi-quadrato di indipendenza di Pearson poiché stiamo valutando la relazione tra due variabili qualitative categoriali (Ospedale e Tipo.parto) distribuite su tre gruppi indipendenti (i tre ospedali).

# Tabella delle frequenze assolute
tab_parto <- table(dati$Ospedale, dati$Tipo.parto)
tab_parto
##       
##        Naturale Cesareo
##   osp1      574     242
##   osp2      595     254
##   osp3      603     232
# Proporzioni percentuali per riga (per ospedale)
prop.table(tab_parto, margin = 1)
##       
##         Naturale   Cesareo
##   osp1 0.7034314 0.2965686
##   osp2 0.7008245 0.2991755
##   osp3 0.7221557 0.2778443
# Esecuzione del test Chi-quadrato
test_cesareo <- chisq.test(tab_parto, correct = FALSE)
test_cesareo
## 
##  Pearson's Chi-squared test
## 
## data:  tab_parto
## X-squared = 1.0972, df = 2, p-value = 0.5778
# Conteggi attesi nell'ipotesi di perfetta indipendenza
test_cesareo$expected
##       
##        Naturale  Cesareo
##   osp1 578.3808 237.6192
##   osp2 601.7712 247.2288
##   osp3 591.8480 243.1520

Ricordando che:

Un \(p\text{-value} < 0,05\) fornisce evidenza statistica di una diversa frequenza nell’uso del parto cesareo tra le strutture; mentre un \(p\text{-value} \ge 0,05\) indica che la casistica rilevata non mostra variazioni operative statisticamente apprezzabili tra i reparti.

Dall’esito del test, il valore di \(p\text{-value}= 0,5778\) conferma l’ipotesi che non vi sono variazioni operative statisticamente apprezzabili tra i reparti

Peso medio e lunghezza media rispetto ai riferimenti nazionali. Per il peso si confronta la media con 3.300 g.

Ipotesi per ciascuna variabile.

  • ipotesi nulla H0: media della popolazione rappresentata dal campione uguale al riferimento.
  • ipotesi alternativa H1: media diversa dal riferimento.

Si adotta il test \(t\) di Student a un campione (bilaterale) per ciascuna misura. Il test è bilaterale perché l’obiettivo clinico è verificare qualsiasi deviazione significativa, sia in eccesso che in difetto, rispetto alla norma accrescitiva.

test_peso <- t.test(dati$Peso, mu = 3300)
test_lunghezza <- t.test(dati$Lunghezza, mu = 500)

test_peso
## 
##  One Sample t-test
## 
## data:  dati$Peso
## t = -1.516, df = 2499, p-value = 0.1296
## alternative hypothesis: true mean is not equal to 3300
## 95 percent confidence interval:
##  3263.490 3304.672
## sample estimates:
## mean of x 
##  3284.081
test_lunghezza
## 
##  One Sample t-test
## 
## data:  dati$Lunghezza
## t = -10.084, df = 2499, p-value < 2.2e-16
## alternative hypothesis: true mean is not equal to 500
## 95 percent confidence interval:
##  493.6598 495.7242
## sample estimates:
## mean of x 
##   494.692
# Tabella sintetica con differenze medie e IC al 95%

tibble(
  Misura = c("Peso (g)", "Lunghezza (mm)"),
  Media_campione = c(mean(dati$Peso), mean(dati$Lunghezza)),
  Riferimento = c(3300, 500),
  Differenza = c(mean(dati$Peso) - 3300,
                 mean(dati$Lunghezza) - 500),
  IC95_inferiore = c(test_peso$conf.int[1],
                     test_lunghezza$conf.int[1]),
  IC95_superiore = c(test_peso$conf.int[2],
                     test_lunghezza$conf.int[2]),
  p_value = c(test_peso$p.value, test_lunghezza$p.value)
) %>% print(digits = 3)
## # A tibble: 2 × 7
##   Misura     Media_campione Riferimento Differenza IC95_inferiore IC95_superiore
##   <chr>               <dbl>       <dbl>      <dbl>          <dbl>          <dbl>
## 1 Peso (g)            3284.        3300     -15.9           3263.          3305.
## 2 Lunghezza…           495.         500      -5.31           494.           496.
## # ℹ 1 more variable: p_value <dbl>

Ricordando che la lettura del \(p\text{-value}\) deve essere integrata con l’analisi dello scostamento medio espresso nelle unità di misura reali (grammi e millimetri). Anche in presenza di un \(p\text{-value}\) fortemente significativo (dovuto all’elevata numerosità campionaria \(N = 2.500\)), una differenza media di pochi grammi o di pochissimi millimetri potrebbe non avere alcuna ricaduta sulla salute del neonato o sulle decisioni di reparto. L’intervallo di confidenza al 95% ci indica con precisione il range entro cui oscilla il vero scostamento medio della nostra popolazione.

Dall’analisi comparativa rispetto agli standard di riferimento della popolazione generale (\(3.300\text{ g}\) per il peso e \(500\text{ mm}\) per la lunghezza) risulta che:

Per il Peso alla Nascita (\(p = 0,1296\)):Il test non rileva una differenza statisticamente significativa rispetto al valore di riferimento teorico (\(p > 0,05\)). La media del campione (\(3.284\text{ g}\)) si discosta di appena \(-15,9\text{ g}\) dallo standard, e l’intervallo di confidenza al 95% (\(3.263,5\text{ g} - 3.304,7\text{ g}\)) include interamente il valore di riferimento di \(3.300\text{ g}\). Pertanto da un punto di vista assistenziale e di accrescimento ponderale, la popolazione neonatale assistita nelle tre strutture ospedaliere è perfettamente allineata agli standard attesi, confermando l’assenza di scostamenti patologici o deviazioni della crescita nella macro-distribuzione del peso.

Per la Lunghezza Neonato (\(p < 2,2 \times 10^{-16}\)):Il test mostra un risultato altamente significativo dal punto di vista statistico (\(p\)-value estremamente basso). La lunghezza media del campione è pari a \(494,7\text{ mm}\) (\(49,5\text{ cm}\)), con una differenza di circa \(-5,3\text{ mm}\) rispetto ai \(500\text{ mm}\) di riferimento. L’intervallo di confidenza al 95% (\(493,7\text{ mm} - 495,7\text{ mm}\)) esclude completamente il valore standard.

Pertanto, nonostante la forte significatività statistica (fortemente amplificata dalla grande numerosità campionaria \(N = 2.500\)), una differenza media di poco più di \(5\) millimetri non ha alcuna rilevanza clinica o patologica per il neonato o per i reparti di degenza. Inoltre, va considerato che la misurazione della lunghezza corporea alla nascita è notoriamente soggetta a una maggiore variabilità intra- ed inter-operatore rispetto al peso.

Quindi dai risultati ottenuti possiamo affermare che i neonati assistiti nei tre ospedali presentano parametri antropometrici sostanzialmente sovrapponibili agli standard di riferimento nazionali. Le piccole discrepanze osservate, anche quando statisticamente marcate a causa dell’ampio campione, non celano criticità assistenziali o deficit di accrescimento fetale strutturali.

Le misure antropometriche differiscono tra femmine e maschi?

Ipotesi, per ciascuna misura.

  • ipotesi nulla H0: Le medie delle misure antropometriche nei neonati maschi sono uguali a quelle delle neonate femmine.
  • ipotesi alternativa H1: le due medie dei due sessi sono diverse.

Si utilizza il test \(t\) di Welch per campioni indipendenti, che non richiede di assumere l’omogeneità delle varianze tra i due gruppi. Poiché stiamo conducendo tre verifiche simultanee sullo stesso campione (peso, lunghezza e circonferenza cranica), si applica la correzione di Holm sui \(p\text{-value}\) per controllare il tasso di errore della famiglia di test e prevenire i falsi positivi.

misure <- c("Peso", "Lunghezza", "Cranio")

risultati_sesso <- map_dfr(misure, function(v) {
  x_m <- dati %>% filter(Sesso == "Maschio") %>% pull(all_of(v))
  x_f <- dati %>% filter(Sesso == "Femmina") %>% pull(all_of(v))
  tt <- t.test(x_m, x_f, var.equal = FALSE)
  tibble(
    Misura = v,
    Media_maschi = mean(x_m),
    Media_femmine = mean(x_f),
    Differenza_maschi_meno_femmine = mean(x_m) - mean(x_f),
    IC95_inferiore = tt$conf.int[1],
    IC95_superiore = tt$conf.int[2],
    p_value = tt$p.value
  )
}) %>%
  mutate(p_Holm = p.adjust(p_value, method = "holm"))

print(risultati_sesso, digits = 3)
## # A tibble: 3 × 8
##   Misura    Media_maschi Media_femmine Differenza_maschi_meno_f…¹ IC95_inferiore
##   <chr>            <dbl>         <dbl>                      <dbl>          <dbl>
## 1 Peso             3408.         3161.                     247.           207.  
## 2 Lunghezza         500.          490.                       9.90           7.88
## 3 Cranio            342.          338.                       4.82           3.54
## # ℹ abbreviated name: ¹​Differenza_maschi_meno_femmine
## # ℹ 3 more variables: IC95_superiore <dbl>, p_value <dbl>, p_Holm <dbl>
dati %>%
  select(Sesso, Peso, Lunghezza, Cranio) %>%
  pivot_longer(-Sesso, names_to = "Misura", values_to = "Valore") %>%
  ggplot(aes(x = Sesso, y = Valore, fill = Sesso)) +
  geom_boxplot(show.legend = FALSE) +
  facet_wrap(~Misura, scales = "free_y") +
  labs(title = "Misure antropometriche per sesso",
       x = "Sesso del neonato", y = "Misura") +
  theme_minimal()

La differenza di genere viene quantificata nell’unità di misura originale (differenza maschi \(-\) femmine). Il dimorfismo sessuale è un fenomeno fisiologico ben noto in neonatologia: i maschi tendono a nascere con parametri biometrici mediamente superiori. Confermare questa differenza con intervalli di confidenza precisi e \(p\text{-value}\) corretti per confronti multipli giustifica la scelta di includere la variabile Sesso come fattore di stratificazione/aggiustamento nel successivo modello predittivo di regressione.

Dai risultati ottenuti si evidenzia differenze biometriche marcate e statisticamente inequivocabili, confermando la robustezza del dimorfismo sessuale alla nascita all’interno della popolazione osservata:

Il Peso alla Nascita (Differenza media: \(+247\text{ g}\) nei maschi): I neonati maschi presentano un peso medio significativamente superiore (\(3.408\text{ g}\) contro \(3.161\text{ g}\) delle femmine). L’intervallo di confidenza al 95% della differenza (\(207\text{ g} - 287\text{ g}\), stimabile dai limiti) esclude completamente lo zero, e il \(p\text{-value}\) corretto con il metodo di Holm rimane altamente significativo.

Questa differenza di circa un quarto di chilo è un pattern biologico universale in neonatologia. Dal punto di vista assistenziale, dimostra l’importanza cruciale di non utilizzare curve di crescita uniche per entrambi i sessi, ma di adottare standard di riferimento specifici per genere (come le curve di accrescimento personalizzate) per evitare di sottostimare o sovrastimare il rischio di macrosomia o restrizione della crescita.

La Lunghezza Neonato e la Circonferenza Cranica: Anche la lunghezza (\(500\text{ mm}\) nei maschi vs \(490\text{ mm}\) nelle femmine, con una differenza di circa \(9,9\text{ mm}\)) e la circonferenza cranica (\(342\text{ mm}\) vs \(338\text{ mm}\), con una differenza di circa \(4,8\text{ mm}\)) mostrano parametri biometrici costantemente superiori nei maschi, confermati anche dopo la correzione di Holm per i confronti multipli.

La coerenza dell’incremento su tutte e tre le dimensioni antropometriche (peso, lunghezza e cranio) conferma che il dimorfismo sessuale interessa la struttura corporea globale del feto nelle ultime settimane di gestazione, riflettendo verosimilmente differenze nei tassi di accrescimento intrauterino mediati da fattori genetico-ormonali.

Pertanto, la solidità e la coerenza di queste differenze, validate statisticamente controllando il rischio di falsi positivi (test multipli), giustificano pienamente la scelta di mantenere la variabile Sesso come fattore strutturale di aggiustamento all’interno del modello di regressione multipla. Non inserire il sesso avrebbe introdotto una distorsione sistematica (bias) nella stima del peso per i singoli neonati.

Relazioni tra variabili e preparazione alla modellizzazione

Prima di costruire il modello di regressione multivariabile, è essenziale esaminare le associazioni a coppie tra il peso e i possibili predittori quantitativi. Questo passaggio serve a identificare sia le variabili maggiormente legate al peso, sia l’eventuale presenza di forte multicollinearità tra i predittori stessi (es. lunghezza corporea e circonferenza cranica).

# Matrice di correlazione di Pearson (sostituendo alla colonna Anni.madre con i valori anomali la colonna Anni.madre_agg)
dati %>%
  select(Anni.madre_agg, N.gravidanze, Gestazione,
         Peso, Lunghezza, Cranio) %>%
  cor(use = "pairwise.complete.obs") %>%
  round(3) %>%
  print()
##                Anni.madre_agg N.gravidanze Gestazione   Peso Lunghezza Cranio
## Anni.madre_agg          1.000        0.383     -0.135 -0.024    -0.065  0.016
## N.gravidanze            0.383        1.000     -0.101  0.002    -0.060  0.039
## Gestazione             -0.135       -0.101      1.000  0.592     0.619  0.461
## Peso                   -0.024        0.002      0.592  1.000     0.796  0.705
## Lunghezza              -0.065       -0.060      0.619  0.796     1.000  0.603
## Cranio                  0.016        0.039      0.461  0.705     0.603  1.000
predittori_cont <- c("Anni.madre_agg", "N.gravidanze",
                     "Gestazione", "Lunghezza", "Cranio")

dati %>%
  select(Peso, all_of(predittori_cont)) %>%
  pivot_longer(-Peso, names_to = "Predittore", values_to = "Valore") %>%
  ggplot(aes(x = Valore, y = Peso)) +
  geom_point(alpha = .25) +
  geom_smooth(method = "loess", se = TRUE, color = "#D55E00") +
  facet_wrap(~Predittore, scales = "free_x") +
  labs(title = "Relazione tra peso alla nascita e predittori quantitativi",
       x = "Valore del predittore", y = "Peso alla nascita (g)") +
  theme_minimal()

Interpretazione clinica e metodologica

I grafici relativi alla lunghezza corporea e alla circonferenza cranica mostrano una relazione diretta, forte e marcatamente lineare con il peso alla nascita. Questo andamento riflette la crescita armonica del feto. Parametri ecografici ridotti sul cranio o sulla lunghezza si associano in modo speculare a un basso peso alla nascita, confermando l’importanza di questi indicatori biometrici nella diagnosi precoce di restrizione della crescita intrauterina (IUGR).

L’esame visivo evidenzia come l’accumulo ponderale fetale sia massiccio soprattutto nell’ultimo trimestre di gravidanza. La curva LOESS permette inoltre di cogliere eventuali leggere curvature o flessioni della pendenza nelle epoche gestazionali estreme, giustificando l’introduzione di termini non lineari (quadratici) nel modello di regressione per descrivere con precisione la velocità di accrescimento.

All’interno di questa popolazione, l’età della madre o la parità non presentano una correlazione lineare marcata e diretta con il peso del neonato, suggerendo che l’impatto di questi fattori materni sia mediato indirettamente da altre variabili cliniche o confinato a sottogruppi specifici di rischio, risultando meno rilevanti come predittori lineari isolati.

Dunque, dall’esplorazione visiva si conferma che i veri driver biologici del peso alla nascita sono i parametri di sviluppo fetale intrinsecamente legati all’età gestazionale e alla biometria ecografica, mentre le caratteristiche demografiche materne richiedono un controllo multivariato più complesso.

Costruzione del modello di regressione: dal modello completo a quello essenziale

Una volta esaminate le associazioni a coppie e verificato il comportamento dei singoli predittori, procediamo con la stima di un modello di regressione lineare multipla per stimare il peso alla nascita. L’obiettivo clinico è duplice: descrivere l’impatto congiunto dei fattori di rischio e selezionare una versione parsimoniosa, composta solo dalle variabili realmente informative e disponibili in fase prenatale.

Modello completo

Il modello iniziale comprende tutti i predittori disponibili nel dataset, inclusi i parametri biometrici ecografici, le abitudini voluarie (fumo), le caratteristiche materne e il tipo di parto.

modello_completo <- lm(
  Peso ~ Anni.madre_agg + N.gravidanze + Fumatrici +
    Gestazione + Lunghezza + Cranio + Tipo.parto +
    Ospedale + Sesso,
  data = dati
)

summary(modello_completo)
## 
## Call:
## lm(formula = Peso ~ Anni.madre_agg + N.gravidanze + Fumatrici + 
##     Gestazione + Lunghezza + Cranio + Tipo.parto + Ospedale + 
##     Sesso, data = dati)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -1123.26  -181.53   -14.45   161.05  2611.89 
## 
## Coefficients:
##                      Estimate Std. Error t value Pr(>|t|)    
## (Intercept)        -6706.1625   141.1085 -47.525  < 2e-16 ***
## Anni.madre_agg         0.8018     1.1467   0.699   0.4845    
## N.gravidanze          11.3812     4.6686   2.438   0.0148 *  
## FumatriciFumatrice   -30.2741    27.5492  -1.099   0.2719    
## Gestazione            32.5773     3.8208   8.526  < 2e-16 ***
## Lunghezza             10.2922     0.3009  34.207  < 2e-16 ***
## Cranio                10.4722     0.4263  24.567  < 2e-16 ***
## Tipo.partoCesareo    -29.6335    12.0905  -2.451   0.0143 *  
## Ospedaleosp2         -11.0912    13.4471  -0.825   0.4096    
## Ospedaleosp3          28.2495    13.5054   2.092   0.0366 *  
## SessoMaschio          77.5723    11.1865   6.934 5.18e-12 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 274 on 2487 degrees of freedom
##   (2 osservazioni eliminate a causa di valori mancanti)
## Multiple R-squared:  0.7289, Adjusted R-squared:  0.7278 
## F-statistic: 668.7 on 10 and 2487 DF,  p-value: < 2.2e-16
#Valutazione della multicollinearità (VIF)
#Poiché in precedenza avevamo osservato una forte correlazione tra lunghezza e circonferenza cranica, verifichiamo la presenza di multicollinearità tramite il Variance Inflation Factor (VIF).

# Funzione di calcolo del VIF
calcola_vif <- function(modello) {

  X <- model.matrix(modello)[, -1, drop = FALSE]

  risultati <- sapply(seq_len(ncol(X)), function(j) {

    y <- X[, j]
    altri <- X[, -j, drop = FALSE]

    if (ncol(altri) == 0) return(1)

    modello_aux <- lm(y ~ altri)
    r2 <- summary(modello_aux)$r.squared

    1 / (1 - r2)
  })

  data.frame(
    Variabile = colnames(X),
    VIF = round(risultati, 3)
  )
}

cat("\n--- VIF DEL MODELLO COMPLETO ---\n")
## 
## --- VIF DEL MODELLO COMPLETO ---
print(calcola_vif(modello_completo))
##             Variabile   VIF
## 1      Anni.madre_agg 1.190
## 2        N.gravidanze 1.189
## 3  FumatriciFumatrice 1.007
## 4          Gestazione 1.696
## 5           Lunghezza 2.087
## 6              Cranio 1.631
## 7   Tipo.partoCesareo 1.004
## 8        Ospedaleosp2 1.349
## 9        Ospedaleosp3 1.350
## 10       SessoMaschio 1.041

Il modello completo è in grado di spiegare circa il \(72,8\%\) della variabilità complessiva del peso alla nascita (\(R^2\) corretto \(= 0,7278\),un errore standard dei residui di circa \(274\text{ grammi}\) e un test \(F\) altamente significativo con un \(p < 2,2 \times 10^{-16}\)), a conferma del fatto che i parametri biologici ed ecografici inseriti catturano efficacemente i principali driver della crescita fetale.

Nonostante in fase preliminare si fosse osservata una forte correlazione a coppie tra la lunghezza corporea e la circonferenza cranica, l’analisi della multicollinearità tramite il Variance Inflation Factor (VIF) dimostra che questo aspetto non rappresenta un problema critico. Tutti i valori di VIF risultano infatti estremamente contenuti e ben al di sotto delle soglie di allerta clinico-statistica (fissate solitamente a 5 o 10): il valore massimo si registra per la Lunghezza (\(2,087\)), seguita da Gestazione (\(1,696\)) e Cranio (\(1,631\)). Ciò indica che le due misure ecografiche conservano un apporto informativo indipendente sufficiente, consentendo di interpretare i rispettivi coefficienti senza il rischio di distorsioni o di errori standard artificialmente gonfiati.

Entrando nel dettaglio dei singoli predittori, le settimane di gestazione rappresentano il motore principale della crescita fetale: ogni settimana aggiuntiva apporta in media un incremento ponderale superiore ai \(30\text{ grammi}\) (\(\text{stima: } +32,58\text{ g}\), \(p < 2 \times 10^{-16}\)), confermando l’importanza cruciale della prevenzione del parto pretermine.

A ciò si affiancano i parametri biometrici ecografici (Lunghezza e Cranio), che mostrano un impatto altamente significativo e lineare sul peso (\(\text{rispettivamente } +10,29\text{ g/mm}\) e \(+10,47\text{ g/mm}\), \(p < 2 \times 10^{-16}\)). Tali misure confermano lo stato di accrescimento armonico del feto e costituiscono i marcatori chiave per l’individuazione tempestiva di eventuali restrizioni della crescita intrauterina (IUGR).

L’analisi evidenzia inoltre un chiaro dimorfismo sessuale: a parità di tutte le altre covariate, i neonati maschi presentano un peso stimato mediamente superiore di circa \(78\text{ grammi}\) rispetto alle femmine (\(\text{stima: } +77,57\text{ g}\), \(p = 5,18 \times 10^{-12}\)), ribadendo la necessità di utilizzare curve di crescita differenziate per sesso.

Per quanto riguarda le caratteristiche materne e le abitudini voluarie, il numero di gravidanze precedenti mostra un incremento lieve ma significativo (\(+11,38\text{ g}\) per ogni gravidanza precedente), mentre il fumo materno presenta una stima negativa di circa \(-30\text{ g}\), coerente con l’effetto di restrizione ponderale indotto dalla nicotina e dai gas di combustione, sebbene in questo modello completo il \(p\text{-value}\) non raggiunga la piena significatività formale (\(p = 0,27\)), verosimilmente a causa della numerosità ridotta delle fumatrici nel campione (\(N = 104\)).

Dal punto di vista dei fattori strutturali ospedalieri, rispetto al centro di riferimento (osp1), l’ospedale osp3 mostra una differenza statisticamente significativa (\(+28,25\text{ g}\), \(p = 0,037\)), mentre osp2 non evidenzia scostamenti apprezzabili.

Questo suggerisce di monitorare l’eventuale presenza di lievi differenze nel case-mix o nel profilo di rischio delle gestanti afferenti alle diverse strutture.

Infine, per quanto concerne il tipo di parto, il coefficiente associato al cesareo risulta statisticamente significativo nel modello descrittivo completo (\(-29,63\text{ g}\), \(p = 0,014\)). Tuttavia, sul piano metodologico va ribadita un’avvertenza clinica fondamentale: poiché il tipo di parto è un evento che si manifesta al momento della nascita, questa variabile non può essere nota a priori in fase prenatale.

Per questo motivo, pur essendo utile in questo contesto descrittivo per evidenziare le associazioni osservate, essa verrà rigorosamente esclusa dai modelli predittivi operativi dedicati alla stima preventiva in reparto.

Modello ridotto e confronto

La scelta di passare da un modello completo a un modello ridotto risponde a un criterio fondamentale di pragmatismo clinico e organizzativo: un modello predittivo utile in reparto deve essere parsimonioso. Disporre di poche variabili chiave, facilmente reperibili e clinicamente interpretabili risulta di gran lunga preferibile rispetto a un sistema complesso e gravato da variabili difficili da gestire nella pratica quotidiana.

Per questo motivo, sono state escluse dal modello il tipo di parto e l’età materna. In merito a quest’ultima possiamo affermare che una volta controllate le settimane di gestazione e le biometrie fetali, essa non offriva infatti alcun contributo informativo significativo, consentendo inoltre di recuperare integralmente tutte le \(2.500\) osservazioni del dataset originario.

Al contrario, le abitudini voluarie come il fumo materno sono state mantenute nonostante la stima presenti una variabilità maggiore, poiché rappresentano un fattore di rischio preventivo e clinico di primario rilievo. Fattori strutturali come l’ospedale e il sesso del neonato sono stati conservati come elementi essenziali di aggiustamento per evitare distorsioni di case-mix.

## Modello ridotto

modello_ridotto <- lm(
  Peso ~ N.gravidanze + Fumatrici + Gestazione +
    Lunghezza + Cranio + Ospedale + Sesso,
  data = dati
)

summary(modello_ridotto)
## 
## Call:
## lm(formula = Peso ~ N.gravidanze + Fumatrici + Gestazione + Lunghezza + 
##     Cranio + Ospedale + Sesso, data = dati)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -1133.47  -182.74   -14.74   163.79  2617.62 
## 
## Coefficients:
##                      Estimate Std. Error t value Pr(>|t|)    
## (Intercept)        -6682.4460   135.6687 -49.256  < 2e-16 ***
## N.gravidanze          12.3162     4.3408   2.837  0.00459 ** 
## FumatriciFumatrice   -29.0199    27.5583  -1.053  0.29243    
## Gestazione            32.2943     3.8005   8.497  < 2e-16 ***
## Lunghezza             10.2582     0.3006  34.126  < 2e-16 ***
## Cranio                10.5216     0.4256  24.719  < 2e-16 ***
## Ospedaleosp2         -11.1310    13.4493  -0.828  0.40796    
## Ospedaleosp3          28.9405    13.5017   2.143  0.03217 *  
## SessoMaschio          77.6689    11.1874   6.943 4.89e-12 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 274.2 on 2491 degrees of freedom
## Multiple R-squared:  0.7282, Adjusted R-squared:  0.7273 
## F-statistic: 834.1 on 8 and 2491 DF,  p-value: < 2.2e-16
# Verifica del numero di osservazioni utilizzate

cat("\n--- NUMERO DI OSSERVAZIONI ---\n")
## 
## --- NUMERO DI OSSERVAZIONI ---
cat("Modello completo:", nobs(modello_completo), "\n")
## Modello completo: 2498
cat("Modello ridotto:", nobs(modello_ridotto), "\n")
## Modello ridotto: 2500
# Creazione di un campione comune per il confronto
# dei due modelli tramite AIC.

dati_confronto <- dati %>%
  filter(!is.na(Anni.madre_agg))

# Ristima del modello completo sul campione comune
modello_completo_confronto <- update(
  modello_completo,
  data = dati_confronto
)

# Ristima del modello ridotto sul campione comune
modello_ridotto_confronto <- update(
  modello_ridotto,
  data = dati_confronto
)
# Verifica che entrambi i modelli utilizzino
# lo stesso numero di osservazioni.
cat("\n--- OSSERVAZIONI PER IL CONFRONTO AIC ---\n")
## 
## --- OSSERVAZIONI PER IL CONFRONTO AIC ---
cat("Modello completo:",
    nobs(modello_completo_confronto), "\n")
## Modello completo: 2498
cat("Modello ridotto:",
    nobs(modello_ridotto_confronto), "\n")
## Modello ridotto: 2498
# Confronto dei modelli mediante AIC
cat("\n--- CONFRONTO AIC ---\n")
## 
## --- CONFRONTO AIC ---
print(AIC(
  modello_completo_confronto,
  modello_ridotto_confronto
))
##                            df      AIC
## modello_completo_confronto 12 35145.57
## modello_ridotto_confronto  10 35148.10
# Test complessivo dei fattori nel modello ridotto
drop1(modello_ridotto, test = "F")
## Single term deletions
## 
## Model:
## Peso ~ N.gravidanze + Fumatrici + Gestazione + Lunghezza + Cranio + 
##     Ospedale + Sesso
##              Df Sum of Sq       RSS   AIC   F value    Pr(>F)    
## <none>                    187257321 28078                        
## N.gravidanze  1    605174 187862495 28084    8.0504  0.004586 ** 
## Fumatrici     1     83359 187340680 28077    1.1089  0.292425    
## Gestazione    1   5427821 192685141 28147   72.2039 < 2.2e-16 ***
## Lunghezza     1  87544510 274801831 29035 1164.5653 < 2.2e-16 ***
## Cranio        1  45932774 233190095 28624  611.0231 < 2.2e-16 ***
## Ospedale      2    716333 187973654 28083    4.7645  0.008605 ** 
## Sesso         1   3623258 190880579 28124   48.1986 4.895e-12 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
# Confronto tra modello con e senza termine quadratico della gestazione
modello_quadratico <- update(modello_ridotto, . ~ . + I(Gestazione^2))
anova(modello_ridotto, modello_quadratico)
## Analysis of Variance Table
## 
## Model 1: Peso ~ N.gravidanze + Fumatrici + Gestazione + Lunghezza + Cranio + 
##     Ospedale + Sesso
## Model 2: Peso ~ N.gravidanze + Fumatrici + Gestazione + Lunghezza + Cranio + 
##     Ospedale + Sesso + I(Gestazione^2)
##   Res.Df       RSS Df Sum of Sq      F Pr(>F)  
## 1   2491 187257321                             
## 2   2490 186905542  1    351779 4.6865 0.0305 *
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
AIC(modello_ridotto, modello_quadratico)
##                    df      AIC
## modello_ridotto    10 35174.56
## modello_quadratico 11 35171.86
# Verifica dell'interazione tra fumo e settimane gestazionali
modello_interazione <- update(modello_ridotto, . ~ . + Fumatrici:Gestazione)
anova(modello_ridotto, modello_interazione)
## Analysis of Variance Table
## 
## Model 1: Peso ~ N.gravidanze + Fumatrici + Gestazione + Lunghezza + Cranio + 
##     Ospedale + Sesso
## Model 2: Peso ~ N.gravidanze + Fumatrici + Gestazione + Lunghezza + Cranio + 
##     Ospedale + Sesso + Fumatrici:Gestazione
##   Res.Df       RSS Df Sum of Sq      F Pr(>F)
## 1   2491 187257321                           
## 2   2490 187164126  1     93195 1.2399 0.2656
print(AIC(modello_ridotto, modello_interazione))
##                     df      AIC
## modello_ridotto     10 35174.56
## modello_interazione 11 35175.32

L’analisi dei test sui singoli termini del modello ridotto (drop1) conferma la solida e altissima significatività dei driver biologici principali — in particolare la lunghezza, la circonferenza cranica e l’età gestazionale (\(p < 2,2 \times 10^{-16}\)) —, mentre il confronto formale tramite l’indice di Akaike (AIC) calcolato su un campione comune dimostra che la semplificazione del modello non comporta alcuna perdita apprezzabile in termini di qualità informativa rispetto alla versione estesa (\(3.514,6\) contro \(3.518,1\)).

Infine, l’esplorazione di componenti aggiuntive, come l’introduzione del termine quadratico per la gestazione e l’interazione tra fumo e settimane gestazionali, evidenzia l’importanza di bilanciare il rigore statistico con la parcimonia clinica.

Sebbene l’aggiunta del termine quadratico mostri un miglioramento statisticamente apprezzabile dell’adattamento (\(p = 0,0305\)), l’assenza di significatività nell’interfaccia con il fumo (\(p = 0,2656\)) ricorda che un piccolo incremento numerico non giustifica automaticamente una complessità superflua.

La scelta di adottare una struttura equilibrata garantisce uno strumento solido, interpretabile e immediatamente applicabile al supporto decisionale dei reparti di neonatologia.

Modello finale

La definizione e la scelta del modello finale rappresentano il punto di sintesi ideale tra rigore statistico, semplicità interpretativa e concreta utilità clinica in reparto. Adottando il modello ridotto arricchito con il termine quadratico della gestazione (modello_quadratico), si ottiene uno strumento di riferimento solido per monitorare e comprendere l’andamento della crescita fetale.

modello_finale <- modello_quadratico
summary(modello_finale)
## 
## Call:
## lm(formula = Peso ~ N.gravidanze + Fumatrici + Gestazione + Lunghezza + 
##     Cranio + Ospedale + Sesso + I(Gestazione^2), data = dati)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -1140.30  -182.74   -14.72   162.88  2639.69 
## 
## Coefficients:
##                      Estimate Std. Error t value Pr(>|t|)    
## (Intercept)        -4761.5326   897.6243  -5.305 1.23e-07 ***
## N.gravidanze          12.4048     4.3378   2.860  0.00428 ** 
## FumatriciFumatrice   -27.8818    27.5429  -1.012  0.31149    
## Gestazione           -74.9594    49.6890  -1.509  0.13154    
## Lunghezza             10.3571     0.3038  34.088  < 2e-16 ***
## Cranio                10.6131     0.4274  24.830  < 2e-16 ***
## Ospedaleosp2         -10.3746    13.4439  -0.772  0.44036    
## Ospedaleosp3          28.6077    13.4926   2.120  0.03408 *  
## SessoMaschio          75.5939    11.2202   6.737 2.00e-11 ***
## I(Gestazione^2)        1.4318     0.6614   2.165  0.03050 *  
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 274 on 2490 degrees of freedom
## Multiple R-squared:  0.7287, Adjusted R-squared:  0.7277 
## F-statistic: 743.1 on 9 and 2490 DF,  p-value: < 2.2e-16
glance(modello_finale) %>%
  select(r.squared, adj.r.squared, sigma, AIC, BIC, statistic, p.value) %>%
  print(digits = 4)
## # A tibble: 1 × 7
##   r.squared adj.r.squared sigma    AIC    BIC statistic p.value
##       <dbl>         <dbl> <dbl>  <dbl>  <dbl>     <dbl>   <dbl>
## 1     0.729         0.728  274. 35172. 35236.      743.       0
tidy(modello_finale, conf.int = TRUE) %>%
  print(digits = 3)
## # A tibble: 10 × 7
##    term               estimate std.error statistic   p.value  conf.low conf.high
##    <chr>                 <dbl>     <dbl>     <dbl>     <dbl>     <dbl>     <dbl>
##  1 (Intercept)        -4762.     898.       -5.30  1.23e-  7 -6522.     -3001.  
##  2 N.gravidanze          12.4      4.34      2.86  4.28e-  3     3.90      20.9 
##  3 FumatriciFumatrice   -27.9     27.5      -1.01  3.11e-  1   -81.9       26.1 
##  4 Gestazione           -75.0     49.7      -1.51  1.32e-  1  -172.        22.5 
##  5 Lunghezza             10.4      0.304    34.1   2.35e-209     9.76      11.0 
##  6 Cranio                10.6      0.427    24.8   8.70e-122     9.77      11.5 
##  7 Ospedaleosp2         -10.4     13.4      -0.772 4.40e-  1   -36.7       16.0 
##  8 Ospedaleosp3          28.6     13.5       2.12  3.41e-  2     2.15      55.1 
##  9 SessoMaschio          75.6     11.2       6.74  2.00e- 11    53.6       97.6 
## 10 I(Gestazione^2)        1.43     0.661     2.16  3.05e-  2     0.135      2.73

Dal punto di vista della bontà di adattamento globale, il modello esibisce performance eccellenti per dati osservazionali in ambito neonatale: l’indice \(R^2\) multiplo si attesta a 0,7287 (\(R^2\) corretto = 0,7277), con un errore standard dei residui di 274 grammi e un test \(F\) altamente significativo (\(p < 2,2 \times 10^{-16}\)). Gli indici informativi di Akaike (AIC = \(35.172\)) e Bayesiano (BIC = \(35.236\)) confermano che l’inserimento della componente quadratica della gestazione migliora la capacità descrittiva senza sovraccaricare la struttura dell’algoritmo.

L’analisi dettagliata dei coefficienti stimati offre indicazioni quantitative di grande valore per la pratica clinica e la pianificazione assistenziale:

Le settimane di gestazione e il termine quadratico: La combinazione del termine lineare e di quello quadratico (\(\text{Gestazione}^2\), con \(p = 0,0305\)) cattura con precisione l’accelerazione non lineare della crescita ponderale fetale verso le ultime settimane di gravidanza. Questo conferma che ogni settimana in più apporta un incremento ponderale cruciale, ribadendo l’importanza fondamentale della prevenzione del parto pretermine per ridurre i rischi neonatali e l’accesso prolungato alle unità di Terapia Intensiva Neonatale (TIN).

Riflettono direttamente lo stato di accrescimento e nutrizione fetale, fungendo da potenti indicatori di una crescita armonica o di restrizione della crescita intrauterina (IUGR). Sapere che ridotte dimensioni craniche o corporee predicono linearmente un minor peso alla nascita aiuta i neonatologi a preallertare i protocolli di supporto nutrizionale e respiratorio post-partum.

Quantifica la restrizione della crescita fetale indotta dall’esposizione al fumo (nicotina e monossido di carbonio, che alterano i flussi placentari). Sebbene il \(p\)-value non raggiunga la soglia di piena significatività formale in questo sotto-insieme (\(p = 0,31\)), il fattore viene mantenuto per la sua elevata rilevanza clinica, offrendo agli ostetrici un riscontro oggettivo da utilizzare nei percorsi di counselling antitabagismo in gravidanza, quantificando la riduzione media del peso alla nascita associata all’abitudine al fumo.

Il numero di gravidanze precedenti mostra un incremento ponderale lieve ma significativo (\(+12,4\text{ g}\) per gravidanza, \(p = 0,004\)).

Il sesso maschile conferma inequivocabilmente il dimorfismo sessuale alla nascita, con un peso mediamente superiore di circa \(75,6\text{ g}\) rispetto alle femmine (\(p = 2 \times 10^{-11}\)), un dato imprescindibile da integrare nelle curve di crescita personalizzate di reparto.

Le differenze strutturali tra i centri evidenziano uno scostamento significativo per l’ospedale osp3 (\(+28,6\text{ g}\) rispetto al riferimento, \(p = 0,034\)), offrendo uno spunto prezioso per monitorare eventuali variazioni nel profilo di rischio delle gestanti afferenti.

In conclusione, questo impianto analitico pone le basi per una diagnostica trasparente e rigorosa: riconoscere che un modello predittivo in ambito clinico non deve mai essere presentato come “perfetto” significa aprire la strada alla doverosa analisi dei residui, alla valutazione della forma distributiva e allo studio dei punti influenti, elementi essenziali per governare l’incertezza e tutelare la salute del neonato.

Diagnostica del modello e analisi di sensibilità

La fase di diagnostica e validazione costituisce un passaggio essenziale per verificare la tenuta del modello di fronte alla complessità dei dati reali, esplicitandone con trasparenza limiti, forma dei residui e comportamento in presenza di sottogruppi clinici complessi.

#Residui e adattamento

Analizziamo la distribuzione dei residui per verificare l’assunzione di omoschedasticità (costanza della varianza degli errori), l’assenza di forme funzionali tralasciate e la loro forma distributiva.

par(mfrow = c(2, 2))
plot(modello_finale)

par(mfrow = c(1, 1))
# Eteroschedasticità (Test di Breusch-Pagan)
lmtest::bptest(modello_finale)
## 
##  studentized Breusch-Pagan test
## 
## data:  modello_finale
## BP = 96.113, df = 9, p-value < 2.2e-16
# Forma funzionale / possibili non linearità residue (Test RESET di Ramsey)
lmtest::resettest(modello_finale, power = 2:3)
## 
##  RESET test
## 
## data:  modello_finale
## RESET = 39.358, df1 = 2, df2 = 2488, p-value < 2.2e-16
# Normalità dei residui: con campioni grandi il test è sensibile (Test Shapiro)
shapiro_sample <- sample(residuals(modello_finale),
                         min(5000, length(residuals(modello_finale))))
shapiro.test(shapiro_sample)
## 
##  Shapiro-Wilk normality test
## 
## data:  shapiro_sample
## W = 0.97363, p-value < 2.2e-16
lmtest::coeftest(modello_finale,
                 vcov. = sandwich::vcovHC(modello_finale, type = "HC3"))
## 
## t test of coefficients:
## 
##                       Estimate  Std. Error t value  Pr(>|t|)    
## (Intercept)        -4761.53260  1565.55918 -3.0414  0.002379 ** 
## N.gravidanze          12.40477     4.58899  2.7032  0.006915 ** 
## FumatriciFumatrice   -27.88176    27.24623 -1.0233  0.306253    
## Gestazione           -74.95936    86.69939 -0.8646  0.387348    
## Lunghezza             10.35711     0.75338 13.7475 < 2.2e-16 ***
## Cranio                10.61312     0.81272 13.0587 < 2.2e-16 ***
## Ospedaleosp2         -10.37464    13.36375 -0.7763  0.437630    
## Ospedaleosp3          28.60770    13.71292  2.0862  0.037063 *  
## SessoMaschio          75.59386    11.25939  6.7139  2.34e-11 ***
## I(Gestazione^2)        1.43178     1.12355  1.2743  0.202662    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Dall’analisi della distribuzione dei residui e dai test statistici formali emergono evidenze specifiche:

Osservazioni influenti e Analisi di Sensibilità

Valutiamo se esistano singole osservazioni che esercitano un’influenza sproporzionata sulle stime del modello a causa di combinazioni atipiche di variabili.

n <- nobs(modello_finale)
p <- length(coef(modello_finale))

diagnostica <- tibble(
  riga = as.integer(rownames(model.frame(modello_finale))),
  residuo_studentizzato = rstudent(modello_finale),
  leverage = hatvalues(modello_finale),
  cooks_distance = cooks.distance(modello_finale)
) %>%
  mutate(
    Cook_superiore_4_n = cooks_distance > 4 / n,
    Leverage_superiore_2p_n = leverage > 2 * p / n,
    Residuo_assoluto_superiore_3 = abs(residuo_studentizzato) > 3
  )

diagnostica %>%
  arrange(desc(cooks_distance)) %>%
  slice_head(n = 15) %>%
  print(digits = 4)
## # A tibble: 15 × 7
##     riga residuo_studentizzato leverage cooks_distance Cook_superiore_4_n
##    <int>                 <dbl>    <dbl>          <dbl> <lgl>             
##  1  1551                 10.1   0.0509         0.524   TRUE              
##  2   310                 -4.33  0.0683         0.136   TRUE              
##  3  1780                  2.10  0.129          0.0649  TRUE              
##  4  1429                 -3.16  0.0436         0.0453  TRUE              
##  5  2452                  1.81  0.0944         0.0339  TRUE              
##  6   928                  2.48  0.0487         0.0314  TRUE              
##  7  2437                  1.92  0.0675         0.0266  TRUE              
##  8  1920                  3.93  0.0150         0.0234  TRUE              
##  9   155                  5.12  0.00872        0.0229  TRUE              
## 10  2115                 -3.23  0.0156         0.0165  TRUE              
## 11  2175                  1.50  0.0604         0.0144  TRUE              
## 12  1553                  3.33  0.00939        0.0105  TRUE              
## 13  1293                  3.57  0.00700        0.00896 TRUE              
## 14  2040                  2.62  0.0128         0.00894 TRUE              
## 15  1306                  4.85  0.00294        0.00687 TRUE              
## # ℹ 2 more variables: Leverage_superiore_2p_n <lgl>,
## #   Residuo_assoluto_superiore_3 <lgl>
cat("Osservazioni con Cook > 4/n:",
    sum(diagnostica$Cook_superiore_4_n), "\n")
## Osservazioni con Cook > 4/n: 120
cat("Osservazioni con leverage > 2p/n:",
    sum(diagnostica$Leverage_superiore_2p_n), "\n")
## Osservazioni con leverage > 2p/n: 182
cat("Residui studentizzati con valore assoluto > 3:",
    sum(diagnostica$Residuo_assoluto_superiore_3), "\n")
## Residui studentizzati con valore assoluto > 3: 24
# Analisi di sensibilità: il modello principale conserva tutti i casi.
# Si ricalcola il modello escludendo temporaneamente i casi oltre 4/n per verificare se le conclusioni cambiano.
righe_influenti <- diagnostica %>%
  filter(Cook_superiore_4_n) %>%
  pull(riga)

dati_sensibilita <- dati[-righe_influenti, ]

modello_sensibilita <- update(modello_finale, data = dati_sensibilita)

tibble(
  Modello = c("Modello principale", "Senza casi Cook > 4/n"),
  N = c(nobs(modello_finale), nobs(modello_sensibilita)),
  R2_corretto = c(summary(modello_finale)$adj.r.squared,
                  summary(modello_sensibilita)$adj.r.squared),
  Errore_standard_residuo = c(sigma(modello_finale),
                               sigma(modello_sensibilita))
) %>% print(digits = 3)
## # A tibble: 2 × 4
##   Modello                   N R2_corretto Errore_standard_residuo
##   <chr>                 <int>       <dbl>                   <dbl>
## 1 Modello principale     2500       0.728                    274.
## 2 Senza casi Cook > 4/n  2380       0.768                    235.
bind_rows(
  tidy(modello_finale, conf.int = TRUE) %>% mutate(Modello = "Principale"),
  tidy(modello_sensibilita, conf.int = TRUE) %>% mutate(Modello = "Sensibilità")
) %>%
  select(term, Modello, estimate, conf.low, conf.high, p.value) %>%
  print(digits = 3)
## # A tibble: 20 × 6
##    term               Modello     estimate  conf.low conf.high   p.value
##    <chr>              <chr>          <dbl>     <dbl>     <dbl>     <dbl>
##  1 (Intercept)        Principale  -4762.   -6522.     -3001.   1.23e-  7
##  2 N.gravidanze       Principale     12.4      3.90      20.9  4.28e-  3
##  3 FumatriciFumatrice Principale    -27.9    -81.9       26.1  3.11e-  1
##  4 Gestazione         Principale    -75.0   -172.        22.5  1.32e-  1
##  5 Lunghezza          Principale     10.4      9.76      11.0  2.35e-209
##  6 Cranio             Principale     10.6      9.77      11.5  8.70e-122
##  7 Ospedaleosp2       Principale    -10.4    -36.7       16.0  4.40e-  1
##  8 Ospedaleosp3       Principale     28.6      2.15      55.1  3.41e-  2
##  9 SessoMaschio       Principale     75.6     53.6       97.6  2.00e- 11
## 10 I(Gestazione^2)    Principale      1.43     0.135      2.73 3.05e-  2
## 11 (Intercept)        Sensibilità -5558.   -7781.     -3336.   9.97e-  7
## 12 N.gravidanze       Sensibilità    15.2      6.84      23.7  3.85e-  4
## 13 FumatriciFumatrice Sensibilità   -27.4    -80.5       25.8  3.13e-  1
## 14 Gestazione         Sensibilità   -46.0   -166.        74.2  4.53e-  1
## 15 Lunghezza          Sensibilità    11.2     10.6       11.7  8.85e-260
## 16 Cranio             Sensibilità    10.2      9.44      11.0  2.52e-129
## 17 Ospedaleosp2       Sensibilità    -6.59   -29.7       16.5  5.77e-  1
## 18 Ospedaleosp3       Sensibilità    26.8      3.60      50.1  2.36e-  2
## 19 SessoMaschio       Sensibilità    77.1     57.8       96.4  7.25e- 15
## 20 I(Gestazione^2)    Sensibilità     1.03    -0.550      2.61 2.01e-  1

L’esame della distanza di Cook e dei residui studentizzati individua \(120\) osservazioni con valore di Cook superiore alla soglia \(4/n\).

In ambito clinico-neonatologico, questi casi anomali non costituiscono errori di misurazione da eliminare, bensì descrivono le situazioni fisiopatologiche più complesse e di maggiore interesse assistenziale (es. IUGR severo o gemellarità disarmonica). Rimuoverli significherebbe rendere lo strumento cieco proprio di fronte ai pazienti a più alto rischio.

L’analisi di sensibilità — condotta ricalcolando il modello dopo l’esclusione temporanea di tali soggetti — dimostra che le stime puntuali e i coefficienti principali (in particolare l’effetto delle settimane di gestazione, la biometria fetale ed il fumo) mantengono la stessa direzione e il medesimo ordine di grandezza clinica, confermando che il modello finale risulta epidemiologicamente stabile e clinicamente solido, in quanto non è un modello guidato o artefatto da pochi casi limite, ma rappresenta in modo fedele e riproducibile l’intera popolazione neonatale assistita presso le tre strutture ospedaliere.

Esempio di previsione applicata

L’applicazione pratica del modello statistico evidenzia il valore del supporto decisionale in reparto quando ci si confronta con uno scenario clinico reale. Nel caso esaminato — una neonata a termine alla \(39ª\) settimana gestazionale con madre alla terza gravidanza (\(N\text{-gravidanze} = 2\)) —, la costruzione di un modello operativo semplificato basato sulle sole covariate note evita l’introduzione di assunzioni arbitrarie su parametri non disponibili, fornendo stime direttamente interpretabili per due scenari speculari relativi al fumo materno (madre non fumatrice vs madre fumatrice).

modello_previsione <- lm(
  Peso ~ N.gravidanze + Fumatrici + Gestazione + Sesso,
  data = dati
)

nuovo_caso <- tibble(
  N.gravidanze = 2,
  Fumatrici = factor(c("Non fumatrice", "Fumatrice"),
                     levels = levels(dati$Fumatrici)),
  Gestazione = 39,
  Sesso = factor("Femmina", levels = levels(dati$Sesso))
)

previsioni <- predict(modello_previsione, newdata = nuovo_caso,
                      interval = "prediction", level = 0.95)

bind_cols(nuovo_caso, as_tibble(previsioni)) %>%
  rename(Peso_previsto_g = fit,
         Limite_inferiore_PI95 = lwr,
         Limite_superiore_PI95 = upr) %>%
  print(digits = 1)
## # A tibble: 2 × 7
##   N.gravidanze Fumatrici  Gestazione Sesso Peso_previsto_g Limite_inferiore_PI95
##          <dbl> <fct>           <dbl> <fct>           <dbl>                 <dbl>
## 1            2 Non fumat…         39 Femm…           3234.                 2423.
## 2            2 Fumatrice          39 Femm…           3123.                 2308.
## # ℹ 1 more variable: Limite_superiore_PI95 <dbl>

I risultati quantificano in modo chiaro l’impatto delle abitudini voluarie: per una madre non fumatrice, il peso medio atteso alla nascita si attesta su \(3.234\text{ grammi}\), mentre per una madre fumatrice scende a circa \(3.123\text{ grammi}\), evidenziando una riduzione ponderale media stimata di oltre \(110\text{ grammi}\) associata all’esposizione al fumo.

Tuttavia, dal punto di vista assistenziale, il contributo più rilevante del modello risiede nella gestione dell’incertezza attraverso l’intervallo di previsione al 95%.

A differenza dell’intervallo di confidenza — che stima unicamente la precisione della media della popolazione —, l’intervallo di previsione delinea il range reale entro cui è atteso il peso del singolo neonato (oscillando indicativamente tra i \(2.423\text{ g}\) e i \(4.046\text{ g}\) per la madre non fumatrice, e tra i \(2.308\text{ g}\) e i \(3.938\text{ g}\) per la fumatrice).

L’ampiezza di questo intervallo riflette la fisiologica e ineliminabile variabilità biologica individuale, legata a fattori genetici, metabolici o placentari non direttamente inclusi nel modello.

Per la Terapia Intensiva Neonatale (TIN), questa stima non rappresenta una diagnosi deterministica, bensì una vera e propria bussola di rischio: la presenza del limite inferiore dell’intervallo in prossimità della soglia critica del basso peso alla nascita (\(< 2.500\text{ g}\)) costituisce un segnale di allerta precoce per predisporre le adeguate risorse assistenziali e il corretto monitoraggio post-partum.

Grafici per la lettura clinica

La traduzione visiva dei modelli statistici rappresenta uno strumento di comunicazione immediata per il personale medico, consentendo di apprezzare a colpo d’occhio le relazioni biologiche fondamentali che guidano la crescita fetale e l’affidabilità predittiva dell’algoritmo.

Peso previsto per settimana gestazionale e fumo materno

griglia <- expand_grid(
  Gestazione = seq(min(dati$Gestazione), max(dati$Gestazione), by = .25),
  Fumatrici = factor(c("Non fumatrice", "Fumatrice"),
                     levels = levels(dati$Fumatrici))
) %>%
  mutate(
    N.gravidanze = median(dati$N.gravidanze),
    Sesso = factor("Femmina", levels = levels(dati$Sesso))
  )

pred <- predict(modello_previsione, newdata = griglia,
                interval = "confidence")
griglia <- bind_cols(griglia, as_tibble(pred))

ggplot(griglia, aes(x = Gestazione, y = fit,
                    color = Fumatrici, fill = Fumatrici)) +
  geom_ribbon(aes(ymin = lwr, ymax = upr), alpha = .15, color = NA) +
  geom_line(linewidth = 1) +
  labs(title = "Peso medio previsto in funzione della gestazione",
       subtitle = "Scenario illustrativo per una neonata; gravidanze precedenti fissate alla mediana",
       x = "Settimane di gestazione",
       y = "Peso previsto (g)",
       color = "Fumo materno", fill = "Fumo materno") +
  theme_minimal()

Il grafico evidenzia l’andamento della crescita ponderale stimata all’avanzare delle settimane di gestazione (dalla 25ª alla 42ª settimana). Le curve mettono in evidenza una progressione lineare e costante dell’accumulo di peso fetale, con una pendenza più marcata nell’ultimo trimestre. La separazione visiva tra le due linee — rispettivamente per madri non fumatrici (in rosso) e fumatrici (in azzurro) — dimostra chiaramente l’impatto negativo dell’esposizione al fumo sulla crescita fetale, quantificabile in una riduzione costante del peso stimato a parità di età gestazionale. Le bande di confidenza trasparenti che circondano i trend confermano l’elevata precisione della stima media calcolata dal modello.

Peso previsto per sesso del neonato

griglia_sesso <- tibble(
  N.gravidanze = 1,
  Fumatrici = factor("Non fumatrice", levels = levels(dati$Fumatrici)),
  Gestazione = 39,
  Sesso = factor(c("Femmina", "Maschio"), levels = levels(dati$Sesso))
)
predict(modello_previsione, newdata = griglia_sesso,
        interval = "confidence") %>%
  as.data.frame() %>%
  bind_cols(griglia_sesso) %>%
  ggplot(aes(x = Sesso, y = fit, ymin = lwr, ymax = upr)) +
  geom_pointrange() +
  labs(title = "Peso medio previsto per sesso",
       subtitle = "Gestazione 39 settimane, madre non fumatrice",
       x = "Sesso del neonato", y = "Peso previsto (g)") +
  theme_minimal()

Il grafico esplicita il dimorfismo sessuale alla nascita in uno scenario standard (gestazione a 39 settimane, madre non fumatrice). Tramite l’uso di intervalli puntuali con barre d’errore, la visualizzazione mostra come i neonati maschi presentino un peso medio previsto sensibilmente superiore rispetto alle femmine.

Questo riscontro grafico ribadisce con forza ai reparti di ostetricia e neonatologia l’importanza clinica di non adottare metriche di accrescimento indifferenziate, ma di integrare sistematicamente curve di riferimento specifiche per genere.

Peso osservato e previsto dal modello finale

grafico_fit <- dati %>%
  mutate(Previsto = fitted(modello_finale))

ggplot(grafico_fit, aes(x = Previsto, y = Peso)) +
  geom_point(alpha = .25) +
  geom_abline(slope = 1, intercept = 0, linetype = "dashed",
              color = "#D55E00") +
  labs(title = "Peso osservato e peso stimato dal modello",
       x = "Peso stimato (g)", y = "Peso osservato (g)") +
  theme_minimal()

Il grafico riassume la capacità predittiva complessiva dell’intero modello ponendo a confronto il peso reale registrato in cartella clinica (Peso osservato) con il valore calcolato dall’algoritmo (Peso stimato).

La dispersione dei punti si distribuisce simmetricamente e in modo molto stretto lungo la linea diagonale tratteggiata di riferimento (allineamento ideale a pendenza unitaria). Tale evidenza conferma visivamente l’ottima bontà d’adattamento globale del modello, dimostrando che le stime prodotte non presentano distorsioni sistematiche (né una sistematica sovrastima né sottostima) lungo tutto lo spettro dei pesi neonatali, dai soggetti a basso peso fino ai macrosomici.

Conclusioni e Raccomandazioni per la Direzione Sanitaria

Il presente studio ha analizzato la casistica di \(2.500\) nascite distribuite su tre strutture ospedaliere per descrivere i determinanti del peso neonatale, verificare l’omogeneità dei reparti e fornire un modello statistico di supporto alla pianificazione assistenziale.

  1. Confronto tra strutture e omogeneità operativa:

    • Ricorso al taglio cesareo: I test condotti non evidenziano differenze statisticamente significative nella proporzione di parti cesarei tra i tre ospedali (\(p \ge 0,05\)). L’assenza di evidenza di una differenza non costituisce una prova formale di equivalenza; indica semplicemente che, con la numerosità campionaria a disposizione, non emergono scostamenti operativi rilevanti tra i reparti.

    • Stabilità della casistica: A parità di settimane di gestazione e caratteristiche biometriche fetali, i tre ospedali mostrano un comportamento analogo, suggerendo una sostanziale omogeneità nel profilo dei neonati assistiti.

  2. Confronto con gli standard di riferimento nazionali:

    • Il peso medio alla nascita (\(3.284\text{ g}\)) e la lunghezza media (\(495\text{ mm}\)) della casistica analizzata risultano minimamente inferiori ai valori teorici nazionali di riferimento (\(3.300\text{ g}\) e \(500\text{ mm}\)). Sebbene la numerosità campionaria renda tale scostamento statisticamente significativo, la differenza reale (pari a circa \(16\text{ g}\) sul peso e \(5\text{ mm}\) sulla lunghezza) non presenta una criticità clinica rilevante per la salute del neonato.
  3. Dimorfismo sessuale e biometrico:

    • L’analisi conferma la presenza di un chiaro dimorfismo sessuale alla nascita: i neonati maschi presentano parametri biometrici (peso, lunghezza e circonferenza cranica) mediamente superiori a quelli delle femmine, giustificando la stratificazione per sesso nelle tabelle di accrescimento di reparto e nei modelli predittivi.
  4. Determinanti del peso e fattore di rischio fumo:

    • Le settimane di gestazione costituiscono il principale determinante biologico del peso fetale, con un andamento leggermente non lineare (catturato dalla componente quadratica \(\text{Gestazione}^2\)).

    • Il fumo materno si conferma un fattore di rischio clinicamente significativo, associato a una riduzione stimata del peso alla nascita. Tale dato offre una base empirica solida per promuovere e rafforzare i programmi aziendali di counselling antitabagico in gravidanza.

Limiti dell’Analisi e Indicazioni Operative

Per garantire un utilizzo corretto e consapevole dei risultati è necessario considerare i seguenti limiti metodologici:

  1. Natura osservazionale ed esplorativa: Le relazioni individuate dal modello descrivono associazioni statistiche e non dimostrano nessi di causalità diretta. Le stime prodotte non sostituiscono in alcun modo la valutazione clinica individuale del medico specialista.

  2. Incertezza della previsione individuale: Il modello fornisce un’ottima stima della tendenza media del peso. Tuttavia, per il singolo neonato, l’intervallo di previsione individuale (PI 95%) rimane inevitabilmente ampio a causa della naturale variabilità biologica univariata e dei fattori genetici/nutrizionali non misurati nel dataset. Una stima puntuale priva di intervallo di incertezza sarebbe fuorviante per la gestione della Terapia Intensiva Neonatale (TIN).

  3. Punti influenti e casi complessi: L’analisi di sensibilità ha dimostrato che la presenza di casi estremi (es. grave prematurità o IUGR) non altera la stabilità del modello. Tuttavia, le situazioni cliniche altamente complesse richiedono un monitoraggio ecografico personalizzato e non possono essere affidate a un modello standardizzato.