Nothing
meta.dt <- function(tp, fp, fn, tn, data, method = "biv.glmm", alpha = 0.05, ...){
if(missing(tp)) stop("need to specify counts of true positives.")
if(missing(fp)) stop("need to specify counts of false positives.")
if(missing(fn)) stop("need to specify counts of false negatives.")
if(missing(tn)) stop("need to specify counts of true negatives.")
if(!missing(data)){
tp <- eval(substitute(tp), data, parent.frame())
fp <- eval(substitute(fp), data, parent.frame())
fn <- eval(substitute(fn), data, parent.frame())
tn <- eval(substitute(tn), data, parent.frame())
}
if((length(tp) != length(fp)) | (length(tp) != length(fn)) | (length(tp) != length(tn))){
stop("the input data have different dimensions.")
}
if(!is.element(method, c("s.roc", "biv.lmm", "biv.glmm"))){
stop("do not recognize the specified method.")
}
idx.allzero <- which(tp == 0 & fp == 0 & fn == 0 & tn == 0)
if(length(idx.allzero) > 0){
tp <- tp[-idx.allzero]
fp <- fp[-idx.allzero]
fn <- fn[-idx.allzero]
tn <- tn[-idx.allzero]
message("studies with zero counts in all four data cells are removed.")
}
if(length(tp) < 2) stop("less than two studies in the meta-analysis.")
dat.ori <- data.frame(tp = tp, fp = fp, fn = fn, tn = tn)
n.stu <- length(tp)
sid <- rep(1:n.stu, each = 2)
sens.id <- rep(c(1, 0), n.stu)
AUC_int <- function(roc){
tryCatch(
{
AUC <- integrate(roc, lower = 0, upper = 1)$value
return(AUC)
},
error=function(error_message) {
tryCatch(
{
AUC <- integrate(roc, lower = 0.0001, upper = 0.9999)$value
return(AUC)
},
error=function(error_message) {
tryCatch(
{
AUC <- integrate(roc, lower = 0.001, upper = 0.999)$value
return(AUC)
},
error=function(error_message) {
tryCatch(
{
AUC <- integrate(roc, lower = 0.01, upper = 0.99)$value
return(AUC)
},
error=function(error_message) {
message("The estimated ROC is not integrable.")
return(0)
}
)
}
)
}
)
}
)
}
if(method == "s.roc"){
for(i in 1:n.stu){
if(tp[i] == 0 | fp[i] == 0 | fn[i] == 0 | tn[i] == 0){
tp[i] <- tp[i] + 0.5
fp[i] <- fp[i] + 0.5
fn[i] <- fn[i] + 0.5
tn[i] <- tn[i] + 0.5
}
}
sens <- tp/(tp + fn)
spec <- tn/(fp + tn)
y1 <- log(sens/(1 - sens))
y2 <- log(spec/(1 - spec))
v1 <- 1/tp + 1/fn
v2 <- 1/fp + 1/tn
D <- y1 + y2
S <- y1 - y2
V <- v1 + v2
lm.unwtd <- lm(D ~ S, ...)
smry.unwtd <- summary(lm.unwtd)
inter.unwtd <- smry.unwtd$coefficients[1,1]
slope.unwtd <- smry.unwtd$coefficients[2,1]
vcov.unwtd <- vcov(lm.unwtd)
logDOR.meanS.unwtd <- inter.unwtd + slope.unwtd*mean(S)
temp.coef <- c(1, mean(S))
logDOR.meanS.unwtd.var <- as.numeric(t(temp.coef) %*% vcov.unwtd %*% temp.coef)
logDOR.meanS.unwtd.ci <- c(logDOR.meanS.unwtd - qnorm(1 - alpha/2)*sqrt(logDOR.meanS.unwtd.var),
logDOR.meanS.unwtd + qnorm(1 - alpha/2)*sqrt(logDOR.meanS.unwtd.var))
Q.unwtd <- 1/(1 + exp(-inter.unwtd/2))
inter.unwtd.ci <- c(inter.unwtd - qnorm(1 - alpha/2)*sqrt(vcov.unwtd[1,1]),
inter.unwtd + qnorm(1 - alpha/2)*sqrt(vcov.unwtd[1,1]))
Q.unwtd.ci <- 1/(1 + exp(-inter.unwtd.ci/2))
roc.curve.unwtd <- function(xval){
spec <- 1 - xval
sens <- 1/(1 + exp(-inter.unwtd/(1 - slope.unwtd))*(spec/(1 - spec))^((1 + slope.unwtd)/(1 - slope.unwtd)))
return(sens)
}
AUC.unwtd <- AUC_int(roc.curve.unwtd)
lm.wtd <- lm(D ~ S, weights = 1/V, ...)
smry.wtd <- summary(lm.wtd)
inter.wtd <- smry.wtd$coefficients[1,1]
slope.wtd <- smry.wtd$coefficients[2,1]
vcov.wtd <- vcov(lm.wtd)
logDOR.meanS.wtd <- inter.wtd + slope.wtd*mean(S)
logDOR.meanS.wtd.var <- as.numeric(t(temp.coef) %*% vcov.wtd %*% temp.coef)
logDOR.meanS.wtd.ci <- c(logDOR.meanS.wtd - qnorm(1 - alpha/2)*sqrt(logDOR.meanS.wtd.var),
logDOR.meanS.wtd + qnorm(1 - alpha/2)*sqrt(logDOR.meanS.wtd.var))
Q.wtd <- 1/(1 + exp(-inter.wtd/2))
inter.wtd.ci <- c(inter.wtd - qnorm(1 - alpha/2)*sqrt(vcov.wtd[1,1]),
inter.wtd + qnorm(1 - alpha/2)*sqrt(vcov.wtd[1,1]))
Q.wtd.ci <- 1/(1 + exp(-inter.wtd.ci/2))
roc.curve.wtd <- function(xval){
spec <- 1 - xval
sens <- 1/(1 + exp(-inter.wtd/(1 - slope.wtd))*(spec/(1 - spec))^((1 + slope.wtd)/(1 - slope.wtd)))
return(sens)
}
AUC.wtd <- AUC_int(roc.curve.wtd)
out <- list(method = method, alpha = alpha,
inter.unwtd = inter.unwtd, slope.unwtd = slope.unwtd, vcov.unwtd = vcov.unwtd,
DOR.meanS.unwtd = exp(logDOR.meanS.unwtd), DOR.meanS.unwtd.ci = exp(logDOR.meanS.unwtd.ci),
Q.unwtd = Q.unwtd, Q.unwtd.ci = Q.unwtd.ci, AUC.unwtd = AUC.unwtd,
inter.wtd = inter.wtd, slope.wtd = slope.wtd, vcov.wtd = vcov.wtd,
DOR.meanS.wtd = exp(logDOR.meanS.wtd), DOR.meanS.wtd.ci = exp(logDOR.meanS.wtd.ci),
Q.wtd = Q.wtd, Q.wtd.ci = Q.wtd.ci, AUC.wtd = AUC.wtd, data = dat.ori)
}
if(is.element(method, c("biv.lmm", "biv.glmm"))){
if(method == "biv.lmm"){
for(i in 1:n.stu){
if(tp[i] == 0 | fp[i] == 0 | fn[i] == 0 | tn[i] == 0){
tp[i] <- tp[i] + 0.5
fp[i] <- fp[i] + 0.5
fn[i] <- fn[i] + 0.5
tn[i] <- tn[i] + 0.5
}
}
sens <- tp/(tp + fn)
spec <- tn/(fp + tn)
y1 <- log(sens/(1 - sens))
y2 <- log(spec/(1 - spec))
y <- c(rbind(y1, y2))
v1 <- 1/tp + 1/fn
v2 <- 1/fp + 1/tn
v <- c(rbind(v1, v2))
dat <- data.frame(sid = sid, sens.id = factor(sens.id), y = y, v = v)
rslt <- rma.mv(yi = y, V = v, mods = ~ sens.id, random = ~ sens.id | sid, struct = "HCS", data = dat, ...)
mu.sens <- rslt$beta[1,1] + rslt$beta[2,1]
mu.spec <- rslt$beta[1,1]
names(mu.sens) <- names(mu.spec) <- NULL
temp.vcov <- rslt$vb
rownames(temp.vcov) <- colnames(temp.vcov) <- NULL
C.mat <- matrix(c(1, 1, 1, 0), 2, 2)
mu.vcov <- C.mat %*% temp.vcov %*% t(C.mat)
sig.sens <- sqrt(rslt$tau2[2])
sig.spec <- sqrt(rslt$tau2[1])
rho <- rslt$rho
}
if(method == "biv.glmm"){
e <- c(rbind(tp, tn))
tot.p <- tp + fn
tot.n <- fp + tn
tot <- c(rbind(tot.p, tot.n))
dat <- data.frame(sid = sid, sens.id = sens.id, spec.id = 1 - sens.id, e = e, tot = tot)
rslt <- glmer(cbind(e, tot - e) ~ sens.id + spec.id - 1 + (sens.id + spec.id - 1 | sid),
data = dat, family = binomial(link = "logit"), ...)
smry <- summary(rslt)
mu.sens <- smry$coefficients[1,1]
mu.spec <- smry$coefficients[2,1]
mu.vcov <- matrix(as.numeric(smry$vcov), 2, 2)
sig.sens <- attr(smry$varcor[[1]], "stddev")[1]
if (sig.sens == 0){
sig.sens <- 0.0001
}
sig.spec <- attr(smry$varcor[[1]], "stddev")[2]
rho <- attr(smry$varcor[[1]], "correlation")[1,2]
if (is.nan(rho)){
rho <- 0
}
names(sig.sens) <- names(sig.spec) <- NULL
}
sens.overall <- 1/(1 + exp(-mu.sens))
mu.sens.ci <- c(mu.sens - qnorm(1 - alpha/2)*sqrt(mu.vcov[1,1]),
mu.sens + qnorm(1 - alpha/2)*sqrt(mu.vcov[1,1]))
sens.overall.ci <- 1/(1 + exp(-mu.sens.ci))
spec.overall <- 1/(1 + exp(-mu.spec))
mu.spec.ci <- c(mu.spec - qnorm(1 - alpha/2)*sqrt(mu.vcov[2,2]),
mu.spec + qnorm(1 - alpha/2)*sqrt(mu.vcov[2,2]))
spec.overall.ci <- 1/(1 + exp(-mu.spec.ci))
logDOR.overall <- mu.sens + mu.spec
logDOR.overall.stderr <- sqrt(sum(mu.vcov))
logDOR.overall.ci <- c(logDOR.overall - qnorm(1 - alpha/2)*logDOR.overall.stderr,
logDOR.overall + qnorm(1 - alpha/2)*logDOR.overall.stderr)
DOR.overall <- exp(logDOR.overall)
DOR.overall.ci <- exp(logDOR.overall.ci)
roc.curve <- function(xval){
spec <- 1 - xval
logit.spec <- log(spec/(1 - spec))
logit.sens <- mu.sens + rho*sig.sens/sig.spec*(logit.spec - mu.spec)
sens <- 1/(1 + exp(-logit.sens))
return(sens)
}
AUC <- AUC_int(roc.curve)
out <- list(method = method, alpha = alpha,
sens.overall = sens.overall, sens.overall.ci = sens.overall.ci,
spec.overall = spec.overall, spec.overall.ci = spec.overall.ci,
DOR.overall = DOR.overall, DOR.overall.ci = DOR.overall.ci, AUC = AUC,
mu.sens = mu.sens, mu.spec = mu.spec, mu.vcov = mu.vcov,
sig.sens = sig.sens, sig.spec = sig.spec, rho = rho, data = dat.ori)
}
class(out) <- "meta.dt"
return(out)
}
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.