6.6 Applicazioni
1) Tabella 6.1 fornisce i risultati di uno studio di coorte allo scopo di determinare, tra le altre cose, i vantaggi di utilizzare, come strumento di screening, test da sforzo (EST) misure. In tali test, un risultato pass / fail può essere derivato durante la diagnosi di malattie delle arterie coronarie (CAD) .
Tabella 6.1. Screening test for physical stress
CAD | ||||
---|---|---|---|---|
Healthy | Ill | Total | ||
EST | Negative | 327 | 208 | 535 |
Positive | 115 | 815 | 930 | |
Total | 442 | 1 023 | 1 465 |
Si presume che non vi sia alcun bias di verifica:
a)
Sulla base di questa matrice di confusione, indicare i seguenti valori (con intervalli di confidenza del 95%): sensibilità e specificità, valore predittivo positivo e negativo.
b)
Qual è il valore dell’area sotto la curva per i dati correnti?
La creazione della tabella dati può essere fatta come indicato di seguito, da una tabella creata con il comando matrix ():
>tab < – as.ping(matrix(c(815,115,208,327), nrow = 2, byrow = TRUE,
dimnames = list(EST = c(“+”,”−”),
CAD = c(“+”,”-”))))
> scheda
Si noti che la tabella è stata riorganizzata in modo da corrispondere alle solite notazioni, con gli eventi “positivi” sulla prima riga (in genere, l’esposizione) e la prima colonna (in genere, la malattia) della tabella.
Sarebbe quindi possibile calcolare tutte le quantità richieste utilizzando pochissime operazioni aritmetiche con R. Tuttavia, il pacchetto epiR contiene tutti gli strumenti necessari per rispondere alle domande epidemiologiche nelle tabelle 2 × 2. Quindi, il comando epi.tests () fornisce valori di prevalenza, sensibilità / specificità, nonché valori predittivi positivi e negativi:
>library(epiR)
> epi.test (tab)
Per quanto riguarda l’area sotto la curva, è possibile utilizzare anche un comando esterno, roc.da.tabella(), nel pacchetto epicalc:
> libreria(epicalc)
> roc.da.tabella (tab, grafico = FALSO)
2) Tabella 6.2 riassume la proporzione di infarti miocardici osservati negli uomini di età compresa tra 40 e 59 anni e per i quali sono stati misurati il livello di pressione sanguigna e il tasso di colesterolo, considerati sotto forma di classi ordinate .
Tabella 6.2. Infarto e pressione del sangue
Colesterolo (mg/100 ml) | |||||||
---|---|---|---|---|---|---|---|
PA | < 200 | 200 – 209 | 210 – 219 | 220 – 244 | 245 – 259 | 260 – 284 | > 284 |
< 117 | 2/53 | 0/21 | 0/15 | 0/20 | 0/14 | 1/22 | 0/11 |
117 – 126 | 0/66 | 2/27 | 1/25 | 8/69 | 0/24 | 5/22 | 1/19 |
127 – 136 | 2/59 | 0/34 | 2/21 | 2/83 | 0/33 | 2/26 | 4/28 |
137 – 146 | 1/65 | 0/19 | 0/26 | 6/81 | 3/23 | 2/34 | 4/23 |
147 – 156 | 2/37 | 0/16 | 0/6 | 3/29 | 2/19 | 4/16 | 1/16 |
157 – 166 | 1/13 | 0/10 | 0/11 | 1/15 | 0/11 | 2/13 | 4/12 |
167 – 186 | 3/21 | 0/5 | 0/11 | 2/27 | 2/5 | 6/16 | 3/14 |
> 186 | 1/5 | 0/1 | 3/6 | 1/10 | 1/7 | 1/7 | 1/7 |
The data are available in the file hdis.dat sotto forma di una tabella con quattro colonne che indicano, rispettivamente, la pressione sanguigna (otto categorie, valutato da 1 a 8), il tasso di colesterolo (sette categorie, valutato da 1 a 7), il numero di infarto miocardico e il numero totale di individui. L’associazione tra la pressione sanguigna e la probabilità di soffrire di un infarto miocardico è il punto di interesse:
a)
Calcola le proporzioni di infarto miocardico per ogni livello di pressione sanguigna e rappresentale in una tabella e in forma grafica;
b)
Esprimere le proporzioni calcolate in (a) in forma logit;
c)
Basato su un modello di regressione logistica, è necessario determinare se vi è una significativa associazione alla soglia α = 0.05 tra pressione arteriosa, trattata come una variabile quantitativa considerando la classe di centri e la probabilità di avere un attacco di cuore;
d)
Express in logit unità di misura la probabilità di infarto previsto dal modello per ciascuno dei livelli di pressione sanguigna;
e)
Display sullo stesso grafico empirica proporzioni e la regressione logistica curva secondo i valori della pressione sanguigna (classe i centri).
Importazione dei dati hdis.dat è raggiunto come di seguito:
> bp< – read.tabella (“hdis.dat”, header = TRUE)
> str(bp)
Come può essere verificato, non esiste un’etichetta associata ai livelli delle variabili di interesse (bpress per la pressione sanguigna, chol per il tasso di colesterolo). Per generare e associare etichette, è possibile inserire i seguenti comandi:
> blab < – c(“<117”,”117-126”,”127-136”,”137-146”,
“147-156”,”157-166”,”167-186”,”>186”)
> clab < – c(“<200”,”200-209”,”210-219”,”220-244”,
“245-259”,”260-284”,”>284”)
> bp$bpress < – factor(bp$bpress, labels = blab)
> bp$chol < – factor(bp cho chol, labels = clab)
L’ultimo comando converte le variabili originali in variabili qualitative e associa alle loro modalità le etichette definite da blab e clab. Per verificare che il database sia ora nella forma desiderata, sono utili i seguenti comandi:
> str(bp)
> summary(bp)
La tabella delle frequenze relative esposte nell’istruzione può ora essere riprodotta:
>round(xtabs(hdis/total bpress + chol, data = bp), 2)
Poiché ci concentreremo solo sulla relazione tra pressione sanguigna e infarto miocardico, è necessario aggregare i dati sui livelli di colesterolo. In altre parole, è necessario accumulare i valori per ciascun livello di pressione sanguigna, indipendentemente dai livelli di colesterolo. L’opportunità dovrebbe anche essere presa per rinominare i livelli della variabile bpress usando i centri degli intervalli di classe:
> blab2< – c(111.5,121.5,131.5,141.5,151.5,161.5,176.5,191.5)
> bp$bpress < rep(blab2, ogni = 7)
> dfrm < – aggregato(bp,
elenco(bpress = bp), somma)
e ‘ l’ultimo comando, di aggregazione(), che rende possibile l’aggregazione dei dati: è la somma di tutti i valori (somma) della variabile chol che non sono inclusi nell’elenco di variabili che devono essere mantenute per l’analisi. Allo stesso tempo, i risultati vengono memorizzati in un nuovo database denominato dfrm. Si noti che in questo caso non si fa uso della notazione della formula ma di quella della sintassi alternativa per aggregate () (variabile di risposta seguita da una lista composta da una o più variabili esplicative). Una panoramica dei dati aggregati può essere ottenuta dando head() come input:
> head(dfrm, 5)
Quando è disponibile una proporzione p, il suo valore su una scala le cui unità sono logits è dato dal log delle relazioni(p/(1 − p)). Da ciò i seguenti comandi possono essere derivati per convertire le proporzioni, calcolate come hdis / totale in unità logit:
> logit < – function(x) log(x/(1-x))
> dfrm$prop < dfrm$clive/dfrm$totale
> dfrm$logit < – logit(dfrm$clive/dfrm$totale)
Si deve osservare che una piccola funzione è stata definita per la conversione di valori x, che qui viene considerato un proporzioni, in un suo equivalente log(x/(1 − x)). Allo stesso modo, si potrebbe scrivere:
>log((dfrm hd hdis/dfrm total total)/(1-dfrm hd hdis/dfrm total total))
I valori calcolati sono stati aggiunti direttamente al frame dati con il nome prop e logit.
Il modello di regressione logistica è scritta nel modo seguente:
> glm(rbind(clive,totale-clive) bpress,dati = dfrm,family = binomial)
La formulazione utilizzata, rbind(clive, totale-clive) bpress, tiene conto del fatto che siamo l’accesso a dati raggruppati e non le singole risposte. Il comando glm () con l’opzione family = binomial corrisponde ad una regressione logistica, che, senza entrare molto nel dettaglio, utilizza per impostazione predefinita la funzione logit come collegamento canonico.
I coefficienti di regressione può essere visualizzato facendo uso di riepilogo():
> summary(glm(rbind(clive, totale-clive) bpress, dati = dfrm,
family = binomial))
Il risultato precedente comprende le informazioni essenziali per rispondere alla domanda della significatività statistica di associazione tra pressione arteriosa e il rischio di attacco di cuore: il coefficiente di regressione (sulla scala log-odds) è pari a 0,024 ed è significativo alla soglia usuale del 5% (vedi colonna Pr (>|z|)).
La probabilità di avere un attacco di cuore in base ai diversi livelli di pressione sanguigna in esame si ottiene come segue:
> glm.res < – glm(cbind(hdis, total-hdis) bpress, data = dfrm,
famiglia = binomio)
> predict(glm.res)
Va notato che i risultati intermedi generati da R sono stati memorizzati con il nome glm.res prima di utilizzare il comando predict (). Le previsioni generate da R sono espresse in forma logit ed è possibile confrontare i logit osservati e previsti:
> cbind(dfrm, logit.predit = predire(glm . res))
Praticamente tutti gli elementi sono disponibili per rappresentare le proporzioni di infarto miocardico osservate e previste graficamente in base al livello di pressione sanguigna. Mancano le previsioni del modello espresse sotto forma di proporzioni e non sulla scala logodds. Può quindi essere auspicabile tracciare la curva di previsione, vale a dire la probabilità di avere un infarto in base alla pressione sanguigna, senza limitare quest’ultima agli otto valori osservati per la variabile bpress. Di seguito una possibile soluzione:
> dfrm prop prop.predit < – predict (glm.la funzione(x)
> f < – function(x)
1 / (1 + exp (- (coef (glm.res) + coef(glm.res)*x)))
> xyplot(hdis/total ˜ bpress, data = dfrm, aspect = 1.2, cex = .8,
xlab = “Blood pressure”,ylab = “Infarction likelihood”,
panel = function(x, y, …) {
panel.xyplot(x, y, col = “gray30”, pch = 19, …)
panel.curve(f, lty = 3, col = “gray70”)
panel.points(x, dfrm$prop.predit, col = “gray70”, …)
})
3) Un’indagine caso-controllo focalizzata sulla relazione tra il consumo di alcol e quello di tabacco e cancro esofageo nell’uomo (studio “le e Villaine”). Il gruppo di casi consisteva in 200 pazienti affetti da cancro all’esofago, diagnosticati tra gennaio 1972 e aprile 1974. Complessivamente, 775 maschi di controllo sono stati selezionati dalle liste elettorali. Tabella 6.3 mostra la distribuzione della totalità dei soggetti in base al loro consumo giornaliero di alcol, considerando che un consumo superiore a 80 g è considerato un fattore di rischio .
Tabella 6.3. Il consumo di alcol e cancro esofageo
il consumo di Alcol (g/giorno) | |||
---|---|---|---|
≥ 80 | < 80 | Totale | |
Caso | 96 | 104 | 200 |
di Controllo | 109 | 666 | 775 |
Totale | 205 | 770 | 975 |
a)
che Cosa è il valore dell’odds ratio e il suo intervallo di confidenza 95% (Woolf metodo)? È una buona stima del rischio relativo?
b)
La percentuale di consumatori a rischio è la stessa tra i casi e tra i controlli (si consideri α = 0,05)?
c)
Costruire il modello di regressione logistica che permette di testare l’associazione tra il consumo di alcol e lo stato degli individui. Il coefficiente di regressione è significativo?
d)
Trova il valore dell’odds ratio osservato, calcolato in (b) e il suo intervallo di confidenza in base ai risultati dell’analisi di regressione.
Poiché i dati grezzi (individuali) non sono disponibili, è necessario lavorare direttamente con la tabella delle frequenze fornita nell’istruzione del problema:
> alcohol < – matrix(c(666,104,109,96), nr = 2,
dimnames = list(c(“Control”,”Case”),
c(“<> = 80”)))
> alcohol
Regarding the odds ratio, the command oddsratio() from the package vcd will be used:
>library(vcd)
>oddsratio(alcohol, log = FALSE)
L’opzione log = FALSE assicura che il risultato restituito corrisponda correttamente a un odds ratio e non al log del odds ratio. Per ottenere un intervallo di confidenza asintotico verrà impiegato quanto segue:
>confint(oddsratio(alcohol, log = FALSE))
Allo stesso modo, summary(oddsratio(alcohol)) potrebbe essere usato per eseguire un test di ipotesi sul log odds ratio (H0 : log(θ) = 0).
Il comando prop.test () può essere utilizzato per verificare l’ipotesi che la percentuale di persone con un consumo giornaliero sia ≥ 80 g ed è identica nei casi e nei controlli, indicando i valori osservati dalla tabulazione incrociata riportata nell’istruzione del problema:
> prop.test (c (96,109), c(200,775), correct = FALSE)
Questo test è esattamente equivalente a un test Z per testare la differenza tra due proporzioni stimate dai dati (se non viene utilizzata alcuna correzione di continuità).
Per quanto riguarda il modello di regressione logistica, la tabella di contingenza deve essere trasformata in una tabella di dati in cui le due variabili qualitative (malattia ed esposizione) sono rappresentate correttamente, vale a dire con un frame di dati. Questo può essere fatto usando il comando melt () dal pacchetto reshape2 che rende possibile trasformare i dati in forma tabellare in formato “lungo”. In questa fase, i livelli della variabile di malattia deve essere registrato con 0 (controllo) e 1 (casi), anche se questo non è davvero necessario e il livello 0 dovrebbe essere considerata come la categoria di riferimento (che facilita l’interpretazione dei risultati):
> library(reshape2)
> alcol.df < – melt(alcohol)
> nomi(alcohol.df)< – c(“malattia”, “esposizione”, “n”)
> livelli(alcol.df disease malattia)< – c(1,0)
> alcol.df disease disease < – relevel (alcohol.df disease disease,”0″)
Il modello di regressione logistica viene quindi scritto nel modo seguente:
> glm.res < – glm(esposizione alla malattia, dati = alcol.df,
famiglia = binomio, pesi = n)
> sommario (glm.res)
Il risultato di interesse è la riga associata con l’esposizione > = 80, in quanto fornisce informazioni circa il valore del coefficiente di regressione associato alla variabile di esposizione, come stimato da R, con il suo errore standard, così come il valore della statistica test. Qui, il coefficiente di regressione viene interpretato come il registro del rapporto di probabilità. Si noti che si otterrebbe esattamente gli stessi risultati scambiando il ruolo delle variabili nella formulazione precedente, malattia da esposizione.
Il rapporto di probabilità calcolato sopra può essere trovato dal coefficiente di regressione associato al fattore di interesse (esposizione), così come il suo intervallo di confidenza del 95%, nel modo seguente:
> exp(coef(glm.res))
> exp (confint (glm.res))
La seconda soluzione consiste nel considerare il numero di casi e il numero totale di individui:
>alcohol2< – dati.telaio(expos = c(“<> = 80”), cassa = c(104,96),
totale = c(104 + 666, 96 + 109))
> summary(glm(rbind(caso, totale-caso) fiere, dati = alcohol2,
family = binomial))
4) i dati arrivano da uno studio che cerca di stabilire la prognosi validità di creatina chinasi concentrazione nel corpo, relativa alla prevenzione dell’insorgenza di infarto del miocardio .
I dati sono disponibili nel file sck.dat: la prima colonna corrisponde alla creatin chinasi variabile (ck), la seconda alla presenza della malattia variabile (pres) e l’ultima alla variabile assenza di malattia (abs).
a)
Qual è il numero totale di soggetti?
b)
Calcola le relative frequenze sick / healthy e rappresenta la loro evoluzione in base ai valori della creatin chinasi utilizzando un diagramma a dispersione (punti + segmenti che collegano i punti).
c)
Sulla base di un modello di regressione logistica che mira a predire la probabilità di ammalarsi, calcolare il valore di CK da cui questo modello predice che le persone soffrono della malattia considerando una soglia di 0,5 (se P (malato) ≥ 0,5 allora malato = 1).
d)
Rappresentano graficamente le probabilità di essere mal previste da questo modello così come le proporzioni empiriche secondo i valori ck.
e)
Stabilire la curva ROC corrispondente e riportare il valore dell’area sotto la curva.
Poiché il nome delle variabili non è nel file di dati, sarà necessario assegnarle immediatamente dopo l’importazione dei dati:
>sck < – read.tabella (“sck.dat”, header = FALSE)
> nomi(sck) < – c(“ck”, “pres”, “abs”)
> summary(sck)
Il numero totale di soggetti corrisponde alla somma delle frequenze per le due variabili pres e abs, che è:
> sum(sck)
o, equivalentemente: sum (sck pre pres) + sum (sck abs abs) (ma non sck sc pres + sck abs abs).
Per calcolare le frequenze relative di queste due variabili, è necessario conoscere le quantità totali per variabile. Questi possono essere ottenuti utilizzando il comando applica e operativo da colonne:
> ni < applica(sck, 2, somma)
sulla Base di questo, è sufficiente dividere ogni valore delle variabili pres e abs per i valori calcolati in precedenza. I valori ottenuti verranno memorizzati in due nuove variabili nella stessa tabella di dati:
> sck pre pres.prop < – sck$pres/ni
> sck$abs.prop < – sck$abs/ni
è possibile verificare che i calcoli sono corretti: la somma dei valori per ogni variabile deve ora essere pari a 1:
> applica(sck, 2, somma)
Quindi le proporzioni ottenuti sono semplicemente rappresentato in un unico grafico, considerando i valori della variabile ck come ascisse:
> xyplot(pres.prop + abs.prop ck, dati = sck, tipo = c (”b”,”g”),
auto.key = TRUE, ylab = “Frequency”)
L’istruzione type = c (”b”,” g”) significa che vogliamo che i punti vengano visualizzati collegati da linee (”b “= ” o ” + “l’) e una griglia (”g”).
Il modello di regressione per i dati raggruppati è scritto come:
> glm.res < – glm(cbind (pres,abs) ck, data = sck, family = binomiale)
> sommario (glm.res)
Le previsioni, espresse in forma di probabilità e non sulla scala log-odds, sono ottenute mediante il comando predict specificando l’opzione type = “response” come segue:
> glm.pred < – predict (glm.res, type = “response”)
> nomi (glm.pred) < – sck c ck
Considerando che le probabilità ≥ 0,5 designano individui malati, si ottiene così la seguente distribuzione:
> glm.pred
Si conclude che le persone saranno considerate malate, secondo questo modello, per valori ck di 80 o più. Questo è facilmente verificabile con un grafico in cui la probabilità stimabile sulla base di valori della variabile di ck sono rappresentati:
> sck$malati < – sck$pres/(sck$pres + sck$abs)
> xyplot(glm.in questo caso, la funzione è quella di utilizzare il pannello di controllo.xyplot (panel)
pannello.xyplot (sck c ck, sck sick sick, pch = 19, col = “grey”)
})
In una prima fase, è necessario “decomprimere” i dati raggruppati e creare una tabella con due colonne: la prima che rappresenta la variabile ck e la seconda che rappresenta la presenza o l’assenza di malattia. Useremo i conteggi per sottogruppo precedentemente calcolati e disponibili nella variabile ni:
> sck.espandere < – dati.la struttura(ck = c(rep(sck c ck, sck pre pres),
rep(sck c ck, sck abs abs)),
sick = c(rep(1,ni), rep(0,ni)))
> tabella(sck.per maggiori informazioni clicca qui.expand, tapply (sick, ck, sum))
Gli ultimi due comandi hanno lo scopo di garantire che vengano rilevati gli stessi conteggi e che la distribuzione delle persone malate in base al valore di ck sia corretta. Si può anche verificare che si ottengano gli stessi risultati per quanto riguarda la regressione logistica e allo stesso tempo si possano aggiungere i valori previsti nella tabella dati precedente (si potrebbe seguire la stessa procedura di prima e replicare le previsioni, ma questo è più semplice in questo modo):
> glm.res2 < – glm(ck malato, dati = sck.espandi, famiglia = binomio)
> sck.expand prediction prediction < – ifelse (predire (glm.res2,
type = “response”) > = 0.5,
1, 0)
> con(sck.expand, table (sick, prediction))
L’ultimo comando consente di visualizzare una matrice di confusione in cui vengono incrociate la diagnostica reale e quelle previste dal modello di regressione. I tassi di classificazione corretti possono essere confrontati quando variiamo la soglia di riferimento:
> classif.scheda < – con(sck.expand, table (sick, prediction))
> sum (diag (classif.tab))/sum(classif.tab)
Per visualizzare la curva ROC, utilizzeremo il pacchetto ROCR:
>library(ROCR)
> pred < – prediction(predict(glm.res2, tipo = “risposta”),
sck.expand$sick)
> perf < – performance(pred, “tpr”,”fpr”)
> plot(perf, ylab = “Sensitivity”, xlab = “1-Specificity”)
> grid()
> abline(0, 1, lty = 2)
The value of the area under the curve is obtained as follows:
> performance(pred, “auc”)@”y.values”