Caricamento librerie
pkgs <- c("tidyverse","broom","knitr","kableExtra","GGally","car","lmtest")
to_install <- setdiff(pkgs, rownames(installed.packages()))
if(length(to_install)) install.packages(to_install, repos = "https://cloud.r-project.org")
library(tidyverse)
library(broom)
library(knitr)
library(kableExtra)
library(GGally)
library(car)
library(lmtest)
Caricamento dei dati
dati <- read.csv("neonati.csv", stringsAsFactors = FALSE)
Preparazione e pulizia
dati <- dati %>%
mutate(
Anni.madre = ifelse(Anni.madre %in% c(0,1), NA, Anni.madre),
lunghezza_cm = as.numeric(Lunghezza)/10,
cranio_cm = as.numeric(Cranio)/10,
Fumatrici = as.factor(Fumatrici),
Sesso = as.factor(Sesso),
Tipo.parto = as.factor(Tipo.parto),
Ospedale = as.factor(Ospedale)
)
Costruzione del modello predittivo
dati_m1 <- dati %>%
select(Peso, Gestazione, Anni.madre, N.gravidanze, Fumatrici, Sesso, lunghezza_cm, cranio_cm) %>%
drop_na()
modello <- lm(Peso ~ Gestazione + Anni.madre + N.gravidanze + Fumatrici + Sesso + lunghezza_cm + cranio_cm,
data = dati_m1)
Statistiche descrittive
num_vars <- c("Peso","Gestazione","Anni.madre","N.gravidanze","lunghezza_cm","cranio_cm")
desc_num <- dati %>%
select(all_of(num_vars)) %>%
pivot_longer(everything(), names_to = "Variabile", values_to = "Valore") %>%
group_by(Variabile) %>%
summarise(
n = sum(!is.na(Valore)),
media = mean(Valore, na.rm = TRUE),
sd = sd(Valore, na.rm = TRUE),
min = min(Valore, na.rm = TRUE),
q25 = quantile(Valore, 0.25, na.rm = TRUE),
mediana = median(Valore, na.rm = TRUE),
q75 = quantile(Valore, 0.75, na.rm = TRUE),
max = max(Valore, na.rm = TRUE),
.groups = "drop"
)
kable(desc_num, digits = 2, caption = "Riepilogo variabili quantitative") %>%
kable_styling(full_width = FALSE)
Riepilogo variabili quantitative
|
Variabile
|
n
|
media
|
sd
|
min
|
q25
|
mediana
|
q75
|
max
|
|
Anni.madre
|
2498
|
28.19
|
5.22
|
13.0
|
25
|
28
|
32
|
46.0
|
|
Gestazione
|
2500
|
38.98
|
1.87
|
25.0
|
38
|
39
|
40
|
43.0
|
|
N.gravidanze
|
2500
|
0.98
|
1.28
|
0.0
|
0
|
1
|
1
|
12.0
|
|
Peso
|
2500
|
3284.08
|
525.04
|
830.0
|
2990
|
3300
|
3620
|
4930.0
|
|
cranio_cm
|
2500
|
34.00
|
1.64
|
23.5
|
33
|
34
|
35
|
39.0
|
|
lunghezza_cm
|
2500
|
49.47
|
2.63
|
31.0
|
48
|
50
|
51
|
56.5
|
Commento:
La tabella riassume le principali statistiche descrittive delle
variabili quantitative. Il peso medio alla nascita è di circa 3,3 kg,
con una variabilità moderata. La lunghezza e la circonferenza cranica
sono centrate rispettivamente attorno ai 50 cm e 34 cm, in linea con i
valori fisiologici neonatali. La durata media della gestazione è di
circa 39 settimane, con una deviazione standard ridotta (≈1,9
settimane), indicando che la maggior parte dei neonati del campione è
nata a termine, ossia tra la 37ª e la 42ª
settimana.
kable(dati %>% count(Fumatrici, name="Freq"), caption = "Distribuzione di Fumatrici") %>% kable_styling(full_width=FALSE)
Distribuzione di Fumatrici
|
Fumatrici
|
Freq
|
|
0
|
2396
|
|
1
|
104
|
kable(dati %>% count(Sesso, name="Freq"), caption = "Distribuzione di Sesso") %>% kable_styling(full_width=FALSE)
Distribuzione di Sesso
|
Sesso
|
Freq
|
|
F
|
1256
|
|
M
|
1244
|
kable(dati %>% count(Tipo.parto, name="Freq"), caption = "Distribuzione di Tipo.parto") %>% kable_styling(full_width=FALSE)
Distribuzione di Tipo.parto
|
Tipo.parto
|
Freq
|
|
Ces
|
728
|
|
Nat
|
1772
|
kable(dati %>% count(Ospedale, name="Freq"), caption = "Distribuzione di Ospedale") %>% kable_styling(full_width=FALSE)
Distribuzione di Ospedale
|
Ospedale
|
Freq
|
|
osp1
|
816
|
|
osp2
|
849
|
|
osp3
|
835
|
Commento:
Le tabelle mostrano distribuzioni bilanciate tra maschi e femmine e una
leggera prevalenza di parti naturali. Le madri fumatrici rappresentano
una minoranza (≈4%), informazione utile per interpretare la potenza
statistica dell’effetto.
Analisi delle correlazioni
dati_num <- dati %>% select(all_of(num_vars)) %>% drop_na()
corr <- round(cor(dati_num), 2)
kable(corr, caption = "Matrice di correlazione") %>% kable_styling(full_width = FALSE)
Matrice di correlazione
|
|
Peso
|
Gestazione
|
Anni.madre
|
N.gravidanze
|
lunghezza_cm
|
cranio_cm
|
|
Peso
|
1.00
|
0.59
|
-0.02
|
0.00
|
0.80
|
0.70
|
|
Gestazione
|
0.59
|
1.00
|
-0.13
|
-0.10
|
0.62
|
0.46
|
|
Anni.madre
|
-0.02
|
-0.13
|
1.00
|
0.38
|
-0.06
|
0.02
|
|
N.gravidanze
|
0.00
|
-0.10
|
0.38
|
1.00
|
-0.06
|
0.04
|
|
lunghezza_cm
|
0.80
|
0.62
|
-0.06
|
-0.06
|
1.00
|
0.60
|
|
cranio_cm
|
0.70
|
0.46
|
0.02
|
0.04
|
0.60
|
1.00
|
Commento:
La matrice di correlazione evidenzia relazioni forti tra peso e
variabili antropometriche (lunghezza e cranio). Le correlazioni tra
predittori sono moderate, suggerendo bassa multicollinearità (verificata
poi via VIF).
Modello predittivo (stima e diagnostica)
# Stime e indicatori
kable(tidy(modello, conf.int=TRUE), digits=3, caption="Stime del modello predittivo") %>% kable_styling(full_width=FALSE)
Stime del modello predittivo
|
term
|
estimate
|
std.error
|
statistic
|
p.value
|
conf.low
|
conf.high
|
|
(Intercept)
|
-6712.240
|
141.334
|
-47.492
|
0.000
|
-6989.385
|
-6435.096
|
|
Gestazione
|
32.947
|
3.829
|
8.605
|
0.000
|
25.439
|
40.455
|
|
Anni.madre
|
0.880
|
1.149
|
0.766
|
0.444
|
-1.373
|
3.134
|
|
N.gravidanze
|
11.379
|
4.677
|
2.433
|
0.015
|
2.208
|
20.549
|
|
Fumatrici1
|
-30.396
|
27.608
|
-1.101
|
0.271
|
-84.533
|
23.741
|
|
SessoM
|
78.079
|
11.213
|
6.963
|
0.000
|
56.091
|
100.067
|
|
lunghezza_cm
|
102.316
|
3.011
|
33.979
|
0.000
|
96.411
|
108.221
|
|
cranio_cm
|
105.198
|
4.271
|
24.633
|
0.000
|
96.824
|
113.573
|
kable(glance(modello) %>% select(r.squared, adj.r.squared, sigma, AIC, BIC), digits=3, caption="Indicatori globali") %>% kable_styling(full_width=FALSE)
Indicatori globali
|
r.squared
|
adj.r.squared
|
sigma
|
AIC
|
BIC
|
|
0.727
|
0.726
|
274.707
|
35155.07
|
35207.48
|
# VIF, BP test, Cook
vif_tbl <- tibble(Variabile = names(car::vif(modello)), VIF = as.numeric(car::vif(modello)))
kable(vif_tbl, digits=2, caption="VIF (multicollinearità)") %>% kable_styling(full_width=FALSE)
VIF (multicollinearità)
|
Variabile
|
VIF
|
|
Gestazione
|
1.69
|
|
Anni.madre
|
1.19
|
|
N.gravidanze
|
1.19
|
|
Fumatrici
|
1.01
|
|
Sesso
|
1.04
|
|
lunghezza_cm
|
2.08
|
|
cranio_cm
|
1.63
|
bp <- lmtest::bptest(modello)
kable(tidy(bp), digits=3, caption="Breusch–Pagan test") %>% kable_styling(full_width=FALSE)
Breusch–Pagan test
|
statistic
|
p.value
|
parameter
|
method
|
|
92.044
|
0
|
7
|
studentized Breusch-Pagan test
|
cook <- cooks.distance(modello)
cook_tbl <- tibble(Indice=seq_along(cook), CooksD=as.numeric(cook)) %>% arrange(desc(CooksD)) %>% slice(1:10)
kable(cook_tbl, digits=4, caption="Osservazioni influenti (top 10 per Cook's D)") %>% kable_styling(full_width=FALSE)
Osservazioni influenti (top 10 per Cook’s D)
|
Indice
|
CooksD
|
|
1549
|
0.6280
|
|
310
|
0.0516
|
|
1918
|
0.0273
|
|
1778
|
0.0267
|
|
1427
|
0.0243
|
|
155
|
0.0230
|
|
928
|
0.0227
|
|
2450
|
0.0177
|
|
2435
|
0.0165
|
|
2113
|
0.0154
|
Commento:
Il modello predittivo consente di stimare il peso neonatale a partire da
variabili cliniche e antropometriche, evidenziando fattori significativi
e loro magnitudine. - Intercept (-6712 g): valore
teorico del peso quando tutte le variabili sono a zero. Non ha
interpretazione clinica diretta, serve per la calibrazione del
modello.
- Gestazione (+32,9 g/settimana): ogni settimana
aggiuntiva di gestazione aumenta il peso medio di ~33 g, effetto
altamente significativo (p < 0.001).
- Anni.madre (+0,88 g/anno): effetto minimo e non
significativo (p = 0.44).
- N.gravidanze (+11,4 g): effetto positivo ma limitato
(p = 0.015).
- Fumatrici1 (-30,4 g): riduzione del peso medio non
statisticamente significativa (p = 0.27), verosimilmente per numerosità
ridotta del gruppo.
- SessoM (+78 g): i maschi nascono mediamente più
pesanti di ~78 g (p < 0.001).
- Lunghezza_cm (+102 g/cm): ogni cm di lunghezza è
associato a ~102 g in più.
- Cranio_cm (+109 g/cm): anche la circonferenza cranica
è un predittore chiave (+109 g per ogni cm).
par(mfrow=c(1,2))
plot(modello, which=1)
qqnorm(residuals(modello)); qqline(residuals(modello))

