Media mobile (media mobile) per gruppo / id con dplyr

Ho un follow-up longitudinale delle registrazioni della pressione arteriosa.

Il valore a un certo punto è meno predittivo rispetto alla media mobile (media mobile), motivo per cui mi piacerebbe calcolarlo. I dati sono simili

test <- read.table(header=TRUE, text = " ID AGE YEAR_VISIT BLOOD_PRESSURE TREATMENT 1 20 2000 NA 3 1 21 2001 129 2 1 22 2002 145 3 1 22 2002 130 2 2 23 2003 NA NA 2 30 2010 150 2 2 31 2011 110 3 4 50 2005 140 3 4 50 2005 130 3 4 50 2005 NA 3 4 51 2006 312 2 5 27 2010 140 4 5 28 2011 170 4 5 29 2012 160 NA 7 40 2007 120 NA ") 

Mi piacerebbe calcolare una nuova variabile, chiamata BLOOD_PRESSURE_UPDATED. Questa variabile dovrebbe essere la media mobile per BLOOD_PRESSURE e avere le seguenti caratteristiche:

  • Una media mobile è il valore corrente più il valore precedente diviso per due.
  • Per la prima osservazione, BLOOD_PRESSURE_UPDATED è solo l’attuale BLOOD_PRESSURE. Se manca, BLOOD_PRESSURE_UPDATED dovrebbe essere la media complessiva.
  • I valori mancanti devono essere compilati con il valore precedente più vicino.

Ho provato il seguente:

 test2 % group_by(ID) %>% arrange(ID, YEAR_VISIT) %>% mutate(BLOOD_PRESSURE_UPDATED = rollmean(x=BLOOD_PRESSURE, 2)) %>% ungroup() 

Ho anche provato a rollaply e rollmeanr senza riuscirci.

Gradirei qualche aiuto.

Se non ti dplyr a dplyr questo dovrebbe funzionare:

 get.mav < - function(bp,n=2){ require(zoo) if(is.na(bp[1])) bp[1] <- mean(bp,na.rm=TRUE) bp <- na.locf(bp,na.rm=FALSE) if(length(bp) 

Questo funziona anche per medie mobili> 2.

Ed ecco una soluzione data.table, che probabilmente sarà molto più veloce se il set di dati è grande.

 library(data.table) setDT(test) # converts test to a data.table in place setkey(test,ID,YEAR_VISIT) test[,BLOOD_PRESSURE_UPDATED:=as.numeric(get.mav(BLOOD_PRESSURE,2)),by=ID] test # ID AGE YEAR_VISIT BLOOD_PRESSURE TREATMENT BLOOD_PRESSURE_UPDATED # 1: 1 20 2000 NA 3 134.6667 # 2: 1 21 2001 129 2 131.8333 # 3: 1 22 2002 145 3 137.0000 # 4: 1 22 2002 130 2 137.5000 # 5: 2 23 2003 NA NA 130.0000 # 6: 2 30 2010 150 2 140.0000 # 7: 2 31 2011 110 3 130.0000 # ... 

Cosa ne pensi di questo?

  library(dplyr) test2< -arrange(test,ID,YEAR_VISIT) %>% mutate(lag1=lag(BLOOD_PRESSURE), lag2=lag(BLOOD_PRESSURE,2), movave=(lag1+lag2)/2) 

Un’altra soluzione che utilizza la funzione “rollapply” nel pacchetto zoo (mi piace di più)

 library(dplyr) library(zoo) test2< -arrange(test,ID,YEAR_VISIT) %>% mutate(ma2=rollapply(BLOOD_PRESSURE,2,mean,align='right',fill=NA))