Limit of detection is the sensitivity of the assay — how low a concentration can the test detect?
To test this, the lab did a dilution series over a range of concentrations. When the concentration is low enough, the fusion won’t be detected.
Using the data from the dilution series, we used 4 models to predict the limit of detection.
- Linear regression using all data
- Linear regression using just the concentrations where data was observed
- Logit
- Probit
1. Linear regression using all data
My data frame “chan” contains deltaCq values and the Percentage_Fusion.
First do the linear regression:
chan.lm <- lm ( deltaCq ~ log2 ( Final_Percentage_Fusion ), data=chan)
summary (chan.lm)
with a prediction interval:
PI <- predict (chan.lm, newdata = new.dat, interval='prediction', level=0.90)
The fusion dilution where the top prediction limit crosses the delta Ct cut-off will be estimated and chosen to be the model's estimate of the C95.
My delta Ct cutoff is 5 (determined from the Accuracy study).
cutoff <- 5
Our linear model on the upper prediction interval is :
upper.lm <- lm (PI[,"upr"] ~ log2(conc) )
y = slope * x + intercept and hence x = (y- intercept)/slope. In our case x is the concentration, and it's what we want. y is delta Ct and we want to know what concentration is predicted to have a delta Ct of 5 (our cutoff).
slope <- upper.lm$coefficients[2]
intercept <- upper.lm$coefficients[1]
C95 = (cutoff - intercept)/slope
conc_LoD = 2^C95
conc_LoD is our limit of detection.
2. Linear regression using just the concentrations where data was observed
To do a linear regression on just some of the data, identify which concentrations to remove.
remove_because_partial_or_no_data <- c(0.0488, 0.0977, 0.1953, 0.3906, 0.781, 1.563)
Remove these concentrations from the data frame:
chan <- chan[!(chan$Final_Percentage_Fusion %in% remove_because_partial_or_no_data),]
and then follow the same steps as in #1.
3. Logit model
First, make a column of whether the PCR product is called as a positive or not. This column is called "CalledPositive".
chan["CalledPositive"] <- 1
If no signal is detected or deltaCq is > 5, then the fusion is not called and we have to assign CalledPositive as false or "0".
chan[is.na(chan$deltaCq), "CalledPositive"] <- 0
chan[!is.na(chan$deltaCq) & chan$deltaCq > 5, "CalledPositive"] <- 0
Run the logit analysis
mylogit <- glm (CalledPositive ~ log2Conc , family = binomial(link = "logit"),
data = chan)
To find the sensitivity at 95% based on the logit model, I manually feed in ranges of values until I get something close to 95%.
For example, by inspecting the graph I know that my LoD is somewhere between 0 and 2 so I set
xlower <- 0
xupper <- 2
and then I make a series of points:
temp.data <- data.frame(log2Conc = seq(from = xlower, to = xupper, length.out = 10))
And I input temp.data to get predicted sensitivities:
predicted.data.logit <- predict(mylogit, temp.data, type = "response", se.fit=TRUE)
I then look at predicted.data.logit to see which concentration gives me close to 95%. This can take several iterations until I'm very close to 0.95
4. Probit model
We make use of the "CalledPositive" column defined from the section 3 logit model.
myprobit <- glm(CalledPositive ~ log2Conc , family = binomial(link = "probit"),
data = chan)
To find the concentration with sensitivity of 95%, do the same steps as described in 3.Logit model, but use predicted.data.probit instead.
predicted.data.probit <- predict(myprobit, temp.data, type = "response", se.fit=TRUE)
You can find my complete linear regression R scripts and probit and logit scripts on github.
No comment yet
1 ping
FDA Validation of Companion Diagnostic (PCR test) » Pauline PI - investigating science, math, and biology says:
December 21, 2018 at 11:36 am (UTC 8)
[…] Analytical Specificity Part 4. Accuracy Part 5. Run Control Specification Part 6. Reportable Range Part 7. Limit of Detection (LoD) Part 8. Precision (repeatability & reproducibility) Part 9. Checking […]