#source drive.r here

#load extra libraries
library(knitr)
library(plyr)
library(ggplot2)
library(GGally)
library(Hmisc)
#off the cuff utility funcitons

pretty.stat = function(x,na.rm=T,digits=4)
  {
  m = mean(x,na.rm=na.rm)
  ci=c(NA,NA)
  if(length(x)>1) ci = t.test(x,na.rm=na.rm)$conf.int
  st = format(c(m,ci),digits=digits,trim=T)
  paste0(st[1]," (",st[2], " -- ", st[3],")" )
  }

#set global options
  #set echo=F to hide code in output
opts_knit$set(echo=T)

This template is very simple in that there is only PK and PD data. But the approach is similar if demographic, lab, and vitals are also to be loaded and merged. The sections (suggested) are:

Background and Protocol

Simulated data for 2 compartment PK model with tumor growth model for PD.

Data Import

The data are stored in the \Data subfolder. There datasets include: PKdata - already includes demo and lab data as covariates TUMORdata - longitudinal tumor size data

We will combine both datasets into a single PK/PD dataset.

PK Data

When loading the PK data, note that the header is not formatted consistently with the data. Header is not comma delimited.

pk.names = read.csv("./Data/PKdata.csv", sep="", nrows=1)
pk.df = read.csv("./Data/PKdata.csv", skip=1)
names(pk.df) = names(pk.names)
names(pk.df)[1]="id"

Data Structure

Check the structure of the PK data

str(pk.df)

Number of subjects: r length(unique(pk.df$id))

Data Transformations

check.id = pk.df$id[9]
pk.df$lndv = log(pk.df$dv)
pk.df$blq = ifelse(pk.df$dv<0.1 & pk.df$evid==0,1,0)

Choose a subject to follow through the transformations - id = r check.id

Table: PK data for sample subject

kable(subset(pk.df,id==check.id),row.names=F)

PD Data

When loading the PD data, note that the header is not formatted consistently with the data. Header is not comma delimited.

pd.names = read.csv("./Data/TUMORdata.csv", sep="", nrows=1)
pd.df = read.csv("./Data/TUMORdata.csv", skip=1)
names(pd.df) = names(pk.names)
names(pd.df)[1]="id"

Data Structure

Check the structure of the PD data

str(pd.df)

Number of subjects: r length(unique(pd.df$id))

Data Transformations

pd.df$lndv = log(pd.df$dv)
pd.df$blq = 0
pd.df = subset(pd.df,evid==0)

Table: PD data for sample subject

kable(subset(pd.df,id==check.id),row.names=F)

Merge data

Cross check data

pk.ids = unique(pk.df$id)
pd.ids = unique(pd.df$id)
pk.nin.pd = pk.ids[pk.ids %nin% pd.ids]
pd.nin.pk = pd.ids[pd.ids %nin% pk.ids]

Subjects in PK not in PD: r pk.nin.pd

Subject in PD not in PK: r pd.nin.pk

Combine data

data.df = rbind(pk.df,pd.df)
data.df = arrange(data.df,id,time,evid)
kable(subset(data.df,id==check.id),row.names=F)

Number of records:

Exclusions

Exclusion rules:

data.df$excl="OK"
data.df$excl[data.df$id %in% pd.nin.pk] = "NoPK"
data.df$excl[data.df$blq==1] = "BLQ"
excl.tab = table(data.df$excl, data.df$dose)

excl.df=as.data.frame.matrix(addmargins(excl.tab))
kable(excl.df,row.names=T)

Exploratory Data Analysis

Create some plots and tables to get an overall feel for the data and check that it is put together correctly.

Covariates

# check the covariate distributions in only included subjects
covars.df = subset(data.df,excl=="OK" & !duplicated(id),select=Cs(sex,race,bmi,wt,ht,age))
covars.df$sex=factor(c("F","M")[covars.df$sex])
covars.df$race=factor(Cs(White,Black,Asian,Other)[covars.df$race])

ggpairs(covars.df)

Subject Timelines

This plot is meant to show the timing of doses and observations. Adjust the plot size as necessary to see the data in the output. Use this as a diagnostic to ensure that the exclusion rules are working ok. Revise exclusion rules as necessary.

data.df$obs = Cs(Dose,PK,NA,PD)[data.df$cmt]
ggplot(data.df) + 
  geom_point(data=data.df, mapping=aes(x=time, y=obs, color=excl, shape=Cs(Dose,PK,NA,PD)[data.df$cmt]),
             size=2) + 
  facet_grid(id~.) + 
  theme_bw() + 
  theme(legend.position="top") +
  labs(colour="EXCL", x="Time from first dose (h)",y="Observation", shape="Observation")

PK & PD by Subject

df = droplevels(subset(data.df,evid==0))
df$obs = paste(df$id,df$obs)
ggplot(df,aes(x=time, y=dv, color=excl)) + 
  geom_point() + 
  facet_wrap(~obs,scales="free_y",ncol=2) + 
  theme_bw() + 
  theme(legend.position="top") +
  labs(colour="Conc.Flag", x="Time from first dose (h)",y="Concentration (ng/ml) or Tumor size (mm)", shape="Observation")

Table: Cmax by dose level

df = ddply(subset(data.df, cmt==2 & evid==0 & excl=="OK"), .(id), summarise,
           dose=dose[1],
           N = length(dv),
           Cmax = max(dv))
df = ddply(df, .(dose), summarise,
           N.obs=sum(N),
           N.subj=length(N),
           Cmax = pretty.stat(Cmax))
kable(df,row.names=F)

Write out the combined dataset




qPharmetra/qpToolkit documentation built on May 24, 2023, 8:52 a.m.