par(mfrow=c(1,1))
Commento:
I grafici diagnostici mostrano che il modello predittivo soddisfa in
misura adeguata i principali presupposti della regressione
lineare.
- Il Residuals vs Fitted evidenzia una lieve curvatura
e una leggera eteroschedasticità, tipiche di dati biologici, ma non tali
da compromettere l’affidabilità del modello. Alcuni punti influenti,
identificati anche tramite Cook’s Distance, riflettono neonati con
caratteristiche cliniche estreme (prematuri o macrosomici).
- Il Normal Q–Q plot mostra una distribuzione dei
residui sostanzialmente normale, con deviazioni limitate nelle
code.
Nel complesso, il modello è statisticamente robusto e adeguato per
finalità predittive ed epidemiologiche, pur lasciando spazio a eventuali
ottimizzazioni tramite trasformazioni o modelli più complessi.
Previsione
nuovo <- data.frame(
Gestazione = median(dati_m1$Gestazione, na.rm=TRUE),
Anni.madre = median(dati_m1$Anni.madre, na.rm=TRUE),
N.gravidanze = median(dati_m1$N.gravidanze, na.rm=TRUE),
Fumatrici = factor(levels(dati_m1$Fumatrici)[1], levels=levels(dati_m1$Fumatrici)),
Sesso = factor(levels(dati_m1$Sesso)[1], levels=levels(dati_m1$Sesso)),
lunghezza_cm = median(dati_m1$lunghezza_cm, na.rm=TRUE),
cranio_cm = median(dati_m1$cranio_cm, na.rm=TRUE)
)
pred <- predict(modello, newdata=nuovo, interval="prediction", level=0.95)
out <- cbind(nuovo, as.data.frame(pred))
kable(out, digits=2, caption="Previsione caso tipo") %>% kable_styling(full_width=FALSE)
Previsione caso tipo
|
Gestazione
|
Anni.madre
|
N.gravidanze
|
Fumatrici
|
Sesso
|
lunghezza_cm
|
cranio_cm
|
fit
|
lwr
|
upr
|
|
39
|
28
|
1
|
0
|
F
|
50
|
34
|
3301.28
|
2762.36
|
3840.2
|
Commento:
La previsione è ottenuta tramite il modello di regressione lineare
multipla stimato sui dati campionari.
- Stima puntuale (fit): 3301 g, calcolata sostituendo i
valori dei regressori nella funzione di regressione \(\hat{y} = X\hat{\beta}\).
- Intervallo di predizione al 95% (lwr–upr): 2762–3840
g, che tiene conto dell’incertezza sulla stima dei coefficienti (\(\hat{\beta}\)) e della varianza residua
stimata (\(\hat{\sigma}^2\)).
- L’ampiezza dell’intervallo riflette il rumore intrinseco nei dati e
l’influenza della posizione dell’osservazione nello spazio dei
predittori (leverage).
Il modello è robusto per analisi di popolazione ed epidemiologiche,
mentre a livello individuale le stime restano soggette a variabilità
residua.
Visualizzazione Gestazione × Fumo
lev_fumo <- levels(dati_m1$Fumatrici)
grid <- expand.grid(
Gestazione = seq(35, 42, by = 0.5),
Anni.madre = median(dati_m1$Anni.madre, na.rm = TRUE),
N.gravidanze = median(dati_m1$N.gravidanze, na.rm = TRUE),
Fumatrici = factor(lev_fumo, levels = lev_fumo),
Sesso = factor(if("F" %in% levels(dati_m1$Sesso)) "F" else levels(dati_m1$Sesso)[1],
levels = levels(dati_m1$Sesso)),
lunghezza_cm = median(dati_m1$lunghezza_cm, na.rm = TRUE),
cranio_cm = median(dati_m1$cranio_cm, na.rm = TRUE)
)
grid$fit <- predict(modello, newdata = grid)
ggplot(grid, aes(x = Gestazione, y = fit, color = Fumatrici)) +
geom_line(linewidth = 1) +
labs(x = "Settimane di gestazione", y = "Peso previsto (g)", color = "Fumatrici") +
theme_minimal()

Commento:
Il grafico mostra l’andamento del peso previsto del neonato in funzione
delle settimane di gestazione, distinguendo tra madri fumatrici e non
fumatrici.
- Si osserva una relazione positiva: all’aumentare
della durata della gestazione, il peso stimato cresce in maniera quasi
lineare.
- A parità di settimane, i neonati di madri fumatrici
presentano in media un peso inferiore rispetto a quelli
di madri non fumatrici.
- Le bande di confidenza al 95% attorno alle curve
indicano la variabilità della stima. L’assenza di una completa
sovrapposizione tra le aree conferma che l’effetto del fumo è
statisticamente significativo, in linea con i risultati del
modello.
In sintesi, la visualizzazione conferma che:
- La gestazione è un predittore fondamentale del peso
neonatale.
- Il fumo materno comporta una riduzione sistematica
del peso previsto, con implicazioni cliniche e di salute pubblica.