CODE FOR MMETA FUNCTION
Please choose your preferred code according to the programming language you use
STATA CODE FOR MMOM METHOD IN MMETA FUNCTION
capture program drop mmom
program mmom, rclass
version 1.1
args ys1 ys2 vars1 vars2
** ys1 ys2 are the two measures from the same study
** vars1 and vars2 are the associated variance
tempvar w1 w2
gen `w1' = 1/vars1
gen `w2' = 1/vars2
tempvar w1_ys1 w2_ys2
gen `w1_ys1' = `w1'*ys1
summ (`w1_ys1'), meanonly
scalar sum_w1_ys1 = r(sum)
gen `w2_ys2' = `w2'*ys2
summ (`w2_ys2'), meanonly
scalar sum_w2_ys2 = r(sum)
summ (`w1'), meanonly
scalar sum_w1 = r(sum)
summ (`w2'), meanonly
scalar sum_w2 = r(sum)
scalar y1_weight = sum_w1_ys1/sum_w1
scalar y2_weight = sum_w2_ys2/sum_w2
gen large_vars1 = 1-1*(vars1 > 10^4)
gen large_vars2 = 1-1*(vars2 > 10^4)
summ (`large_vars1'), meanonly
scalar n1 = r(sum)
summ (`large_vars2'), meanonly
scalar n2 = r(sum)
gen inter1 = `w1'*(ys1-y1_weight)^2
gen inter2 = `w2'*(ys2-y2_weight)^2
summ (inter1), meanonly
scalar Q1 = r(sum)
summ (inter2), meanonly
scalar Q2 = r(sum)
tempvar w1_2 w2_2
gen `w1_2' = `w1'^2
gen `w2_2' = `w2'^2
summ (`w1_2'), meanonly
scalar sum_w1_2 = r(sum)
summ (`w2_2'), meanonly
scalar sum_w2_2 = r(sum)
scalar tau1_2_hat = max(0, (Q1-(n1-1))/(sum_w1-sum_w1_2/sum_w1))
scalar tau2_2_hat = max(0, (Q2-(n2-1))/(sum_w2-sum_w2_2/sum_w2))
* variance estimate:
gen w1_star = 1/(vars1 + tau1_2_hat)
gen w2_star = 1/(vars2 + tau2_2_hat)
summ (w1_star), meanonly
scalar sum_w1_star = r(sum)
summ (w2_star), meanonly
scalar sum_w2_star = r(sum)
gen w1_star_ys1 = w1_star * ys1
gen w2_star_ys2 = w2_star * ys2
​
summ (w1_star_ys1), meanonly
scalar sum_w1_star_ys1 = r(sum)
summ (w2_star_ys2), meanonly
scalar sum_w2_star_ys2 = r(sum)
scalar beta1_hat = sum_w1_star_ys1/sum_w1_star
scalar beta2_hat = sum_w2_star_ys2/sum_w2_star
scalar var_beta1_hat = 1/sum_w1_star
scalar var_beta2_hat = 1/sum_w2_star
gen mycov_beta_piece = (w1_star/sum_w1_star)*(w2_star/sum_w2_star)*(ys1 - beta1_hat)*(ys2 - beta2_hat)
summ (mycov_beta_piece), meanonly
scalar mycov_beta = r(sum)
matrix beta_hat = (beta1_hat , beta2_hat)
matrix sigma_hat = (var_beta1_hat, mycov_beta \ mycov_beta,var_beta2_hat)
matrix list beta_hat
matrix list sigma_hat
end
R CODE FOR MMETA FUNCTION
mmeta <-
function(data, rhow, type, k, method) {
nn.reml <-
function(y1, s1, y2, s2, rhow) {
S=cbind(s1^2, rhow*s1*s2, s2^2)
myreml= mvmeta(cbind(y1, y2), S, method="reml")
coef = coef(myreml)[1,]
vcov = vcov(myreml)
rhob <- cov2cor(myreml$Psi)[2,1]
myresults = list(coefficients = coef, vcov= vcov, rhob=rhob)
return(myresults)
}
nn.cl <-
function(y1, s1, y2, s2) {
m=length(y1)
estim.pseudo=rep(NA, 4)
my.pseudo1= mvmeta(y1,s1^2,method="reml")
my.pseudo2= mvmeta(y2,s2^2,method="reml")
estim.pseudo[c(1:2)]=c(coef(my.pseudo1), my.pseudo1$Psi)
estim.pseudo[c(3:4)]=c(coef(my.pseudo2), my.pseudo2$Psi)
estim.pseudo = matrix(estim.pseudo, nrow=1)
colnames(estim.pseudo)=c("beta1", "tau1.2", "beta2", "tau2.2")
Score1.beta = (y1-coef(my.pseudo1))/(s1^2+my.pseudo1$Psi)
Score2.beta = (y2-coef(my.pseudo2))/(s2^2+my.pseudo2$Psi)
Score1.tau2 = -1/(2*(s1^2+my.pseudo1$Psi)) + (y1-coef(my.pseudo1))^2/(s1^2+my.pseudo1$Psi)^2/2
Score2.tau2 = -1/(2*(s2^2+my.pseudo2$Psi)) + (y2-coef(my.pseudo2))^2/(s2^2+my.pseudo2$Psi)^2/2
Score1 = rbind(Score1.beta, Score1.tau2); Score2 = rbind(Score2.beta, Score2.tau2)
I11.hat = Score1%*%t(Score1)/m; I22.hat = Score2%*%t(Score2)/m
I12.hat = Score1%*%t(Score2)/m
myoff.diag = solve(I11.hat,tol=1e-100)%*%I12.hat%*%solve(I22.hat,tol=1e-100)/m
myupper = cbind(solve(m*I11.hat,tol=1e-100), (myoff.diag))
mylower = cbind(t(myoff.diag), solve(m*I22.hat,tol=1e-100))
myV=rbind(myupper,mylower)
colnames(myV)=c("beta1", "tau1.2", "beta2", "tau2.2")
rownames(myV)=c("beta1", "tau1.2", "beta2", "tau2.2")
myresults = list(coefficients = estim.pseudo, vcov= myV)
return(myresults)
}
nn.mom= function(y1, s1, y2, s2){
v1 = s1^2
v2 = s2^2
w1 = 1/(v1)
w2 = 1/(v2)
y1.weight = sum(w1*y1)/sum(w1)
y2.weight = sum(w2*y2)/sum(w2)
n1 = sum(1-1*(v1 > 10^4))
n2 = sum(1-1*(v2 > 10^4))
Q1 = sum(w1*(y1-y1.weight)^2)
Q2 = sum(w2*(y2-y2.weight)^2)
tau1.2.hat = max(0, (Q1-(n1-1))/(sum(w1)-sum(w1^2)/sum(w1)))
tau2.2.hat = max(0, (Q2-(n2-1))/(sum(w2)-sum(w2^2)/sum(w2)))
## variance estimate:
w1.star = 1/(v1 + tau1.2.hat)
w2.star = 1/(v2 + tau2.2.hat)
beta1.hat = sum(w1.star*y1)/sum(w1.star)
beta2.hat = sum(w2.star*y2)/sum(w2.star)
var.beta1.hat = 1/sum(w1.star)
var.beta2.hat = 1/sum(w2.star)
mycov.beta = sum((w1.star/sum(w1.star))*(w2.star/sum(w2.star))*(y1 - beta1.hat)*(y2 - beta2.hat))
beta.hat = cbind(beta1=beta1.hat,beta2=beta2.hat)
myV = matrix(c(var.beta1.hat,mycov.beta,mycov.beta,var.beta2.hat),nrow = 2, byrow = T)
colnames(myV)=c("beta1", "beta2")
rownames(myV)=c("beta1", "beta2")
myresults = list(coefficients = beta.hat, vcov= myV)
return(myresults)
}
log.Riley.Lik.reml.func = function(mygamma, y1, s1, y2, s2){
m = length(y1)
beta1 = mygamma[1]; beta2= mygamma[2]
log.psi1.2 = mygamma[3]; log.psi2.2 = mygamma[4]; omega = mygamma[5]
psi1.2 = exp(log.psi1.2); psi2.2 = exp(log.psi2.2)
rho = 2*plogis(omega)-1
s1.2 = s1^2
s2.2 = s2^2
Sigma = matrix(0, nrow=(2*m), ncol=(2*m))
for(i in 1:m){
cov.y1.y2 = rho*sqrt((psi1.2+s1.2[i])*(psi2.2+s2.2[i]))
Sigma.i = matrix(c(s1.2[i]+psi1.2, cov.y1.y2, cov.y1.y2, s2.2[i]+psi2.2), nrow=2)
Sigma[((i-1)*2+c(1:2)), ((i-1)*2+c(1:2))] = Sigma.i
}
y1.temp = rep(y1, each=2); y2.temp = rep(y2, each=2)
y1.temp2 = y1.temp%*%diag(rep(c(1,0), times=m))
y2.temp2 = y2.temp%*%diag(rep(c(0,1), times=m))
Y = as.vector(y1.temp2+y2.temp2)
x.design=cbind(rep(c(1,0), times=m), rep(c(0,1),times=m))
mybeta=x.design%*%c(beta1,beta2)
mylik = -0.5*((m-2)*log(2*pi)-log(det(t(x.design)%*%x.design)) +
log(det(Sigma))+log(det(t(x.design)%*%solve(Sigma,tol=1e-100)%*%x.design)) +
t(Y-mybeta)%*%solve(Sigma,tol=1e-100)%*%(Y-mybeta))
mylik = as.numeric(mylik)
return(mylik)
}
log.Riley.Lik.reml.i.func=function(mygamma, y1.i, s1.i, y2.i, s2.i){
result=log.Riley.Lik.reml.func(mygamma, y1.i, s1.i, y2.i, s2.i)
return(result)
}
robustV.ftn=function(mygamma, y1, s1, y2, s2){
m = length(y1)
SigmaB=array(NA, c(5,5,m))
SigmaA=array(NA, c(5,5,m))
for (i in 1:m){
y1.i=y1[i]
s1.i=s1[i]
y2.i=y2[i]
s2.i=s2[i]
myB=jacobian(log.Riley.Lik.reml.i.func, mygamma, y1.i=y1.i, s1.i=s1.i, y2.i=y2.i, s2.i=s2.i)
SigmaB[,,i]=t(myB)%*%myB
myA=hessian(log.Riley.Lik.reml.i.func, mygamma, y1.i=y1.i, s1.i=s1.i, y2.i=y2.i, s2.i=s2.i)
SigmaA[,,i]=-myA
}
E.A=apply(SigmaA, c(1:2), mean) # sensitivity matrix
E.B=apply(SigmaB, c(1:2), mean) # variability matrix
myV=solve(E.A)%*%E.B%*%solve(E.A)
return(myV)
}
nn.rs=function(y1, s1, y2, s2){
mygamma.init = c(0,0,0,0,0)
myresults = optim(mygamma.init, log.Riley.Lik.reml.func, y1=y1, s1=s1, y2=y2, s2=s2, hessian=TRUE,
control = list(fnscale=-1,maxit=1000))
beta1=myresults$par[1]
tau1.2=exp(myresults$par[3])
beta2=myresults$par[2]
tau2.2=exp(myresults$par[4])
rhos=2*plogis(myresults$par[5])-1
par=cbind(beta1, tau1.2, beta2, tau2.2, rhos)
myV=robustV.ftn(myresults$par, y1=y1, s1=s1, y2=y2, s2=s2)/length(y1)
colnames(myV)=c("beta1", "log.tau1.2", "beta2", "log.tau2.2", "omega")
rownames(myV)=c("beta1", "log.tau1.2", "beta2", "log.tau2.2", "omega")
return(list(coefficients=par, vcov=myV))
}
myLik.indep.log=function(mypar, mydat) {
a1.temp <- mypar[1]; b1.temp <- mypar[2]
a2.temp <- mypar[3]; b2.temp <- mypar[4]
a1 <- exp(a1.temp); b1 <- exp(b1.temp)
a2 <- exp(a2.temp); b2 <- exp(b2.temp)
temp1 <- (lgamma(a1+mydat$y1) + lgamma(b1+mydat$n1-mydat$y1)
+ lgamma(a2+mydat$y2) + lgamma(b2+mydat$n2-mydat$y2)
+ lgamma(a1+b1) + lgamma(a2+b2))
temp2 <- (lgamma(a1) + lgamma(b1) + lgamma(a2) + lgamma(b2)
+ lgamma(a1+b1+mydat$n1) + lgamma(a2+b2+mydat$n2))
myLogLik <- sum(temp1 - temp2)
return(myLogLik)
}
par.cal=function(mypar) {
a1 <- exp(mypar[1]); b1 <- exp(mypar[2])
a2 <- exp(mypar[3]); b2 <- exp(mypar[4])
eta <- mypar[5]
cc <- sqrt(a1*a2*b1*b2)/sqrt((a1+b1+1)*(a2+b2+1))
upper.bound <- cc/max(a1*b2, a2*b1)
lower.bound <- -cc/max(a1*a2, b1*b2)
expit.eta= exp(eta)/(1+exp(eta))
rho <- (upper.bound-lower.bound)*expit.eta + lower.bound
return(c(a1,b1,a2,b2,rho,eta))
}
bb.cl=function(y1,n1,y2,n2){
nstudy=length(y1)
initial.val.gen <- function(y, n) {
BBfit <- betabin(cbind(y, n-y)~1, ~1, data=data.frame(y=y,n=n))
expit.BB <- exp(as.numeric(BBfit@param[1]))/(1+exp(as.numeric(BBfit@param[1])))
a.ini <- expit.BB*(1/as.numeric(BBfit@param[2])-1)
b.ini <- (1/as.numeric(BBfit@param[2])-1)*(1-expit.BB)
return(list(a=a.ini, b=b.ini))
}
mle.CL <- function(y1=y1,n1=n1,y2=y2,n2=n2) {
init.val <- rep(0, 5)
fit1 <- initial.val.gen(y1, n1)
fit2 <- initial.val.gen(y2, n2)
init.val[1] <- log(fit1$a);
init.val[2] <- log(fit1$b)
init.val[3] <- log(fit2$a);
init.val[4] <- log(fit2$b)
MLE.inde.log <- optim(init.val[1:4], myLik.indep.log, method = "L-BFGS-B",
lower=rep(-20,4), upper=rep(20,4),
control = list(fnscale=-1,maxit=1000),
hessian = T, mydat=list(y1=y1,n1=n1,y2=y2,n2=n2))
mypar<- par.cal(MLE.inde.log$par)
rho<-0;
eta<-NA;
hessian.log<-MLE.inde.log$hessian
colnames(hessian.log)<-c("loga1","logb1","loga2","logb2")
rownames(hessian.log)<-c("loga1","logb1","loga2","logb2")
conv=MLE.inde.log$convergence
a1 <- mypar[1]; b1 <- mypar[2];
a2 <- mypar[3]; b2 <- mypar[4];
prior.MLE<-c(a1, b1, a2, b2, rho ,eta)
return(list(MLE=prior.MLE,hessian.log=hessian.log,conv=conv))
}
myLik.indep.vector=function(mypar, mydat) {
a1.temp <- mypar[1]; b1.temp <- mypar[2]
a2.temp <- mypar[3]; b2.temp <- mypar[4]
a1 <- exp(a1.temp); b1 <- exp(b1.temp)
a2 <- exp(a2.temp); b2 <- exp(b2.temp)
temp1 <- (lgamma(a1+mydat$y1) + lgamma(b1+mydat$n1-mydat$y1)
+ lgamma(a2+mydat$y2) + lgamma(b2+mydat$n2-mydat$y2)
+ lgamma(a1+b1) + lgamma(a2+b2))
temp2 <- (lgamma(a1) + lgamma(b1) + lgamma(a2) + lgamma(b2)
+ lgamma(a1+b1+mydat$n1) + lgamma(a2+b2+mydat$n2))
myLogLik <- (temp1 - temp2)
return(myLogLik)
}
sandwich.var.cal=function(mypar, myhessian.indep, mydat){
npar=length(mypar)
delta=1e-8
myD = matrix(NA, nrow=npar, ncol=nstudy)
for(i in 1:npar){
par.for=par.back=mypar
par.for[i]=par.for[i]+delta
par.back[i]=par.back[i]-delta
myD[i,] = (myLik.indep.vector(par.for, mydat)-myLik.indep.vector(par.back,mydat))/(2*delta)
}
score.squared = myD%*%t(myD)
inv.hessian = solve(-myhessian.indep)
results=inv.hessian%*% score.squared %*%inv.hessian
return(results)
}
out=mle.CL(y1=y1,n1=n1,y2=y2,n2=n2)
mle=out$MLE
hessian.log=out$hessian.log
a1=mle[1];b1=mle[2]
a2=mle[3];b2=mle[4]
mypar=log(c(a1,b1,a2,b2))
mydat=list(y1=y1,n1=n1,y2=y2,n2=n2)
covar.sandwich=sandwich.var.cal(mypar, hessian.log, mydat)
myD <- matrix(c(-1, 1, 1, -1), nrow=1)
myVar.log <- as.numeric(myD %*% covar.sandwich %*% t(myD))
logOR <- log((a2/b2)/(a1/b1))
OR_CI=c(exp(logOR-1.96*sqrt(myVar.log)), exp(logOR+1.96*sqrt(myVar.log)))
#return(list(logOR=logOR, OR_CI=OR_CI, se=sqrt(myVar.log),hessian.log=hessian.log,conv=out$conv,mle=mle))
return(list(logOR=logOR, OR_CI=OR_CI, se=sqrt(myVar.log),hessian.log=hessian.log,conv=out$conv,mle=mle))
}
logit = function(p) log(p/(1-p))
expit = function(b) exp(b)/(1+exp(b))
dlogitnorm = function(p, mu, tau2){
(2*pi*tau2)^(-1/2)*exp(-(qlogis(p)-mu)^2/(2*tau2))/(p*(1-p))
}
integrand1<-function(n,y, mypar2, p.grid){
dbinom(y, size=n, prob=p.grid)*dlogitnorm(p.grid, mypar2[1], mypar2[2])
}
integrand2<-function(n,y,mypar2, p.grid){
dbinom(y, size=n, prob=p.grid)*dlogitnorm(p.grid, mypar2[1], mypar2[2])*2*(qlogis(p.grid)-mypar2[1])/(2*mypar2[2])
}
integrand3<-function(n,y,mypar2, p.grid){
dbinom(y, size=n, prob=p.grid)*dlogitnorm(p.grid, mypar2[1], mypar2[2])*(-1/(2*mypar2[2])+(qlogis(p.grid)-mypar2[1])^2/(2*mypar2[2]^2))
}
mystandize = function(MM){
diag(1/sqrt(diag(MM)))%*%MM%*%diag((1/sqrt(diag(MM))))
}
bn.cl=function(y1, n1, y2, n2){
id=c(1:length(y1))
mydat1 = data.frame(id,n1,y1,n2,y2)
names(mydat1) = c("id","Nd","SeY","Nn","SpY")
m = nrow(mydat1)
estim = estim.orig = mbse.orig = matrix(NA, nrow=4, ncol=1)
mySandwich = matrix(NA,nrow=4,ncol=4)
fit.SeY = glmmML(cbind(SeY, Nd-SeY)~1, data = mydat1, cluster = id, method= "ghq", n.points=8, control=list(epsilon=1e-08 , maxit=50000,trace=FALSE))
fit.SpY = glmmML(cbind(SpY, Nn-SpY)~1, data = mydat1, cluster = id, method= "ghq", n.points=8, control=list(epsilon=1e-08 , maxit=50000,trace=FALSE))
estim[c(1: 2), 1] = c(as.numeric(fit.SeY$coefficients), (fit.SeY$sigma)^2)
estim[c(3: 4), 1] = c(as.numeric(fit.SpY$coefficients), (fit.SpY$sigma)^2)
estim.orig[c(1: 2), 1] = c(plogis(estim[1, 1]), estim[2, 1])
estim.orig[c(3: 4), 1] = c(plogis(estim[3, 1]), estim[4, 1])
rownames(estim)=c("SeY", "SeY.S.2", "SpY", "SpY.S.2")
rownames(estim.orig)=c("SeY", "SeY.S.2", "SpY", "SpY.S.2")
I11.hat = solve(m*fit.SeY$variance)
I22.hat = solve(m*fit.SpY$variance)
int1 = int2 = int3 = rep(NA, length=m)
est1 = estim[c(1: 2), 1] ##plug in the point estimate based on sensitivity
for(i in 1: m){
int1[i] = integrate(integrand1, lower=0, upper=1, n=mydat1$Nd[i], mypar2=est1, y=mydat1$SeY[i])$value
int2[i] = integrate(integrand2, lower=0, upper=1, n=mydat1$Nd[i], mypar2=est1, y=mydat1$SeY[i])$value
int3[i] = integrate(integrand3, lower=0, upper=1, n=mydat1$Nd[i], mypar2=est1, y=mydat1$SeY[i])$value
}
deriveSeY.mu = int2/int1
deriveSeY.tau2 = int3/int1
B.SeY = cbind(deriveSeY.mu, deriveSeY.tau2)
int1 = int2 = int3 = rep(NA, length=m)
est2 = estim[c(3: 4), 1] ##plug in the point estimate based on specificity
for(i in 1: m){
int1[i] = integrate(integrand1, lower=0, upper=1, n=mydat1$Nn[i], mypar2=est2, y=mydat1$SpY[i])$value
int2[i] = integrate(integrand2, lower=0, upper=1, n=mydat1$Nn[i], mypar2=est2, y=mydat1$SpY[i])$value
int3[i] = integrate(integrand3, lower=0, upper=1, n=mydat1$Nn[i], mypar2=est2, y=mydat1$SpY[i])$value
}
deriveSpY.mu = int2/int1
deriveSpY.tau2 = int3/int1
B.SpY = cbind(deriveSpY.mu, deriveSpY.tau2)
I12.hat = t(B.SeY)%*%B.SpY/m
myoff.diag = solve(I11.hat)%*%I12.hat%*%solve(I22.hat)/m
myupper = cbind(fit.SeY$variance, myoff.diag)
mylower = cbind(t(myoff.diag), fit.SpY$variance)
myV = rbind(myupper, mylower)
colnames(myV)=c("SeY", "SeY.S.2", "SpY", "SpY.S.2")
rownames(myV)=c("SeY", "SeY.S.2", "SpY", "SpY.S.2")
return(list(coefficients=estim, par.orig=estim.orig, vcov=myV))
}
score.Li.func = function(PiY,SeY,SpY,n,n1,n0,PiY.est,SeY.est,SpY.est){
beta0 = PiY.est[1]; beta1 = SeY.est[1]; beta2 = SpY.est[1]
mu0 = expit(beta0); mu1 = expit(beta1); mu2 = expit(beta2)
phi0 = PiY.est[2]; phi1 = SeY.est[2]; phi2 = SpY.est[2]
theta0 = phi0/(1-phi0); theta1 = phi1/(1-phi1); theta2 = phi2/(1-phi2)
k01 = c(0:(PiY-1)); k02 = c(0:(n-PiY-1)); k03 = c(0:(n-1))
k11 = c(0:(SeY-1)); k12 = c(0:(n1-SeY-1)); k13 = c(0:(n1-1))
k21 = c(0:(SpY-1)); k22 = c(0:(n0-SpY-1)); k23 = c(0:(n0-1))
# notice for outbound
if(PiY == 0) k01 = NULL; if(PiY == n) k02 = NULL
if(SeY == 0) k11 = NULL; if(SeY == n1) k12 = NULL
if(SpY == 0) k21 = NULL; if(SpY == n0) k22 = NULL
Dbeta0 = Dbeta1 = Dbeta2 = Dphi0 = Dphi1 = Dphi2 = 0
Dphi0 = (sum(k01/(mu0+k01*theta0))+sum(k02/(1-mu0+k02*theta0))- sum(k03/(1+k03*theta0)))/((1-phi0)^2)
Dphi1 = (sum(k11/(mu1+k11*theta1))+sum(k12/(1-mu1+k12*theta1))-sum(k13/(1+k13*theta1)))/((1-phi1)^2)
Dphi2 = (sum(k21/(mu2+k21*theta2))+sum(k22/(1-mu2+k22*theta2))-sum(k23/(1+k23*theta2)))/((1-phi2)^2)
Dbeta0 = sum(mu0*(1-mu0)/(mu0+k01*theta0))-sum(mu0*(1-mu0)/(1-mu0+k02*theta0))
Dbeta1 = sum(mu1*(1-mu1)/(mu1+k11*theta1))-sum(mu1*(1-mu1)/(1-mu1+k12*theta1))
Dbeta2 = sum(mu2*(1-mu2)/(mu2+k21*theta2))-sum(mu2*(1-mu2)/(1-mu2+k22*theta2))
score.PiY = as.vector(c(Dbeta0,Dphi0))
score.SeY = as.vector(c(Dbeta1,Dphi1))
score.SpY = as.vector(c(Dbeta2,Dphi2))
return(list(score.PiY=score.PiY, score.SeY=score.SeY, score.SpY=score.SpY))
}
score.Li.all.func= function(SeY,SpY,n1,n0,SeY.est,SpY.est){
beta1 = SeY.est[1] ; beta2 = SpY.est[1]
mu1 = expit(beta1) ; mu2 = expit(beta2)
phi1 = SeY.est[2] ; phi2 =SpY.est[2]
theta1 = phi1/(1-phi1) ; theta2 = phi2/(1-phi2)
k11 = c(0:(SeY-1)); k12 = c(0:(n1-SeY-1)); k13 = c(0:(n1-1))
k21 = c(0:(SpY-1)); k22 = c(0:(n0-SpY-1)); k23 = c(0:(n0-1))
# notice for outbound
if(SeY == 0) k11 = NULL ; if(SeY == n1) k12 = NULL
if(SpY == 0) k21 = NULL ; if(SpY == n0) k22 = NULL
Dbeta1 = Dbeta2 = Dphi1 = Dphi2 = 0
Dphi1 = (sum(k11/(mu1+k11*theta1))+sum(k12/(1-mu1+k12*theta1))- sum(k13/(1+k13*theta1)))/((1-phi1)^2)
Dphi2 = (sum(k21/(mu2+k21*theta2))+sum(k22/(1-mu2+k22*theta2))- sum(k23/(1+k23*theta2)))/((1-phi2)^2)
Dbeta1 = sum(mu1*(1-mu1)/(mu1+k11*theta1))- sum(mu1*(1-mu1)/(1-mu1+k12*theta1))
Dbeta2 = sum(mu2*(1-mu2)/(mu2+k21*theta2))-sum(mu2*(1-mu2)/(1-mu2+k22*theta2))
score.SeY = as.vector(c(Dbeta1,Dphi1))
score.SpY = as.vector(c(Dbeta2,Dphi2))
return(list(score.SeY=score.SeY, score.SpY=score.SpY))
}
Fisher.inf = function(PiY.del,SeY.del,SpY.del,n.del,n1.del, n0.del, SeY,SpY,n1,n0,PiY.est,SeY.est, SpY.est){
m = length(SeY) # the length of all study, including case control study & cohort study
m2 = length(PiY.del) # the length of the cohort study only
I00.array = I01.array = I02.array = array(NA,c(2,2,m2))
I11.array = I12.array = I22.array = array(NA,c(2,2,m))
for(i in 1:m2){
temp = score.Li.func (PiY.del[i], SeY.del[i],SpY.del[i],n.del[i], n1.del[i],n0.del[i],PiY.est, SeY.est, SpY.est)
score.PiY = temp$score.PiY
score.SeY = temp$score.SeY
score.SpY = temp$score.SpY
I00.array[ , , i] = score.PiY%*%t(score.PiY)
I01.array[ , , i] = score.PiY%*%t(score.SeY)
I02.array[ , , i] = score.PiY%*%t(score.SpY)
}
for(i in 1:m){
temp = score.Li.all.func (SeY[i],SpY[i],n1[i],n0[i],SeY.est,SpY.est)
score.SeY = temp$score.SeY
score.SpY = temp$score.SpY
I11.array[ , , i] = score.SeY%*%t(score.SeY)
I12.array[ , , i] = score.SeY%*%t(score.SpY)
I22.array[ , , i] = score.SpY%*%t(score.SpY)
}
I00 = apply(I00.array, c(1,2), mean)
I01 = apply(I01.array, c(1,2), mean)
I02 = apply(I02.array, c(1,2), mean)
I11 = apply(I11.array, c(1,2), mean)
I12 = apply(I12.array, c(1,2), mean)
I22 = apply(I22.array, c(1,2), mean)
return(list(I00=I00, I01=I01, I02=I02, I11=I11, I12=I12, I22=I22))
}
tb.cl=function(n, PiY, SeY, n1, SpY, n2){
m = length(SeY) # the length of all study, including case control study & cohort study
m2 = sum(is.na(PiY)!=1) # the length of the cohort study only
estim = estim.orig = mbse.orig = matrix(NA,nrow=6,ncol=1)
mySandwich = matrix(NA,nrow=6,ncol=6)
mydat1 = data.frame(n,PiY,n1,SeY,n2, SpY)
names(mydat1) = c("n","PiY", "n1","SeY","n0","SpY")
mydat2 = mydat1[is.na(mydat1$PiY)==FALSE, ] ## dataset used for estimating prevalence
fit.PiY = betabin(cbind(PiY, n-PiY)~1, ~1, hessian=T, data=mydat2, link="logit")
fit.SeY = betabin(cbind(SeY, n1-SeY)~1, ~1, hessian=T, data=mydat1, link="logit")
fit.SpY = betabin(cbind(SpY, n0-SpY)~1, ~1, hessian=T, data=mydat1, link="logit")
estim[c(1:2), 1] = c(as.numeric(fit.PiY@param))
estim[c(3:4), 1] = c(as.numeric(fit.SeY@param))
estim[c(5:6), 1] = c(as.numeric(fit.SpY@param))
estim.orig[c(1: 2), 1] = c(expit(estim[1, 1]), estim[2, 1])
estim.orig[c(3: 4), 1] = c(expit(estim[3, 1]), estim[4, 1])
estim.orig[c(5: 6), 1] = c(expit(estim[5, 1]), estim[6, 1])
rownames(estim)=c("PiY1", "PiY2", "SeY1", "SeY2", "SpY1", "SpY2")
rownames(estim.orig)=c("PiY1", "PiY2", "SeY1", "SeY2", "SpY1", "SpY2")
fit.PiY.var = matrix(c(fit.PiY@varparam[1,1], fit.PiY@varparam[1,2], fit.PiY@varparam[2,1],fit.PiY@varparam[2,2]), nrow=2,byrow=TRUE)
fit.SeY.var = matrix(c(fit.SeY@varparam[1,1], fit.SeY@varparam[1,2], fit.SeY@varparam[2,1],fit.SeY@varparam[2,2]), nrow=2,byrow=TRUE)
fit.SpY.var = matrix(c(fit.SpY@varparam[1,1], fit.SpY@varparam[1,2], fit.SpY@varparam[2,1],fit.SpY@varparam[2,2]), nrow=2,byrow=TRUE)
I00.hat = solve(m2*fit.PiY.var)
I11.hat = solve(m*fit.SeY.var)
I22.hat = solve(m*fit.SpY.var)
estim.PiY = estim[c(1:2), 1]
estim.SeY = estim[c(3:4), 1]
estim.SpY = estim[c(5:6), 1]
temp = Fisher.inf(mydat2$PiY,mydat2$SeY,mydat2$SpY,mydat2$n,mydat2$n1,mydat2$n0, mydat1$SeY,mydat1$SpY,mydat1$n1,mydat1$n0,estim.PiY, estim.SeY, estim.SpY)
I01.hat = temp$I01 ; I02.hat = temp$I02 ; I12.hat = temp$I12
myoff.diag01 = solve(I00.hat)%*%I01.hat%*%solve(I11.hat)/m
myoff.diag02 = solve(I00.hat)%*%I02.hat%*%solve(I22.hat)/m
myoff.diag12 = solve(I11.hat)%*%I12.hat%*%solve(I22.hat)/m
myupper = cbind((fit.PiY.var), sqrt(m/m2)*(myoff.diag01), sqrt(m/m2)*(myoff.diag02))
mymiddle = cbind(sqrt(m/m2)*t(myoff.diag01), (fit.SeY.var), (myoff.diag12))
mylower = cbind(sqrt(m/m2)*t(myoff.diag02), t(myoff.diag12), (fit.SpY.var))
myV = rbind(myupper, mymiddle, mylower)
colnames(myV)=c("PiY1", "PiY2", "SeY1", "SeY2", "SpY1", "SpY2")
rownames(myV)=c("PiY1", "PiY2", "SeY1", "SeY2", "SpY1", "SpY2")
mu0.mbse = (estim.orig[1, 1]*(1-estim.orig[1, 1]))*sqrt(diag(myV)[1])
mu1.mbse = (estim.orig[3, 1]*(1-estim.orig[3, 1]))*sqrt(diag(myV)[3])
mu2.mbse = (estim.orig[5, 1]*(1-estim.orig[5, 1]))*sqrt(diag(myV)[5])
s1.2.mbse = sqrt(diag(myV)[2])
s2.2.mbse = sqrt(diag(myV)[4])
s3.2.mbse = sqrt(diag(myV)[6])
mbse.orig = c(mu0.mbse, s1.2.mbse, mu1.mbse, s2.2.mbse, mu2.mbse, s3.2.mbse)
return(list(coefficients=estim, estim.orig=estim.orig, vcov=myV))
}
tn.cl=function(n, PiY2, SeY1, SeY2, SpY1, SpY2, Nd, Nn){
estim = estim.orig = mbse.orig = matrix(NA, nrow=6, ncol=1)
m1=length(SeY1)
m2=length(SeY2)
m=m1+m2
PiY = c(rep(NA, length=m1),PiY2)
SeY = c(SeY1, SeY2)
SpY = c(SpY1, SpY2)
id=c(1:m)
mydat = data.frame(id, rep(n, length=m), PiY, Nd ,SeY,Nn, SpY)
names(mydat) = c("id", "Nt","PiY", "Nd","SeY","Nn","SpY") ## codebook for mydat: study id, number of total subjects, number of disease ppl among total subjects, number of diease ppl, number of being postive test among disease ppl, number of disease-free ppl, number of being negative test among disease-free ppl
mydat2=na.omit(mydat)
fit.PiY = glmmML(cbind(PiY, Nt-PiY)~1, data = mydat2, cluster = id, method= "ghq", n.points=8, control=list(epsilon=1e-08 , maxit=50000,trace=FALSE))
fit.SeY = glmmML(cbind(SeY, Nd-SeY)~1, data = mydat, cluster = id, method= "ghq", n.points=8, control=list(epsilon=1e-08 , maxit=50000,trace=FALSE))
fit.SpY = glmmML(cbind(SpY, Nn-SpY)~1, data = mydat, cluster = id, method= "ghq", n.points=8, control=list(epsilon=1e-08 , maxit=50000,trace=FALSE))
estim[c(1: 2),1] = c(as.numeric(fit.PiY$coefficients), (fit.PiY$sigma)^2)
estim[c(3: 4),1] = c(as.numeric(fit.SeY$coefficients), (fit.SeY$sigma)^2)
estim[c(5: 6),1] = c(as.numeric(fit.SpY$coefficients), (fit.SpY$sigma)^2)
estim.orig[c(1: 2),1] = c(plogis(estim[1,1]), estim[2,1])
estim.orig[c(3: 4),1] = c(plogis(estim[3,1]), estim[4,1])
estim.orig[c(5: 6),1] = c(plogis(estim[5,1]), estim[6,1])
rownames(estim)=c("PiY1", "PiY2", "SeY1", "SeY2", "SpY1", "SpY2")
rownames(estim.orig)=c("PiY1", "PiY2", "SeY1", "SeY2", "SpY1", "SpY2")
I00.hat = solve(m2*fit.PiY$variance)
I11.hat = solve(m*fit.SeY$variance)
I22.hat = solve(m*fit.SpY$variance)
int1 = int2 = int3 = rep(NA, length=m2)
est0 = estim[c(1: 2),1] ##plug in the point estimate based on disease prevalence
for(i in 1: m2){
int1[i] = integrate(integrand1, lower=0, upper=1, n=mydat2$Nt[i], mypar2=est0, y=mydat2$PiY[i])$value
int2[i] = integrate(integrand2, lower=0, upper=1, n=mydat2$Nt[i], mypar2=est0, y=mydat2$PiY[i])$value
int3[i] = integrate(integrand3, lower=0, upper=1, n=mydat2$Nt[i], mypar2=est0, y=mydat2$PiY[i])$value
}
##
derivePiY.mu = int2/int1
derivePiY.tau2 = int3/int1
B.PiY = cbind(derivePiY.mu, derivePiY.tau2)
int1 = int2 = int3 = rep(NA, length=m)
est1 = estim[c(3: 4),1] ##plug in the point estimate based on sensitivity
for(i in 1: m){
int1[i] = integrate(integrand1, lower=0, upper=1, n=mydat$Nd[i], mypar2=est1, y=mydat$SeY[i])$value
int2[i] = integrate(integrand2, lower=0, upper=1, n=mydat$Nd[i], mypar2=est1, y=mydat$SeY[i])$value
int3[i] = integrate(integrand3, lower=0, upper=1, n=mydat$Nd[i], mypar2=est1, y=mydat$SeY[i])$value
}
deriveSeY.mu = int2/int1
deriveSeY.tau2 = int3/int1
B.SeY = cbind(deriveSeY.mu, deriveSeY.tau2)
B.SeY.del = B.SeY[-c(1:m1), ] ## delete the first m1 studies
int1 = int2 = int3 = rep(NA, length=m)
est2 = estim[c(5: 6),1] ##plug in the point estimate based on specificity
for(i in 1: m){
int1[i] = integrate(integrand1, lower=0, upper=1, n=mydat$Nn[i], mypar2=est2, y=mydat$SpY[i])$value
int2[i] = integrate(integrand2, lower=0, upper=1, n=mydat$Nn[i], mypar2=est2, y=mydat$SpY[i])$value
int3[i] = integrate(integrand3, lower=0, upper=1, n=mydat$Nn[i], mypar2=est2, y=mydat$SpY[i])$value
}
deriveSpY.mu = int2/int1
deriveSpY.tau2 = int3/int1
B.SpY = cbind(deriveSpY.mu, deriveSpY.tau2)
B.SpY.del = B.SpY[-c(1:m1), ] ## delete the first m1 studies
I01.hat = t(B.PiY)%*%B.SeY.del/m2
I02.hat = t(B.PiY)%*%B.SpY.del/m2
I12.hat = t(B.SeY)%*%B.SpY/m
myoff.diag01 = solve(I00.hat)%*%I01.hat%*%solve(I11.hat)/m
myoff.diag02 = solve(I00.hat)%*%I02.hat%*%solve(I22.hat)/m
myoff.diag12 = solve(I11.hat)%*%I12.hat%*%solve(I22.hat)/m
myupper = cbind(fit.PiY$variance, sqrt(m/m2)*(myoff.diag01), sqrt(m/m2)*(myoff.diag02))
mymiddle = cbind(sqrt(m/m2)*t(myoff.diag01), fit.SeY$variance, (myoff.diag12))
mylower = cbind(sqrt(m/m2)*t(myoff.diag02), t(myoff.diag12), fit.SpY$variance)
myV = rbind(myupper, mymiddle, mylower)
colnames(myV)=c("PiY1", "PiY2", "SeY1", "SeY2", "SpY1", "SpY2")
rownames(myV)=c("PiY1", "PiY2", "SeY1", "SeY2", "SpY1", "SpY2")
return(list(coefficients=estim, estim.orig=estim.orig, vcov=myV))
}
if (missing(data)){data=NULL}
if (is.null(data)){
stop("The dataset must be specified.")
}
if (missing(k)){k=NULL}
if (is.null(k)){
stop("The number of outcomes must be specified.")
}
if (missing(type)){type=NULL}
if (is.null(type)){
stop('The type of outcome must be specified. Please input "continuous" or "binary". ')
}
if (missing(method)){method=NULL}
if (is.null(method)){
stop("A method must be specified. ")
}
if (missing(rhow)){rhow=NULL}
if ((is.null(rhow))&(method=="nn.reml")){
stop('The within-study correlations are required for the input method "nn.reml".')
}
if (k>2){
stop('The method for MMA with more than 2 outcomes are currently under development. ')
}
if (type=="continuous"){
y1=data$y1
s1=data$s1
y2=data$y2
s2=data$s2
if(method=="nn.cl"){
fit=nn.cl(y1, s1, y2, s2)}
if(method=="nn.reml"){
fit=nn.reml(y1, s1, y2, s2, rhow)}
if(method=="nn.mom"){
fit=nn.mom(y1, s1, y2, s2)}
if(method=="nn.rs"){
fit=nn.rs(y1, s1, y2, s2)}
if ((method%in%c("nn.reml", "nn.cl", "nn.mom", "nn.rs"))!=1){
stop('The input method is not available for continuous outcomes. Please choose from
"nn.reml", "nn.cl", "nn.mom", or "nn.rs". ')
}
}
if(type=="binary"){
if (method=="bb.cl"){
y1=data$y1
n1=data$n1
y2=data$y2
n2=data$n2
fit=bb.cl(y1,n1,y2,n2)
}
if (method=="bn.cl"){
y1=data$y1
n1=data$n1
y2=data$y2
n2=data$n2
fit=bn.cl(y1,n1,y2,n2)
}
if (method=="tb.cl"){
n=data$n
PiY=data$PiY
SeY=data$SeY
n1=data$n1
SpY=data$SpY
n2=data$n2
fit=tb.cl(n, PiY, SeY, n1, SpY, n2)
}
if (method=="tn.cl"){
n=data$n
PiY2=data$PiY2
SeY1=data$SeY1
SeY2=data$SeY2
SpY1=data$SpY1
SpY2=data$SpY2
Nd=data$Nd
Nn=data$Nn
fit=tn.cl(n, PiY2, SeY1, SeY2, SpY1, SpY2, Nd, Nn)
}
if ((method%in%c("bb.cl", "bn.cl", "tb.cl", "tn.cl"))!=1){
stop('The input method is not available for binary outcomes. Please choose from
"bb.cl", "bn.cl", "tb.cl", or "tn.cl". ')
}
}
res=list(type=type, k=k, method=method, coefficients=fit$coefficients, vcov=fit$vcov)
if(method=="bb.cl"){
res=list(type=type, k=k, method=method, logOR=fit$logOR, OR_CI=fit$OR_CI, se=fit$se,hessian.log=fit$hessian.log,conv=fit$conv,mle=fit$mle)
}
class(res) = c("mmeta")
return(res)
}
​
​
​
​
​