IV data

library(PKPDmisc)
library(dplyr)
## 
## Attaching package: 'dplyr'
## 
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## 
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
head(data)
##   ID TIME   CONC AMT_IV AMT_ORAL OCC  TAD
## 1  1 0.00 130.60   5000        0   1 0.00
## 2  1 0.05  96.64      0        0   1 0.05
## 3  1 0.35  83.24      0        0   1 0.35
## 4  1 0.50  86.62      0        0   1 0.50
## 5  1 0.75  58.66      0        0   1 0.75
## 6  1 1.00  62.03      0        0   1 1.00

First we must extract the IV data (OCC == 1)

IV_data <- data %>% filter(OCC==1)

curve stripping requires a DOSE column so will extract from AMT_IV column

IV_data <- IV_data %>% group_by(ID) %>% mutate(DOSE = max(AMT_IV))

There is a function execute_curve_stripping that will handle summarizing the data by dose and time to get mean concentration-time profiles by dose level, then will perform curve stripping. You simply need to pass in the dataframe and how many points are in the terminal phase.

We can eyeball the terminal phase points graphically

library(ggplot2)
ggplot(IV_data, aes(x = TIME, y = CONC, group = ID)) + geom_point() + geom_line() +
  scale_y_log10()

plot of chunk unnamed-chunk-6

Based on a basic eyeballing 7 points seems appropriate.

In this case the column names match the default execute_curve_stripping arguments so we simply need to pass the dataframe and the number of terminal points to get initial estimates

execute_curve_stripping(IV_data, number_terminal_points = 7)
## Source: local data frame [1 x 5]
## 
##   DOSE    Vc    Vp    Q    CL
## 1 5000 48.62 66.02 8.23 19.85

If you have differently named columns you can pass the column names to specific which columns should be used for TIME, DV, and DOSE

IV_data2 <- rename(IV_data, c("TIME" = "TAD", "DOSE" = "dose", "CONC" = "DV"))
head(IV_data2)
## Source: local data frame [6 x 8]
## Groups: ID
## 
##   ID  TAD     DV AMT_IV AMT_ORAL OCC TAD.1 dose
## 1  1 0.00 130.60   5000        0   1  0.00 5000
## 2  1 0.05  96.64      0        0   1  0.05 5000
## 3  1 0.35  83.24      0        0   1  0.35 5000
## 4  1 0.50  86.62      0        0   1  0.50 5000
## 5  1 0.75  58.66      0        0   1  0.75 5000
## 6  1 1.00  62.03      0        0   1  1.00 5000
# so must also include the column names
execute_curve_stripping(IV_data2, "TAD", "DV", "dose", number_terminal_points = 7)
## Source: local data frame [1 x 5]
## 
##   DOSE    Vc    Vp    Q    CL
## 1 5000 48.62 66.02 8.23 19.85

If you have already calculated the mean concentration time profiles in another program or would like to handle it manually in R, you can use the underlying function strip_curves to calculate the parameters from mean level data.

mean_IV <- IV_data %>% group_by(TIME, DOSE) %>% summarize(geomean = exp(mean(log(CONC))))
head(mean_IV)
## Source: local data frame [6 x 3]
## Groups: TIME
## 
##   TIME DOSE geomean
## 1 0.00 5000  102.84
## 2 0.05 5000   96.58
## 3 0.35 5000   81.26
## 4 0.50 5000   76.32
## 5 0.75 5000   65.81
## 6 1.00 5000   59.76
strip_curves(mean_IV$TIME, mean_IV$geomean, DOSE = mean_IV$DOSE, number_terminal_points = 7)
##      Vc    Vp    Q    CL
## 1 48.62 66.02 8.23 19.85

Note, that this only works for a single dose level at a time, if you would like to calculate multiple dose levels you can use the do() function in dplyr or manually subset out each dose and run them separately. This is only the case for the strip_curves function, the execute_curve_stripping already handles multiple dose levels in this fashion.

mean_IV %>% group_by(DOSE) %>% do(strip_curves(TIME = .$TIME, .$geomean,DOSE = .$DOSE, number_terminal_points = 7))
## Source: local data frame [1 x 5]
## Groups: DOSE
## 
##   DOSE    Vc    Vp    Q    CL
## 1 5000 48.62 66.02 8.23 19.85

In this case the dataset only has one dose group, but this will work for multiple dose groups.

oral data

The curve stripping can also be used for oral data, though it still uses the IV formula so it will be biased, however should place the initial estimates in range for a naive pooled fit to hone the results.

In this dataset 3 ascending doses of 5000, 10000, and 25000 where given to each ID

oral_data <- data %>% filter(OCC >1)
# get dose column all dose levels and remove placebo data as it will wreck havoc on the curve stripping with all 0 concentrations
# we group by OCC as well to get the proper dose level for each ID for each occasion
oral_data <- oral_data %>% group_by(ID, OCC) %>% mutate(DOSE = max(AMT_ORAL)) %>% filter(DOSE > 0)

execute_curve_stripping(oral_data, TIME_name = "TAD", number_terminal_points = 7, oral=T)
## Source: local data frame [3 x 5]
## 
##    DOSE    Vc    Vp     Q    CL
## 1  5000 91.90 101.1 13.25 37.14
## 2 10000 93.25 101.4 13.03 36.83
## 3 25000 93.61 106.6 13.51 37.63

As we can see it overpredicts Vc and Vp compared to IV, but this is to be expected as the equation for calculating Vp involves Cmax, which for oral data will be lower, and there is nothing to distiquish that the lower cmax is due the fact that there is absorption. Depending on the compound, there could also be bioavailability differences between oral and IV that also drive this difference.

Note: for oral data this calculation should be seen as relative Cl, Vc, etc.