Vai al contenuto

Sanità e ricerca clinicaBI, AI e ML per l'azienda

Studio clinico: l'analisi intermedia

Visite, misure ed eventi avversi di uno studio arrivano dal sistema di raccolta dati, la lista di randomizzazione da un file. Muvia li unisce paziente per paziente, una funzione Python rifà il confronto statistico a ogni visita e il rapporto intermedio per il comitato è sempre aggiornato.

Scenario illustrativo: descrive un caso tipo, non il progetto di un cliente.

Ogni analisi intermedia riparte da un foglio diverso.

In uno studio clinico misure, visite, eventi avversi e randomizzazione stanno in sistemi diversi. Ogni volta che il comitato chiede un aggiornamento qualcuno esporta, unisce, rifà i test e impagina il rapporto, e due esportazioni a un mese di distanza non sono mai fatte nello stesso modo.

Scrivere una volta l'unione dei dati e il confronto statistico, e rifarli a ogni visita sugli stessi dati, rende ogni rapporto confrontabile con il precedente e lascia ai biostatistici il tempo per le domande nuove.

Per chi
Biostatistici e data manager dello studio, medical monitor, promotori e comitati di monitoraggio.
Le esportazioni del sistema di raccolta dati dello studio via SFTP, la lista di randomizzazione in Excel e gli eventi avversi da un database PostgreSQL entrano in Muvia, dove una funzione del team confronta i bracci; escono la tabella dei risultati per visita, un cruscotto dello studio e il rapporto intermedio in PDF per il comitato.

In Muvia, passo per passo

Schermate vere del prodotto, registrate su un progetto con dati di esempio.

1 di 5

Il video · Visite, misure ed eventi avversi di uno studio arrivano dal sistema di raccolta dati, la lista di randomizzazione da un file. Muvia li unisce paziente per paziente, una funzione Python rifà il confronto statistico a ogni visita e il rapporto intermedio per il comitato è sempre aggiornato.

Cosa ottieni

Rapporti confrontabili
Unione dei dati e test sono scritti una volta: ogni rapporto è fatto nello stesso modo, sugli ultimi dati.
La statistica si rilegge
Il confronto è una funzione che i biostatistici possono rileggere versione per versione, non una sequenza di passaggi a mano.
Efficacia e sicurezza insieme
Variazioni dal basale ed eventi avversi si leggono nello stesso posto, per visita e per braccio.
Più tempo per le domande nuove
L'analisi ricorrente gira da sola; il team si occupa di quello che il comitato chiede di nuovo.

Per il team tecnico

Come si costruisce in Muvia

  1. 1

    Porta in Muvia i dati dello studio

    Le esportazioni del sistema di raccolta dati arrivano come file via SFTP, la randomizzazione come file Excel e gli eventi avversi con una copia incrementale. Ogni sorgente diventa una tabella.

  2. 2

    Calcola la variazione dal basale

    Una query unisce misure e randomizzazione e calcola per ogni paziente e ogni visita la variazione dal basale. La salvi come dataset con campi stabili.

  3. 3

    Confronta i bracci in Python

    Una funzione con scipy calcola per ogni visita la differenza tra i bracci, il t di Welch, l'intervallo di confidenza al 95 % e il d di Cohen. Un flusso la esegue ogni lunedì e scrive i risultati in una tabella gestita.

  4. 4

    Guarda le due popolazioni

    Un cruscotto mostra la distribuzione delle variazioni per visita e braccio, l'andamento medio e gli eventi avversi per tipo.

  5. 5

    Prepara il rapporto per il comitato

    Un notebook con testo, indicatori, la tabella per visita e gli eventi avversi diventa un PDF per il comitato, rifatto sui dati più recenti.

Funzione Python

import numpy as np
import pandas as pd
from scipy import stats

def transform(inputs, params, ctx):
    df, righe = inputs["rows"], []
    for visita, g in df.groupby("visita"):
        a = g.loc[g["braccio"] == params["braccio_attivo"], "variazione"].dropna()
        p = g.loc[g["braccio"] == params["braccio_controllo"], "variazione"].dropna()
        t, pval = stats.ttest_ind(a, p, equal_var=False)
        va, vp = a.var() / len(a), p.var() / len(p)
        gl = (va + vp) ** 2 / (va ** 2 / (len(a) - 1) + vp ** 2 / (len(p) - 1))
        diff, mezzo_ic = a.mean() - p.mean(), stats.t.ppf(0.975, gl) * np.sqrt(va + vp)
        righe.append({"visita": visita, "differenza": diff,
                      "ic_basso": diff - mezzo_ic, "ic_alto": diff + mezzo_ic,
                      "t": t, "p": pval,
                      "d_cohen": diff / np.sqrt((a.var() + p.var()) / 2)})
    ctx.logger.info("visite analizzate: %d", len(righe))
    return {"rows": pd.DataFrame(righe)}
Il confronto tra i bracci rifatto a ogni visita, sempre nello stesso modo: differenza, t di Welch con il suo intervallo al 95 % e d di Cohen.
I dati che servono
  • Visite e misure per paziente, per esempio la pressione sistolica, esportate dal sistema di raccolta dati dello studio via SFTP
  • Lista di randomizzazione con il braccio di ogni paziente, da un file Excel
  • Eventi avversi con tipo, gravità e data, da un database PostgreSQL
Le parti di Muvia usate

Portaci una domanda a cui oggi non sai rispondere.

Partiamo da una domanda vera della tua azienda e ti mostriamo il percorso dalla fonte al cruscotto, con i tuoi sistemi e non con quelli di una demo.