######################## ## ## Patterns of measurement and available data ## ## In the following function, audio and aes are two dataframes that contain the ## the necessary variables. ## ## (I have a tendency to re-write this function to be specific to each longitudinal ## data set) ## ######################## pagedisp <- function(p,audio,aes) { par (mgp=c(3,1,0),mar=c(5,5,4,2)+.1) plot (c(-12,24),c(1,length(p)),type="n",xlab="Time from Randomization (months)", xaxt="n",yaxt="n",ylab="Subject Identification Numbers") p <- p[p > 0 & p <= length(unique(audio$Subject))] title(paste("Information Status for Subjects",min(p),"-",max(p))) axis (1,c(-10,-6,0,3,6,9,12,15,21),labels=c("Rndmz","Days",0,3,6,9,12,15,"Reason"),cex.axis=0.8) for (i in 1:length(p)) { id <- unique(audio$Subject)[p][i] axis(2,i,id,las=1,tick=0,cex.axis=0.8) uAudio <- audio$Subject == id uAEs <- aes$Subject == id text(-10,i,format(unique(audio$StartDate[uAudio])),cex=0.5) text(-6,i,format(unique(audio$LengthTreatment[uAudio])),cex=0.5) if (unique(audio$Reason[uAudio]) != "complete") text(21,i,format(unique(audio$Reason[uAudio])),cex=0.5) tAudio <- audio$VisitDays[uAudio] / 30.4 tAEs <- aes$VisitDays[uAEs] / 30.4 tTreat <- unique(audio$LengthTreatment[uAudio]) / 30.4 tComb <- sort(unique(c(tAudio,tAEs))) lines(c(min(tComb),0),c(i,i),lty=3) lines(c(0,tTreat),c(i,i),lty=1) lines(c(tTreat,max(tComb)),c(i,i),lty=2) lbls <- c("N","A","M","B")[(tComb %in% tAudio) + 2 * (tComb %in% tAEs) + 1] cols <- c(1,2,5,2)[(tComb %in% tAudio) + 2 * (tComb %in% tAEs) + 1] text (tComb,rep(i-0.2,length(tComb)),lbls,cex=.5,col=cols) } abline(v=0,lty=3) abline(v=12,lty=3) } for (j in 1:5) pagedisp((1:25)+(j-1)*25)