├── ChangeLog ├── DESCRIPTION ├── MD5 ├── NAMESPACE ├── R ├── BCPNN.R ├── GPS.R ├── PRR.R ├── PhViD.search.R ├── RFET.R ├── ROR.R └── as.PhViD.R ├── data └── PhViDdata.frame.rda ├── inst └── CITATION └── man ├── BCPNN.Rd ├── GPS.Rd ├── PRR.Rd ├── PhViD-package.Rd ├── PhViD.search.Rd ├── PhViDdata.frame.Rd ├── RFET.Rd ├── ROR.Rd └── as.PhViD.Rd /ChangeLog: -------------------------------------------------------------------------------- 1 | CHANGES IN PhViD 1.02 2 | 3 | 4 | o fixed the PRR function. 5 | There was an error in the formula used for the PRR 6 | The formula for the variance has also been modified. It is not the one proposed in an Puijenbroek et al. (2002). 7 | var[log(PRR)] = 1/n11 - 1/(n11 + n10) + 1/n01 - 1/(n01 + n00) 8 | 9 | 10 | CHANGES IN PhViD 1.03 11 | 12 | o typo in PhViD.gui: notifications -> reports 13 | o typo in GPS help file (thanks to Brock Stewart) log(lambda,2) 14 | o dealing with encodage issues. All files are encoded in UTF-8 15 | 16 | CHANGES IN PhViD 1.04 17 | 18 | o compression of the data folder for the compilation : R CMD build --resave-data PhViD 19 | 20 | 21 | CHANGES IN PhViD 1.06 22 | 23 | o I removed the graphical interface as it generated too many warnings during the package building... 24 | 25 | CHANGES IN PhViD 1.07 26 | 27 | o RAS 28 | 29 | CHANGES IN PhViD 1.08 30 | 31 | o Correction of a mistake in the marginal likelihood of GPS (in case of TRONC = T) thanks to John Ihrie 32 | -------------------------------------------------------------------------------- /DESCRIPTION: -------------------------------------------------------------------------------- 1 | Package: PhViD 2 | Type: Package 3 | Title: PharmacoVigilance Signal Detection 4 | Version: 1.0.8 5 | Date: 2016-11-03 6 | Author: Ismaïl Ahmed & Antoine Poncet 7 | Maintainer: Ismaïl Ahmed 8 | Depends: R (>= 2.10), LBE, MCMCpack 9 | Description: A collection of several pharmacovigilance signal detection methods extended to the multiple comparison setting. 10 | License: GPL-2 11 | Encoding: UTF-8 12 | NeedsCompilation: no 13 | Packaged: 2016-11-03 09:45:18 UTC; isma 14 | SystemRequirements: Tcl/Tk package TkTable. 15 | Repository: CRAN 16 | Date/Publication: 2016-11-03 12:14:08 17 | -------------------------------------------------------------------------------- /MD5: -------------------------------------------------------------------------------- 1 | 62de8dd62200339dda4fac23a67885e2 *ChangeLog 2 | bd794208b2c6bf601013b1abc183a348 *DESCRIPTION 3 | 9e1839a9dbeec21db76f2b4214c352e0 *NAMESPACE 4 | d843a62ed1edaf727198371eb23139ad *R/BCPNN.R 5 | a809ebfa01e2a2847e6ff736c21a43e9 *R/GPS.R 6 | d43578013c81618cb70cec718b42d3b7 *R/PRR.R 7 | e6fb5746f11b7ae59bed5a96f7d39cb9 *R/PhViD.search.R 8 | 3af8d1ea24e5ac8f1d1422baf3ba5384 *R/RFET.R 9 | f7d9a9202eda973cedc2211ea4f559ce *R/ROR.R 10 | d11acff950334873e71b4e224df5fd95 *R/as.PhViD.R 11 | 93b87747bda6a3d8ee898fbef7bbd280 *data/PhViDdata.frame.rda 12 | a139fcef1edb8b7bc42cbb6a3813d552 *inst/CITATION 13 | 245d4d60666e34f537ebe83b6ffde887 *man/BCPNN.Rd 14 | cb521aba6f3f911d055c8c3a88fd64ae *man/GPS.Rd 15 | 3474c5d9e34b3b1b2c7433dee528f657 *man/PRR.Rd 16 | 9bc1fa65da545586f72cf6049bb6e085 *man/PhViD-package.Rd 17 | 3d0cdb02b5f4bc1c4ca7a3bf6e5c867e *man/PhViD.search.Rd 18 | 49169415fec5918a7dc3ff41d722f39b *man/PhViDdata.frame.Rd 19 | f028314d1335ca819ab47c3762cd87d0 *man/RFET.Rd 20 | eb0487c20a8798053e69ce862c5da071 *man/ROR.Rd 21 | eaae781ba198df1d9e5337a062d9af77 *man/as.PhViD.Rd 22 | -------------------------------------------------------------------------------- /NAMESPACE: -------------------------------------------------------------------------------- 1 | # Default NAMESPACE created by R 2 | # Remove the previous line if you edit this file 3 | 4 | # Export all names 5 | exportPattern(".") 6 | 7 | # Import all packages listed as Imports or Depends 8 | import( 9 | LBE, 10 | MCMCpack 11 | ) 12 | 13 | importFrom("stats", "dnbinom", "fisher.test", "nlm", "pgamma", 14 | "pnbinom", "pnorm", "qnorm", "xtabs") -------------------------------------------------------------------------------- /R/BCPNN.R: -------------------------------------------------------------------------------- 1 | `BCPNN` <- 2 | function(DATABASE, RR0 = 1, MIN.n11 = 1, DECISION = 1, 3 | DECISION.THRES = 0.05, RANKSTAT = 1, MC = FALSE, 4 | NB.MC = 10000) { 5 | 6 | DATA <- DATABASE$data 7 | N <- DATABASE$N 8 | L <- DATABASE$L 9 | 10 | n11 <- DATA[,1] 11 | n1. <- DATA[,2] 12 | n.1 <- DATA[,3] 13 | n10 <- n1. - n11 14 | n01 <- n.1 - n11 15 | n00 <- N - (n11+n10+n01) 16 | E <- n1. * n.1 / N # les counts attendus 17 | 18 | if(MIN.n11 > 1) { 19 | E <- E[n11 >= MIN.n11] 20 | n1. <- n1.[n11 >= MIN.n11] 21 | n.1 <- n.1[n11 >= MIN.n11] 22 | n10 <- n10[n11 >= MIN.n11] 23 | n01 <- n01[n11 >= MIN.n11] 24 | n00 <- n00[n11 >= MIN.n11] 25 | # LL <- data.frame(drugs=L[,1],events=L[,2],n11) 26 | # LL1 <- LL[,1][n11 >= MIN.n11] 27 | # LL2 <- LL[,2][n11 >= MIN.n11] 28 | # rm(list="L") 29 | # L <- data.frame(LL1,LL2) 30 | L <- L[n11 >= MIN.n11,] 31 | n11 <- n11[n11 >= MIN.n11] 32 | } 33 | 34 | Nb.Cell <- length(n11) 35 | 36 | if (MC == FALSE) { 37 | post.H0 <- matrix(nrow=Nb.Cell,ncol=length(RR0)) 38 | p1 <- 1 + n1. 39 | p2 <- 1 + N - n1. 40 | q1 <- 1 + n.1 41 | q2 <- 1 + N - n.1 42 | r1 <- 1 + n11 43 | r2b <- N - n11 -1 + (2+N)^2/(q1*p1) 44 | EICb <- log(2)^(-1) * (digamma(r1) - digamma(r1+r2b) - (digamma(p1) - digamma(p1+p2) + digamma(q1) - digamma(q1+q2))) 45 | VICb <- log(2)^(-2) * (trigamma(r1) - trigamma(r1+r2b) + (trigamma(p1) - trigamma(p1+p2) + trigamma(q1) - trigamma(q1+q2))) 46 | post.H0 <- pnorm(log(RR0),EICb,sqrt(VICb)) 47 | # Calculation of the Lower Bound 48 | LB <- qnorm(0.025,EICb,sqrt(VICb)) 49 | } 50 | 51 | if (MC == TRUE) { # Advanced option MC 52 | n1. <- n11 + n10 53 | n.1 <- n11 + n01 54 | Nb_Obs <- length(n11) 55 | 56 | ## Nouvelles priors 57 | q1. <- (n1. +.5)/(N +1) 58 | q.1 <- (n.1 +.5)/(N +1) 59 | q.0 <- (N - n.1 +.5)/(N +1) 60 | q0. <- (N - n1. +.5)/(N +1) 61 | 62 | a.. <- .5/(q1.*q.1) ## le .5 devrait pouvoir être changé 63 | 64 | a11 <- q1.*q.1* a.. 65 | a10 <- q1.*q.0* a.. 66 | a01 <- q0.*q.1* a.. 67 | a00 <- q0.*q.0* a.. 68 | 69 | g11 <- a11 + n11 70 | g10 <- a10 + n10 71 | g01 <- a01 + n01 72 | g00 <- a00 + n00 73 | g1. <- g11 + g10 74 | g.1 <- g11 + g01 75 | 76 | post.H0 <- vector(length=length(n11)) 77 | LB <- vector(length=length(n11)) 78 | quantile <- vector("numeric",length=length(n11)) 79 | for (m in 1 : length(n11)){ 80 | p <- rdirichlet(NB.MC,c(g11[m],g10[m],g01[m],g00[m])) 81 | p11 <- p[,1] 82 | p1. <- p11 + p[,2] 83 | p.1 <- p11 + p[,3] 84 | IC_monte <- log(p11/(p1.* p.1)) 85 | temp <- IC_monte < log(RR0) 86 | post.H0[m] <- sum(temp)/NB.MC 87 | LB[m] <- sort(IC_monte)[round(NB.MC * 0.025)] 88 | } 89 | rm(p11,p1.,p.1,IC_monte,temp) 90 | gc() 91 | } 92 | 93 | if (RANKSTAT==1) RankStat <- post.H0 94 | if (RANKSTAT==2) RankStat <- LB 95 | 96 | if (RANKSTAT==1) { 97 | FDR <- (cumsum(post.H0[order(post.H0)]) / (1:length(post.H0))) 98 | FNR <- rev(cumsum((1-post.H0)[order(1-post.H0)])) / (Nb.Cell - 1:length(post.H0)) 99 | Se <- cumsum((1-post.H0)[order(post.H0)]) / (sum(1-post.H0)) 100 | Sp <- rev(cumsum(post.H0[order(1-post.H0)])) / (Nb.Cell - sum(1-post.H0)) 101 | } 102 | 103 | if (RANKSTAT==2) { 104 | FDR <- (cumsum(post.H0[order(LB,decreasing=TRUE)]) / (1:length(post.H0))) 105 | FNR <- rev(cumsum((1-post.H0)[order(1-LB,decreasing=TRUE)])) / (Nb.Cell - 1:length(post.H0)) 106 | Se <- cumsum((1-post.H0)[order(LB,decreasing=TRUE)]) / (sum(1-post.H0)) 107 | Sp <- rev(cumsum(post.H0[order(1-LB,decreasing=TRUE)])) / (Nb.Cell - sum(1-post.H0)) 108 | } 109 | 110 | # Calculation of the number of signals according to the decision rule (pp/FDR/Nb of Signals) 111 | if (DECISION == 1) Nb.signaux <- sum(FDR <= DECISION.THRES) 112 | if (DECISION == 2) Nb.signaux <- min(DECISION.THRES,Nb.Cell) 113 | if (DECISION == 3) { 114 | if (RANKSTAT==1) Nb.signaux <- sum(RankStat <= DECISION.THRES, na.rm = TRUE) 115 | if (RANKSTAT==2) Nb.signaux <- sum(RankStat >= DECISION.THRES, na.rm = TRUE) 116 | } 117 | 118 | 119 | ############################ SORTIE DE LA FONCTION ############################# 120 | RES <- vector(mode="list") 121 | 122 | #RES$LIBEL <- L 123 | #colnames(RES$LIBEL) <- c("DRUG","EVENT") 124 | 125 | #RES$param.D <- param.D 126 | RES$INPUT.PARAM <- data.frame(RR0,MIN.n11,DECISION,DECISION.THRES,RANKSTAT) 127 | #colnames(RES$INPUT.PARAM) <- c("RR0","MIN.n11","DECISION","DECISION.THRES","RANKSTAT") 128 | 129 | # Presentation of the statistics calculated for each couple 130 | ##RES$STATISTIC <- data.frame(n11,post.H0,LB) 131 | ##rownames(RES$STATISTIC) <- paste(L[,1],L[,2]) # liste des libellés ingénue 132 | ##colnames(RES$STATISTIC) <- c("count","postH0","Lower Bound") 133 | 134 | # STATISTICAL VALUE TO BE CONSIDERED (used in function compare) 135 | #RES$COMPARE <- vector(mode="list") 136 | #RES$COMPARE$RANKSTAT <- RANKSTAT 137 | #RES$COMPARE$STAT <- RankStat 138 | 139 | # SIGNALS RESULTS and presentation 140 | if (RANKSTAT==1) { 141 | RES$ALLSIGNALS <- data.frame( L[,1][order(RankStat)], 142 | L[,2][order(RankStat)], 143 | n11[order(RankStat)], 144 | E[order(RankStat)], 145 | RankStat[order(RankStat)], 146 | (n11/E)[order(RankStat)], 147 | n1.[order(RankStat)], 148 | n.1[order(RankStat)], 149 | FDR, FNR, Se, Sp ) 150 | colnames(RES$ALLSIGNALS) <- c("drug code","event effect","count","expected count","post.H0", 151 | "n11/E","drug margin","event margin","FDR","FNR","Se","Sp") 152 | } 153 | if (RANKSTAT==2) { 154 | RES$ALLSIGNALS <- data.frame( L[,1][order(RankStat, decreasing=TRUE)], 155 | L[,2][order(RankStat, decreasing=TRUE)], 156 | n11[order(RankStat, decreasing=TRUE)], 157 | E[order(RankStat,decreasing=TRUE)], 158 | RankStat[order(RankStat,decreasing=TRUE)], 159 | (n11/E)[order(RankStat,decreasing=TRUE)], 160 | n1.[order(RankStat,decreasing=TRUE)], 161 | n.1[order(RankStat,decreasing=TRUE)], 162 | FDR, FNR, Se, Sp, 163 | post.H0[order(RankStat,decreasing=TRUE)] ) 164 | colnames(RES$ALLSIGNALS) <- c("drug code","event effect","count","expected count","Q_0.025(log(IC))", 165 | "n11/E","drug margin","event margin","FDR","FNR","Se","Sp","postH0") 166 | } 167 | 168 | # List of Signals generated according to the DECISION.THRES 169 | RES$SIGNALS <- RES$ALLSIGNALS[1:Nb.signaux,] 170 | 171 | # FDR,FNR,Se,Sp 172 | #RES$OpChar <- data.frame(FDR,FNR,Se,Sp) 173 | #rownames(RES$OpChar) <- paste(RES$ALLSIGNALS[,1],RES$ALLSIGNALS[,2]) 174 | 175 | # Number of signals 176 | RES$NB.SIGNALS <- Nb.signaux 177 | RES 178 | 179 | } 180 | 181 | -------------------------------------------------------------------------------- /R/GPS.R: -------------------------------------------------------------------------------- 1 | `GPS` <- 2 | function(DATABASE, RR0 = 1, MIN.n11 = 1, DECISION = 1, DECISION.THRES = 0.05, RANKSTAT = 1, TRONC = FALSE, TRONC.THRES = 1, PRIOR.INIT = c(alpha1= 0.2, beta1= 0.06, alpha2=1.4, beta2=1.8, w=0.1), PRIOR.PARAM = NULL){ 3 | 4 | DATA <- DATABASE$data 5 | N <- DATABASE$N 6 | L <- DATABASE$L 7 | 8 | n11 <- DATA[,1] # les nij ou n11 (c'est pareil) 9 | n1. <- DATA[,2] # les marges lignes (effets indésirables) 10 | n.1 <- DATA[,3] # les marges colonnes (médicaments) 11 | E <- DATA[,2] * DATA[,3] / N # les effectifs attendus 12 | 13 | P_OUT <- TRUE 14 | 15 | if (is.null(PRIOR.PARAM)) { 16 | P_OUT <- FALSE 17 | 18 | 19 | if (TRONC == FALSE){ 20 | # Dumouchel situation (we will consider the whole contingency table with 0) 21 | data_cont<-xtabs(DATA[,1]~L[,1]+L[,2]) 22 | n1._mat <- apply(data_cont,1, sum) # on recalcule les marges des lignes... 23 | n.1_mat <- apply(data_cont,2, sum) # ...et des colonnes 24 | n1._c <- rep(n1._mat, times=length(n.1_mat)) 25 | n.1_c <- rep(n.1_mat, each=length(n1._mat)) 26 | E_c <- n1._c * n.1_c / N 27 | n11_c <- as.vector(data_cont) 28 | 29 | p_out <-suppressWarnings(nlm(.lik2NB, p=PRIOR.INIT, n11=n11_c, E=E_c, iterlim=500)) 30 | } 31 | 32 | # alternative tenant compte de la troncature 33 | if (TRONC == TRUE){ 34 | tronc <- TRONC.THRES - 1 # si l'utilisateur a décidé de tronquer sa base 35 | p_out <-suppressWarnings(nlm(.likTronc2NB, p=PRIOR.INIT, n11=n11[n11>=TRONC.THRES], E=E[n11>=TRONC.THRES], tronc,iterlim=500)) 36 | } 37 | 38 | PRIOR.PARAM <-p_out$estimate 39 | code.convergence <- p_out$code 40 | } 41 | 42 | # Algorithm allowing to conserve only the couples presenting the minimal nb of notifications entered by the user 43 | if(MIN.n11 > 1) { 44 | E <- E[n11 >= MIN.n11] 45 | n1. <- n1.[n11 >= MIN.n11] 46 | n.1 <- n.1[n11 >= MIN.n11] 47 | LL <- data.frame(drugs=L[,1],events=L[,2],n11) 48 | LL1 <- LL[,1][n11 >= MIN.n11] 49 | LL2 <- LL[,2][n11 >= MIN.n11] 50 | rm(list="L") 51 | L <- data.frame(LL1,LL2) 52 | n11 <- n11[n11 >= MIN.n11] 53 | } 54 | 55 | Nb.Cell <- length(n11) 56 | post.H0 <- vector(length=Nb.Cell) 57 | 58 | 59 | # Posterior probability of the null hypothesis 60 | Q <- PRIOR.PARAM[5]*dnbinom(n11,size=PRIOR.PARAM[1],prob=PRIOR.PARAM[2]/(PRIOR.PARAM[2]+E)) / 61 | (PRIOR.PARAM[5]*dnbinom(n11,size=PRIOR.PARAM[1],prob=PRIOR.PARAM[2]/(PRIOR.PARAM[2]+E)) + (1-PRIOR.PARAM[5])* 62 | dnbinom(n11,size=PRIOR.PARAM[3],prob=PRIOR.PARAM[4]/(PRIOR.PARAM[4]+E))) 63 | 64 | post.H0 <- Q*pgamma(RR0,PRIOR.PARAM[1]+n11,PRIOR.PARAM[2]+E) +(1-Q)*pgamma(RR0,PRIOR.PARAM[3]+n11,PRIOR.PARAM[4]+E) # proba a posteriori de H0 65 | 66 | # Posterior Expectation of Lambda 67 | postE <- log(2)^(-1)*(Q*(digamma(PRIOR.PARAM[1]+n11)-log(PRIOR.PARAM[2]+E))+(1-Q)*(digamma(PRIOR.PARAM[3]+n11)-log(PRIOR.PARAM[4]+E))) 68 | 69 | 70 | # Algorithme allowing the calculation of the CI Lower Bound (at Seuil%) 71 | 72 | # Algorithm Emmanuel Roux 73 | 74 | 75 | # Calculation of the Lower Bound. (VALUEbis is former LBQ) 76 | LB <- .QuantileDuMouchel(0.05,Q,PRIOR.PARAM[1]+n11,PRIOR.PARAM[2]+E,PRIOR.PARAM[3]+n11,PRIOR.PARAM[4]+E) 77 | 78 | 79 | # Assignment based on the method (pp/postE/LB) 80 | if (RANKSTAT==1) RankStat <- post.H0 81 | if (RANKSTAT==2) RankStat <- LB 82 | if (RANKSTAT==3) RankStat <- postE 83 | 84 | # FDR, FNR, Se and Sp based on the method (pp/postE/LB) 85 | if (RANKSTAT==1) { 86 | FDR <- (cumsum(post.H0[order(RankStat)]) / (1:length(post.H0))) 87 | FNR <- rev(cumsum((1-post.H0)[order(1-RankStat)])) / (Nb.Cell - 1:length(post.H0)) 88 | Se <- cumsum((1-post.H0)[order(RankStat)]) / (sum(1-post.H0)) 89 | Sp <- rev(cumsum(post.H0[order(1-RankStat)])) / (Nb.Cell - sum(1-post.H0)) 90 | } 91 | if (RANKSTAT==2 | RANKSTAT==3) { 92 | FDR <- (cumsum(post.H0[order(RankStat,decreasing=TRUE)]) / (1:length(post.H0))) 93 | FNR <- rev(cumsum((1-post.H0)[order(1-RankStat,decreasing=TRUE)])) / (Nb.Cell - 1:length(post.H0)) 94 | Se <- cumsum((1-post.H0)[order(RankStat,decreasing=TRUE)]) / (sum(1-post.H0)) 95 | Sp <- rev(cumsum(post.H0[order(1-RankStat,decreasing=TRUE)])) / (Nb.Cell - sum(1-post.H0)) 96 | } 97 | 98 | # Number of signals according to the decision rule (pp/FDR/Nb of Signals) 99 | 100 | if (DECISION == 1) Nb.signaux <- sum(FDR <= DECISION.THRES) 101 | if (DECISION == 2) Nb.signaux <- min(DECISION.THRES,Nb.Cell) 102 | if (DECISION == 3) { 103 | if (RANKSTAT==1) Nb.signaux <- sum(RankStat <= DECISION.THRES, na.rm = TRUE) 104 | if (RANKSTAT==2 | RANKSTAT==3) Nb.signaux <- sum(RankStat >= DECISION.THRES, na.rm = TRUE) 105 | } 106 | 107 | 108 | ############################ Output ############################# 109 | RES <- vector(mode="list") 110 | 111 | #RES$LIBEL <- L 112 | #colnames(RES$LIBEL) <- c("DRUG","EVENT") 113 | 114 | # list of the parameters used 115 | RES$INPUT.PARAM <- data.frame(RR0,MIN.n11,DECISION,DECISION.THRES,RANKSTAT,TRONC,TRONC.THRES) 116 | #colnames(RES$INPUT.PARAM) <- c("RR0","MIN.n11","TRONC","TRONC.THRES","DECISION","DECISION.THRES","RANKSTAT") 117 | 118 | RES$PARAM <- vector(mode="list") 119 | # vector of the final a priori parameters (if P_OUT=TRUE) 120 | if (P_OUT==TRUE) RES$PARAM$PRIOR.PARAM <- data.frame(PRIOR.PARAM) 121 | # vector of the initial a priori and final a priori parameters (if P_OUT=FALSE) 122 | if (P_OUT==FALSE) { 123 | RES$PARAM$PRIOR.INIT <- data.frame(PRIOR.INIT) 124 | RES$PARAM$PRIOR.PARAM <- PRIOR.PARAM 125 | RES$PARAM$CONVERGENCE <- code.convergence 126 | } 127 | #RES$PARAM$Q <- Q 128 | 129 | # Presentation of the statistics calculated for each couple 130 | ##RES$STATISTIC <- data.frame(n11,post.H0,LB,postE) 131 | ##rownames(RES$STATISTIC) <- paste(L[,1],L[,2]) 132 | ##colnames(RES$STATISTIC) <- c("Effectif","postH0","Lower Bound","postE") 133 | 134 | # STATISTICAL VALUE TO BE CONSIDERED (used in function compare) 135 | #RES$COMPARE <- vector(mode="list") 136 | #RES$COMPARE$RANKSTAT <- RANKSTAT 137 | #RES$COMPARE$STAT <- RankStat 138 | 139 | # SIGNALS RESULTS and presentation 140 | if (RANKSTAT==1) { 141 | RES$ALLSIGNALS <- data.frame( L[,1][order(RankStat)], 142 | L[,2][order(RankStat)], 143 | n11[order(RankStat)], 144 | E[order(RankStat)], 145 | RankStat[order(RankStat)], 146 | (n11/E)[order(RankStat)], 147 | n1.[order(RankStat)], 148 | n.1[order(RankStat)], 149 | FDR, FNR, Se, Sp ) 150 | colnames(RES$ALLSIGNALS) <- c("drug","event","count","expected count","postH0", 151 | "n11/E","drug margin","event margin","FDR","FNR","Se","Sp") 152 | } 153 | if (RANKSTAT==2 | RANKSTAT==3) { 154 | RES$ALLSIGNALS <- data.frame( L[,1][order(RankStat, decreasing=TRUE)], 155 | L[,2][order(RankStat, decreasing=TRUE)], 156 | n11[order(RankStat, decreasing=TRUE)], 157 | E[order(RankStat,decreasing=TRUE)], 158 | RankStat[order(RankStat,decreasing=TRUE)], 159 | (n11/E)[order(RankStat,decreasing=TRUE)], 160 | n1.[order(RankStat,decreasing=TRUE)], 161 | n.1[order(RankStat,decreasing=TRUE)], 162 | FDR, FNR, Se, Sp, 163 | post.H0[order(RankStat,decreasing=TRUE)] ) 164 | if (RANKSTAT==2) colnames(RES$ALLSIGNALS) <- c("drug","event","count","expected count", 165 | "Q_0.05(lambda)","n11/E","drug margin","event margin","FDR","FNR","Se","Sp","postH0") 166 | if (RANKSTAT==3) colnames(RES$ALLSIGNALS) <- c("drug","event","count","expected count", 167 | "post E(Lambda)","n11/E","drug margin","event margin","FDR","FNR","Se","Sp","postH0") 168 | 169 | } 170 | 171 | # List of Signals generated according to the method 172 | RES$SIGNALS <- RES$ALLSIGNALS[1:Nb.signaux,] 173 | 174 | # FDR,FNR,Se,Sp 175 | #RES$OpChar <- data.frame(FDR,FNR,Se,Sp) 176 | #rownames(RES$OpChar) <- paste(RES$ALLSIGNALS[,1],RES$ALLSIGNALS[,2]) 177 | 178 | # Number of signals 179 | RES$NB.SIGNALS <- Nb.signaux 180 | 181 | RES 182 | } 183 | 184 | .QuantileDuMouchel<-function(Seuil,Q,a1,b1,a2,b2) { 185 | m<-rep(-100000,length(Q)) 186 | M<-rep(100000,length(Q)) 187 | x<-rep(1,length(Q)) 188 | Cout<- .FCoutQuantileDuMouchel(x,Seuil,Q,a1,b1,a2,b2) 189 | while (max(round(Cout*1e4))!=0) { 190 | S<-sign(Cout) 191 | xnew<-(1+S)/2*((x+m)/2)+(1-S)/2*((M+x)/2) 192 | M<-(1+S)/2*x+(1-S)/2*M 193 | m<-(1+S)/2*m+(1-S)/2*x 194 | x<-xnew 195 | Cout<-.FCoutQuantileDuMouchel(x,Seuil,Q,a1,b1,a2,b2) 196 | } 197 | x 198 | } 199 | .FCoutQuantileDuMouchel<-function(p,Seuil,Q,a1,b1,a2,b2) { 200 | Q*pgamma(p,shape=a1,rate=b1)+(1-Q)*pgamma(p,shape=a2,rate=b2)-Seuil 201 | } 202 | 203 | # .likTronc2NB <-function(p,n11,E,tronc){ 204 | # sum(-log( 205 | # (p[5] * dnbinom(n11, size=p[1], prob=p[2]/(p[2]+E)) 206 | # + (1-p[5]) * dnbinom(n11, size=p[3], prob=p[4]/(p[4]+E))) 207 | # / (1-(p[5] * pnbinom(tronc, size=p[1], prob=p[2]/(p[2]+E)) 208 | # + (1-p[5]) * pnbinom(tronc, size=p[3], prob=p[4]/(p[4]+E)))) 209 | # )) 210 | # } 211 | 212 | .likTronc2NB <- function(p, n11, E, tronc){ 213 | nb1 <- dnbinom(n11, size = p[1], prob = p[2] / (p[2] + E)) / 214 | (1 - pnbinom(tronc, size = p[1], prob = p[2] / (p[2] + E))) 215 | 216 | nb2 <- dnbinom(n11, size = p[3], prob = p[4] / (p[4] + E)) / 217 | (1 - pnbinom(tronc, size = p[3], prob = p[4] / (p[4] + E))) 218 | L <- (p[5] * nb1) + ((1 - p[5]) * nb2) 219 | sum(-log(L)) 220 | } 221 | 222 | .lik2NB <- function(p,n11,E){ 223 | sum(-log((p[5] * dnbinom(n11, size=p[1], prob=p[2]/(p[2]+E)) + (1-p[5]) * dnbinom(n11, size=p[3], prob=p[4]/(p[4]+E))))) 224 | } 225 | -------------------------------------------------------------------------------- /R/PRR.R: -------------------------------------------------------------------------------- 1 | `PRR` <- 2 | function(DATABASE, RR0 = 1, MIN.n11 = 1, DECISION = 1, DECISION.THRES = 0.05, RANKSTAT = 1) { 3 | 4 | # DATABASE : object. It is the object returned by the function transform_data. It contains : 5 | # DATABASE$PARAM : the parameters used when calling the function transform_data 6 | # DATABASE$data : matrix. The first column of DATA must contain the number of notifications n11, the second 7 | # column the row marges n10 and the third column the column marges n01 8 | # DATABASE$N : Nb de notifications total 9 | # DATABASE$L : LIBELLES 10 | 11 | # RR0 : positive double. The value of the risk you want to consider. By default, RR0=1 12 | 13 | # MIN.n11 : You can choose a minimum number of notifications contraint for a couple may be considered as a possible 14 | # signal. By default, MIN.n11 = 1. (ex: if MIN.n11=5, only couples with at least 5 notifications will 15 | # be able to be declared as an alert) 16 | 17 | # DECISION : You can choose which rule to use to determine the list of signals 18 | # 1 = FDR (ex : 0.05) : This decision is only available when the P-values are chosen as ranking stat SEE RANKSTAT 19 | # 2 = Number of Signals (ex : 1000) 20 | # 3 = Ranking statistic See RankStat 21 | 22 | # DECISION.THRES : The value of the FDR / Number of signals, Ranking statistic, considering the DECISION rule you choose 23 | 24 | # RankStat: You can choose which statistic to use to order the signals : 25 | # (expert) 1 = pVALUE 26 | # 2 = CI Lower Bound (95%) of ln(PRR) 27 | 28 | 29 | if (RANKSTAT==2 & DECISION == 1) stop("The FDR can't be used as decision rule with this ranking Statistic") 30 | # Initialization 31 | DATA <- DATABASE$data 32 | N <- DATABASE$N 33 | L <- DATABASE$L 34 | 35 | n11 <- DATA[,1] 36 | n1. <- DATA[,2] # marginal drug counts 37 | n.1 <- DATA[,3] # marginal AE counts 38 | n10 <- n1. - n11 39 | n01 <- n.1 - n11 40 | n00 <- N - (n11+n10+n01) 41 | E <- n1. * n.1 / N 42 | 43 | if(MIN.n11 > 1) { 44 | E <- E[n11 >= MIN.n11] 45 | n1. <- n1.[n11 >= MIN.n11] 46 | n.1 <- n.1[n11 >= MIN.n11] 47 | n10 <- n10[n11 >= MIN.n11] 48 | n01 <- n01[n11 >= MIN.n11] 49 | n00 <- n00[n11 >= MIN.n11] 50 | LL <- data.frame(drugs=L[,1],events=L[,2],n11) 51 | LL1 <- LL[,1][n11 >= MIN.n11] 52 | LL2 <- LL[,2][n11 >= MIN.n11] 53 | rm(list="L") 54 | L <- data.frame(LL1,LL2) 55 | n11 <- n11[n11 >= MIN.n11] 56 | } 57 | 58 | Nb.Cell <- length(n11) 59 | 60 | #logPRR <- log( (n11 / (n11 + n01)) / (n10 / (n10 + n00)) ) 61 | #var.logPRR <- 1/n11 - 1/(n11 + n01) + 1/n10 - 1/(n10 + n00) 62 | logPRR <- log( (n11 / (n11 + n10)) / (n01 / (n01 + n00)) ) 63 | var.logPRR <- 1/n11 - 1/(n11 + n10) + 1/n01 - 1/(n01 + n00) 64 | pval.logPRR.uni<- 1-pnorm(logPRR,log(RR0),sqrt(var.logPRR)) 65 | petit_rankstat <- (logPRR-log(RR0))/sqrt(var.logPRR) 66 | pval.uni <- pval.logPRR.uni 67 | 68 | pval.uni[pval.uni>1] <-1 69 | pval.uni[pval.uni<0] <-0 70 | 71 | PVAL.UNI <- pval.uni 72 | LBE.res <- LBE(2 * apply(cbind(pval.uni, 1-pval.uni),1,min),plot.type="none") 73 | pi.c <- LBE.res$pi0 74 | fdr <- pi.c * sort(pval.uni[pval.uni <= .5]) / (c(1:sum(pval.uni <= .5)) / Nb.Cell) 75 | fdr <- c(fdr, 76 | pi.c /(2 *((sum(pval.uni <= .5)+1) : Nb.Cell)/ Nb.Cell) 77 | + 1 78 | - sum(pval.uni <= .5)/((sum(pval.uni <= .5)+1):Nb.Cell) 79 | ) 80 | FDR <- apply(cbind(fdr,1),1,min) 81 | 82 | if (RANKSTAT==2){FDR <- rep(NaN,length(n11))} 83 | 84 | # Calculation of the Lower Bound 85 | LB <- qnorm(0.025,logPRR,sqrt(var.logPRR)) 86 | 87 | 88 | if (RANKSTAT==1) RankStat <- PVAL.UNI 89 | if (RANKSTAT==2) RankStat <- LB 90 | 91 | # Calculation of the number of signals according to the decision rule (pval/FDR/Nb of Signals) 92 | if (DECISION == 1 & RANKSTAT==1) Nb.signaux <- sum(FDR <= DECISION.THRES) 93 | if (DECISION == 2) Nb.signaux <- min(DECISION.THRES,Nb.Cell) 94 | if (DECISION == 3) { 95 | if (RANKSTAT==1) Nb.signaux <- sum(RankStat <= DECISION.THRES, na.rm = TRUE) 96 | if (RANKSTAT==2) Nb.signaux <- sum(RankStat >= DECISION.THRES, na.rm = TRUE) 97 | } 98 | 99 | 100 | ############################ SORTIE DE LA FONCTION ############################# 101 | RES <- vector(mode="list") 102 | 103 | #RES$LIBEL <- L 104 | #colnames(RES$LIBEL) <- c("DRUG","EVENT") 105 | 106 | RES$INPUT.PARAM <- data.frame(RR0, MIN.n11, DECISION, DECISION.THRES, RANKSTAT) 107 | #colnames(RES$INPUT.PARAM) <- c("RR0","notification threshold") 108 | 109 | # Presentation of the statistics calculated for each couple 110 | ##RES$STATISTIC <- data.frame(n11,PVAL.UNI,LB) 111 | ##rownames(RES$STATISTIC) <- paste(L[,1],L[,2]) # liste des libellés ingénue 112 | ##colnames(RES$STATISTIC) <- c("Effectif","pvalue","Lower Bound") 113 | 114 | # STATISTICAL VALUE TO BE CONSIDERED (used in function compare) 115 | #RES$COMPARE <- vector(mode="list") 116 | #RES$COMPARE$RANKSTAT <- RANKSTAT 117 | #RES$COMPARE$STAT <- RankStat 118 | 119 | # SIGNALS RESULTS and presentation 120 | #if (RANKSTAT==1) { 121 | RES$ALLSIGNALS <- data.frame( L[,1][order(petit_rankstat, decreasing=TRUE)], 122 | L[,2][order(petit_rankstat, decreasing=TRUE)], 123 | n11[order(petit_rankstat, decreasing=TRUE)], 124 | E[order(petit_rankstat, decreasing=TRUE)], 125 | RankStat[order(petit_rankstat, decreasing=TRUE)], 126 | exp(logPRR)[order(petit_rankstat, decreasing=TRUE)], 127 | n1.[order(petit_rankstat, decreasing=TRUE)], 128 | n.1[order(petit_rankstat, decreasing=TRUE)], 129 | FDR ) 130 | colnames(RES$ALLSIGNALS) <- c("drug code","event effect","count","expected count","p-value", 131 | "PRR","drug margin","event margin","FDR") 132 | if (RANKSTAT==2){colnames(RES$ALLSIGNALS)[5] <- "LB95(log(PRR))"} 133 | #} 134 | #if (RANKSTAT==2 & DECISION != 1) { 135 | # RES$ALLSIGNALS <- data.frame( L[,1][order(RankStat, decreasing=TRUE)], 136 | # L[,2][order(RankStat, decreasing=TRUE)], 137 | # n11[order(RankStat, decreasing=TRUE)], 138 | # E[order(RankStat,decreasing=TRUE)], 139 | # RankStat[order(RankStat,decreasing=TRUE)], 140 | # exp(logPRR)[order(RankStat,decreasing=TRUE)], 141 | # n1.[order(RankStat,decreasing=TRUE)], 142 | # n.1[order(RankStat,decreasing=TRUE)],FDR) 143 | # colnames(RES$ALLSIGNALS) <- c("drug code","event effect","count","expected count","CI Lower Bound", 144 | # "ROR","drug margin","event margin") 145 | #} 146 | # List of Signals generated according to the DECISION.THRES 147 | RES$SIGNALS <- RES$ALLSIGNALS[1:Nb.signaux,] 148 | 149 | # FDR,FNR,Se,Sp 150 | #RES$OpChar <- as.matrix(FDR) 151 | #if (RANKSTAT==2){RES$OpChar <- matrix(NaN,nr=length(n11),nc=1)} 152 | #rownames(RES$OpChar) <- paste(RES$ALLSIGNALS[,1],RES$ALLSIGNALS[,2]) 153 | #colnames(RES$OpChar) <- "FDR" 154 | 155 | # Number of signals 156 | RES$NB.SIGNALS <- Nb.signaux 157 | 158 | RES 159 | } 160 | 161 | -------------------------------------------------------------------------------- /R/PhViD.search.R: -------------------------------------------------------------------------------- 1 | `PhViD.search` <- 2 | function(RESULT,DRUG=NULL,EVENT=NULL) { 3 | # fonction permettant de rechercher les résultats pour un médicament, un effet indésirable ou les deux 4 | 5 | 6 | RESULT$ALLSIGNALS[,1]<-as.character(RESULT$ALLSIGNALS[,1]) 7 | RESULT$ALLSIGNALS[,2]<-as.character(RESULT$ALLSIGNALS[,2]) 8 | #if (RESULT$COMPARE$RANKSTAT == 2 | RESULT$COMPARE$RANKSTAT == 3) 9 | # rang <- rank(-RESULT$ALLSIGNALS[,5]) 10 | #else rang <- rank(RESULT$ALLSIGNALS[,5]) 11 | 12 | if (RESULT$INPUT.PARAM$RANKSTAT == 2 | RESULT$INPUT.PARAM$RANKSTAT == 3) 13 | rang <- rank(-RESULT$ALLSIGNALS[,5]) 14 | else rang <- rank(RESULT$ALLSIGNALS[,5]) 15 | 16 | EXIST_DRUG <- TRUE 17 | EXIST_EVENT <- TRUE 18 | if (is.null(DRUG)==FALSE) EXIST_DRUG <- length(RESULT$ALLSIGNALS[,1][RESULT$ALLSIGNALS[,1]==DRUG])!=0 19 | if (is.null(EVENT)==FALSE) EXIST_EVENT <- length(RESULT$ALLSIGNALS[,2][RESULT$ALLSIGNALS[,2]==EVENT])!=0 20 | 21 | #if (EVENT==NULL) RESULT$ALLSIGNALS[,3]<-RESULT$ALLSIGNALS[,3][RESULT$ALLSIGNALS[,1]==DRUG] 22 | #if (DRUG==NULL) RESULT$ALLSIGNALS[,3]<-RESULT$ALLSIGNALS[,3][RESULT$ALLSIGNALS[,2]==EVENT] 23 | 24 | if (is.null(EVENT)==FALSE & is.null(DRUG)==FALSE) { 25 | Lmedic <- RESULT$ALLSIGNALS[,1][RESULT$ALLSIGNALS[,1]==DRUG & RESULT$ALLSIGNALS[,2]==EVENT] 26 | Leffect <- RESULT$ALLSIGNALS[,2][RESULT$ALLSIGNALS[,1]==DRUG & RESULT$ALLSIGNALS[,2]==EVENT] 27 | effectif <- RESULT$ALLSIGNALS[,3][RESULT$ALLSIGNALS[,1]==DRUG & RESULT$ALLSIGNALS[,2]==EVENT] 28 | expect_E <- RESULT$ALLSIGNALS[,4][RESULT$ALLSIGNALS[,1]==DRUG & RESULT$ALLSIGNALS[,2]==EVENT] 29 | stat <- RESULT$ALLSIGNALS[,5][RESULT$ALLSIGNALS[,1]==DRUG & RESULT$ALLSIGNALS[,2]==EVENT] 30 | r <- rang[RESULT$ALLSIGNALS[,1]==DRUG & RESULT$ALLSIGNALS[,2]==EVENT] 31 | #fdr <- RESULT$OpChar[,1][RESULT$ALLSIGNALS[,1]==DRUG & RESULT$ALLSIGNALS[,2]==EVENT] 32 | fdr <- RESULT$ALLSIGNALS[,9][RESULT$ALLSIGNALS[,1]==DRUG & RESULT$ALLSIGNALS[,2]==EVENT] 33 | } 34 | 35 | if (is.null(EVENT) & is.null(DRUG)==FALSE) { 36 | Lmedic <- RESULT$ALLSIGNALS[,1][RESULT$ALLSIGNALS[,1]==DRUG] 37 | Leffect <- RESULT$ALLSIGNALS[,2][RESULT$ALLSIGNALS[,1]==DRUG] 38 | effectif <- RESULT$ALLSIGNALS[,3][RESULT$ALLSIGNALS[,1]==DRUG] 39 | expect_E <- RESULT$ALLSIGNALS[,4][RESULT$ALLSIGNALS[,1]==DRUG] 40 | stat <- RESULT$ALLSIGNALS[,5][RESULT$ALLSIGNALS[,1]==DRUG] 41 | r <- rang[RESULT$ALLSIGNALS[,1]==DRUG] 42 | #fdr <- RESULT$OpChar[,1][RESULT$ALLSIGNALS[,1]==DRUG] 43 | fdr <- RESULT$ALLSIGNALS[,9][RESULT$ALLSIGNALS[,1]==DRUG] 44 | } 45 | 46 | if (is.null(EVENT)==FALSE & is.null(DRUG)) { 47 | Lmedic <- RESULT$ALLSIGNALS[,1][RESULT$ALLSIGNALS[,2]==EVENT] 48 | Leffect <- RESULT$ALLSIGNALS[,2][RESULT$ALLSIGNALS[,2]==EVENT] 49 | effectif <- RESULT$ALLSIGNALS[,3][RESULT$ALLSIGNALS[,2]==EVENT] 50 | expect_E <- RESULT$ALLSIGNALS[,4][RESULT$ALLSIGNALS[,2]==EVENT] 51 | stat <- RESULT$ALLSIGNALS[,5][RESULT$ALLSIGNALS[,2]==EVENT] 52 | r <- rang[RESULT$ALLSIGNALS[,2]==EVENT] 53 | #fdr <- RESULT$OpChar[,1][RESULT$ALLSIGNALS[,2]==EVENT] 54 | fdr <- RESULT$ALLSIGNALS[,9][RESULT$ALLSIGNALS[,2]==EVENT] 55 | } 56 | 57 | 58 | RES <- vector(mode="list") 59 | RES$DRUG <- DRUG 60 | RES$EVENT <- EVENT 61 | RES$EXIST_EVENT <- EXIST_EVENT 62 | RES$EXIST_DRUG <- EXIST_DRUG 63 | RES$EXIST_COUPLE <- length(Lmedic)!=0 64 | RES$LIST <- data.frame(Lmedic,Leffect,effectif,expect_E,stat,r,fdr) 65 | colnames(RES$LIST) <- c("drug name","event","count","expected count","stat","rank","fdr") 66 | RES 67 | } 68 | 69 | -------------------------------------------------------------------------------- /R/RFET.R: -------------------------------------------------------------------------------- 1 | `RFET` <- 2 | function(DATABASE, OR0 = 1, MIN.n11 = 1, DECISION = 1, DECISION.THRES=0.05, MID.PVAL = FALSE) { 3 | 4 | # DATABASE : object. It is the object returned by the function transform_data. It contains : 5 | # DATABASE$PARAM : the parameters used when calling the function transform_data 6 | # DATABASE$data : matrix. The first column of DATA must contain the number of notifications n11, the second 7 | # column the row marges n10 and the third column the column marges n01 8 | # DATABASE$N : Nb de notifications total 9 | # DATABASE$L : LIBELLES 10 | 11 | # OR0 : positive double. The value of the risk you want to consider. By default, OR0=1 12 | 13 | # MIN.n11 : You can choose a minimum number of notifications contraint for a couple may be considered as a possible 14 | # signal. By default, MIN.n11 = 1. (ex: if MIN.n11=5, only couples with at least 5 notifications will 15 | # be able to be declared as an alert) 16 | 17 | # DECISION : You can choose which rule to use to determine the list of signals 18 | # 1 = FDR (ex : 0.05) 19 | # 2 = Number of Signals (ex : 1000) 20 | # 3 = pVALUE 21 | 22 | # DECISION.THRES : The value of the FDR / Number of signals, Ranking statistic, considering the DECISION rule you choose 23 | 24 | # MID.PVAL : Default = False 25 | 26 | #OR0 <-c(1,2,5) ## seuil pour la definition des associations 27 | 28 | 29 | 30 | 31 | # Initialization 32 | DATA <- DATABASE$data 33 | N <- DATABASE$N 34 | L <- DATABASE$L 35 | 36 | n11 <- DATA[,1] 37 | n1. <- DATA[,2] # les marges lignes (effets indésirables) 38 | n.1 <- DATA[,3] # les marges colonnes (médicaments) 39 | n10 <- n1. - n11 40 | n01 <- n.1 - n11 41 | n00 <- N - (n11+n10+n01) 42 | E <- n1. * n.1 / N # les effectifs attendus 43 | 44 | if(MIN.n11 > 1) { 45 | E <- E[n11 >= MIN.n11] 46 | n1. <- n1.[n11 >= MIN.n11] 47 | n.1 <- n.1[n11 >= MIN.n11] 48 | n10 <- n10[n11 >= MIN.n11] 49 | n01 <- n01[n11 >= MIN.n11] 50 | n00 <- n00[n11 >= MIN.n11] 51 | LL <- data.frame(drugs=L[,1],events=L[,2],n11) 52 | LL1 <- LL[,1][n11 >= MIN.n11] 53 | LL2 <- LL[,2][n11 >= MIN.n11] 54 | rm(list="L") 55 | L <- data.frame(LL1,LL2) 56 | n11 <- n11[n11 >= MIN.n11] 57 | } 58 | 59 | Nb.Cell <- length(n11) 60 | 61 | logRFET <- log(n11 * n00 /(n10 * n01)) 62 | 63 | 64 | pval.fish.uni <- vector(length=Nb.Cell) 65 | for (p in 1 : Nb.Cell) { 66 | pval.fish.uni[p] <- fisher.test(matrix(c(n11[p],n10[p],n01[p],n00[p]),ncol=2,byrow=TRUE),or=OR0,alternative="g")$p.value 67 | } 68 | 69 | if (MID.PVAL == TRUE) { # option MID.PVAL 70 | for (p in 1 : Nb.Cell) { 71 | pval.fish.uni[p] <- pval.fish.uni[p] - 0.5 * dnoncenhypergeom(x = n11[p], n1 = n11[p] + n01[p] , n2 = n10[p] + n00[p], m1 = n11[p] + n10[p], psi = OR0) 72 | } 73 | } 74 | 75 | pval.uni <- pval.fish.uni 76 | pval.uni[pval.uni>1] <-1 77 | pval.uni[pval.uni<0] <-0 78 | 79 | RankStat <- pval.uni 80 | LBE.res <- LBE(2 * apply(cbind(RankStat, 1-RankStat),1,min),plot.type="none") 81 | pi.c <- LBE.res$pi0 82 | 83 | fdr <- pi.c * sort(RankStat[RankStat <= .5]) / (c(1:sum(RankStat <= .5)) / Nb.Cell) 84 | fdr <- c(fdr, 85 | pi.c /(2 *((sum(RankStat <= .5)+1) : Nb.Cell)/ Nb.Cell) 86 | + 1 87 | - sum(RankStat <= .5)/((sum(RankStat <= .5)+1):Nb.Cell) 88 | ) 89 | FDR <- apply(cbind(fdr,1),1,min) 90 | 91 | # Calculation of the number of signals according to the decision rule (pp/FDR/Nb of Signals) 92 | if (DECISION == 1) Nb.signaux <- sum(FDR <= DECISION.THRES) 93 | if (DECISION == 2) Nb.signaux <- min(DECISION.THRES,Nb.Cell) 94 | if (DECISION == 3) Nb.signaux <- sum(RankStat <= DECISION.THRES) 95 | 96 | 97 | ############################ SORTIE DE LA FONCTION ############################# 98 | RES <- vector(mode="list") 99 | 100 | #RES$LIBEL <- L 101 | #colnames(RES$LIBEL) <- c("DRUG","EVENT") 102 | 103 | RES$INPUT.PARAM <- data.frame(OR0, MIN.n11, DECISION, DECISION.THRES, MID.PVAL,RANKSTAT=1) 104 | #colnames(RES$INPUT.PARAM) <- c("OR0","notification threshold") 105 | 106 | # Presentation of the statistics calculated for each couple 107 | ##RES$STATISTIC <- data.frame(n11,RankStat) 108 | ##rownames(RES$STATISTIC) <- paste(L[,1],L[,2]) # liste des libellés ingénue 109 | ##colnames(RES$STATISTIC) <- c("Effectif","pvalue") 110 | 111 | # STATISTICAL VALUE TO BE CONSIDERED (used in function compare) 112 | #RES$COMPARE <- vector(mode="list") 113 | #RES$COMPARE$RANKSTAT <- 1 114 | #RES$COMPARE$STAT <- RankStat 115 | 116 | # SIGNALS RESULTS and presentation 117 | RES$ALLSIGNALS <- data.frame( L[,1][order(RankStat)], 118 | L[,2][order(RankStat)], 119 | n11[order(RankStat)], 120 | E[order(RankStat)], 121 | RankStat[order(RankStat)], 122 | exp(logRFET)[order(RankStat)], 123 | n1.[order(RankStat)], 124 | n.1[order(RankStat)], 125 | FDR ) 126 | colnames(RES$ALLSIGNALS) <- c("drug code","event effect","count","expected count","p-value", 127 | "ROR","drug margin","event margin","FDR") 128 | 129 | # List of Signals generated according to the DECISION.THRES 130 | RES$SIGNALS <- RES$ALLSIGNALS[1:Nb.signaux,] 131 | 132 | # FDR,FNR,Se,Sp 133 | #RES$OpChar <- as.matrix(FDR) 134 | #rownames(RES$OpChar) <- paste(RES$ALLSIGNALS[,1],RES$ALLSIGNALS[,2]) 135 | #colnames(RES$OpChar) <- "FDR" 136 | 137 | # Number of signals 138 | RES$NB.SIGNALS <- Nb.signaux 139 | 140 | RES 141 | } 142 | 143 | -------------------------------------------------------------------------------- /R/ROR.R: -------------------------------------------------------------------------------- 1 | `ROR` <- 2 | function(DATABASE, OR0 = 1, MIN.n11 = 1, DECISION = 1, DECISION.THRES = 0.05, RANKSTAT = 1) { 3 | 4 | # DATABASE : object. It is the object returned by the function transform_data. It contains : 5 | # DATABASE$PARAM : the parameters used when calling the function transform_data 6 | # DATABASE$data : matrix. The first column of DATA must contain the number of notifications n11, the second 7 | # column the row marges n10 and the third column the column marges n01 8 | # DATABASE$N : Nb de notifications total 9 | # DATABASE$L : LIBELLES 10 | 11 | # OR0 : positive double. The value of the risk you want to consider. By default, OR0=1 12 | 13 | # MIN.n11 : You can choose a minimum number of notifications contraint for a couple may be considered as a possible 14 | # signal. By default, MIN.n11 = 1. (ex: if MIN.n11=5, only couples with at least 5 notifications will 15 | # be able to be declared as an alert) 16 | 17 | # DECISION : You can choose which rule to use to determine the list of signals 18 | # 1 = FDR (ex : 0.05) : This decision is only available when the P-values are chosen as ranking stat SEE RANKSTAT 19 | # 2 = Number of Signals (ex : 1000) 20 | # 3 = Ranking statistic See RankStat 21 | 22 | # DECISION.THRES : The value of the FDR / Number of signals, Ranking statistic, considering the DECISION rule you choose 23 | 24 | # RANKSTAT : You can choose which statistic to use to order the signals : 25 | # 1 = pVALUE 26 | # 2 = CI Lower Bound (95%) of ln(PRR) 27 | 28 | 29 | if (RANKSTAT==2 & DECISION == 1) stop("The FDR can't be used as decision rule with this ranking statistic") 30 | 31 | # Initialization 32 | DATA <- DATABASE$data 33 | N <- DATABASE$N 34 | L <- DATABASE$L 35 | 36 | n11 <- DATA[,1] 37 | n1. <- DATA[,2] 38 | n.1 <- DATA[,3] 39 | n10 <- n1. - n11 40 | n01 <- n.1 - n11 41 | n00 <- N - (n11+n10+n01) 42 | E <- n1. * n.1 / N # les effectifs attendus 43 | 44 | if(MIN.n11 > 1) { 45 | E <- E[n11 >= MIN.n11] 46 | n1. <- n1.[n11 >= MIN.n11] 47 | n.1 <- n.1[n11 >= MIN.n11] 48 | n10 <- n10[n11 >= MIN.n11] 49 | n01 <- n01[n11 >= MIN.n11] 50 | n00 <- n00[n11 >= MIN.n11] 51 | LL <- data.frame(drugs=L[,1],events=L[,2],n11) 52 | LL1 <- LL[,1][n11 >= MIN.n11] 53 | LL2 <- LL[,2][n11 >= MIN.n11] 54 | rm(list="L") 55 | L <- data.frame(LL1,LL2) 56 | n11 <- n11[n11 >= MIN.n11] 57 | } 58 | 59 | Nb.Cell <- length(n11) 60 | 61 | logROR <- log(n11 * n00 /(n10 * n01)) 62 | var.logROR <- 1/n11 + 1/n10 + 1/n01 + 1/n00 63 | pval.logOR.uni <- 1-pnorm(logROR,log(OR0),sqrt(var.logROR)) 64 | petit_rankstat <- (logROR-log(OR0))/sqrt(var.logROR) # on va trier les signaux par rapport aux valeurs centrées réduites 65 | pval.uni <- pval.logOR.uni 66 | 67 | pval.uni[pval.uni>1] <-1 68 | pval.uni[pval.uni<0] <-0 69 | 70 | PVAL.UNI <- pval.uni 71 | LBE.res <- LBE(2 * apply(cbind(pval.uni, 1-pval.uni),1,min),plot.type="none") 72 | pi.c <- LBE.res$pi0 73 | fdr <- pi.c * sort(pval.uni[pval.uni <= .5]) / (c(1:sum(pval.uni <= .5)) / Nb.Cell) 74 | fdr <- c(fdr, 75 | pi.c /(2 *((sum(pval.uni <= .5)+1) : Nb.Cell)/ Nb.Cell) 76 | + 1 77 | - sum(pval.uni <= .5)/((sum(pval.uni <= .5)+1):Nb.Cell) 78 | ) 79 | FDR <- apply(cbind(fdr,1),1,min) 80 | 81 | if (RANKSTAT==2){FDR <- rep(NaN,length(n11))} 82 | 83 | # Calculation of the Lower Bound 84 | LB <- qnorm(0.025,logROR,sqrt(var.logROR)) 85 | 86 | 87 | if (RANKSTAT==1) RankStat <- PVAL.UNI 88 | if (RANKSTAT==2) RankStat <- LB 89 | 90 | # Calculation of the number of signals according to the decision rule (pval/FDR/Nb of Signals) 91 | if (DECISION == 1 & RANKSTAT==1) Nb.signaux <- sum(FDR <= DECISION.THRES) 92 | if (DECISION == 2) Nb.signaux <- min(DECISION.THRES,Nb.Cell) 93 | if (DECISION == 3) { 94 | if (RANKSTAT==1) Nb.signaux <- sum(RankStat <= DECISION.THRES, na.rm = TRUE) 95 | if (RANKSTAT==2) Nb.signaux <- sum(RankStat >= DECISION.THRES, na.rm = TRUE) 96 | } 97 | 98 | 99 | ############################ SORTIE DE LA FONCTION ############################# 100 | RES <- vector(mode="list") 101 | 102 | #RES$LIBEL <- L 103 | #colnames(RES$LIBEL) <- c("DRUG","EVENT") 104 | 105 | RES$INPUT.PARAM <- data.frame(OR0, MIN.n11, DECISION, DECISION.THRES, RANKSTAT) 106 | #colnames(RES$INPUT.PARAM) <- c("OR0","notification threshold") 107 | 108 | # Presentation of the statistics calculated for each couple 109 | ##RES$STATISTIC <- data.frame(n11,PVAL.UNI,LB) 110 | ##rownames(RES$STATISTIC) <- paste(L[,1],L[,2]) # liste des libellés ingénue 111 | ##colnames(RES$STATISTIC) <- c("Effectif","pvalue","Lower Bound") 112 | 113 | # STATISTICAL VALUE TO BE CONSIDERED (used in function compare) 114 | #RES$COMPARE <- vector(mode="list") 115 | #RES$COMPARE$RANKSTAT <- RANKSTAT 116 | #RES$COMPARE$STAT <- RankStat 117 | 118 | # SIGNALS RESULTS and presentation 119 | #if (RANKSTAT==1) { 120 | RES$ALLSIGNALS <- data.frame( L[,1][order(petit_rankstat, decreasing=TRUE)], 121 | L[,2][order(petit_rankstat, decreasing=TRUE)], 122 | n11[order(petit_rankstat, decreasing=TRUE)], 123 | E[order(petit_rankstat, decreasing=TRUE)], 124 | RankStat[order(petit_rankstat, decreasing=TRUE)], 125 | exp(logROR)[order(petit_rankstat, decreasing=TRUE)], 126 | n1.[order(petit_rankstat, decreasing=TRUE)], 127 | n.1[order(petit_rankstat, decreasing=TRUE)], 128 | FDR ) 129 | colnames(RES$ALLSIGNALS) <- c("drug code","event effect","count","expected count","p-value", 130 | "ROR","drug margin","event margin","FDR") 131 | if (RANKSTAT==2){colnames(RES$ALLSIGNALS)[5] <- "LB95(log(ROR))"} 132 | #} 133 | #if (RANKSTAT==2 & DECISION != 1) { 134 | # RES$ALLSIGNALS <- data.frame( L[,1][order(RankStat, decreasing=TRUE)], 135 | # L[,2][order(RankStat, decreasing=TRUE)], 136 | # n11[order(RankStat,decreasing=TRUE)], 137 | # E[order(RankStat,decreasing=TRUE)], 138 | # RankStat[order(RankStat,decreasing=TRUE)], 139 | # exp(logROR)[order(RankStat,decreasing=TRUE)], 140 | # n1.[order(RankStat,decreasing=TRUE)], 141 | # n.1[order(RankStat,decreasing=TRUE)],FDR ) 142 | # colnames(RES$ALLSIGNALS) <- c("drug code","event effect","count","expected count","LB95(log(ROR))", 143 | # "ROR","drug margin","event margin") 144 | #} 145 | # List of Signals generated according to the DECISION.THRES 146 | RES$SIGNALS <- RES$ALLSIGNALS[1:Nb.signaux,] 147 | 148 | # FDR,FNR,Se,Sp 149 | #RES$OpChar <- as.matrix(FDR) 150 | #if (RANKSTAT==2){RES$OpChar <- matrix(NaN,nr=length(n11),nc=1)} 151 | #rownames(RES$OpChar) <- paste(RES$ALLSIGNALS[,1],RES$ALLSIGNALS[,2]) 152 | #colnames(RES$OpChar) <- "FDR" 153 | 154 | # Number of signals 155 | RES$NB.SIGNALS <- Nb.signaux 156 | RES 157 | } 158 | 159 | -------------------------------------------------------------------------------- /R/as.PhViD.R: -------------------------------------------------------------------------------- 1 | `as.PhViD` <- 2 | function(DATA.FRAME,MARGIN.THRES=1){ 3 | ## Fonction qui va permettre de calculer le nombre de notifications pour chaque "médicament" et "effet indésirable". 4 | 5 | ## FILE : Emplacement + nom du fichier 6 | ## Les données doivent contenir 3 colonnes 7 | ## - le label ATC 8 | ## - le label meddra 9 | ## - le nombre de notifications 10 | 11 | ## MARGIN.THRES : Seuil sur les marges. on peut considérer uniquement les lignes et colonnes qui dépassent 12 | ## un certain effectif 13 | 14 | ## FILE="ATC7-pt.csv" 15 | ## FILE="ATC5-hlt.csv" 16 | ## rm(list=ls()) 17 | 18 | ############################################################################# 19 | ## 20 | ## Event 21 | ## ______________ 22 | ## Drug | n11 | n10 | <- Drug.marge (n1.) 23 | ## |_______|______| 24 | ## | n01 | n00 | 25 | ## |_______|______| 26 | ## | N (n..) 27 | ## Event.marge (n.1) 28 | ############################################################################## 29 | 30 | data <- DATA.FRAME 31 | data[,1] <- as.factor(DATA.FRAME[,1]) 32 | data[,2] <- as.factor(DATA.FRAME[,2]) 33 | data[,3] <- as.double(DATA.FRAME[,3]) 34 | #data <- read.table(file=FILE,header=TRUE,sep=";",colClasses=c("factor","factor","double")) 35 | 36 | coln <- names(data) # On stocke le nom des colonnes 37 | names(data)[3] <-"n11" 38 | data_cont <- xtabs(n11 ~ .,data=data) # "matrice" de contingence 39 | n1._mat <- apply(data_cont,1,sum) # marges des lignes 40 | n.1_mat <- apply(data_cont,2,sum) # marges des colonnes 41 | 42 | 43 | ## Nettoyage en fonction du seuil sur les marges 44 | if (MARGIN.THRES > 1){ 45 | while(sum(n1._mat0 | sum(n.1_mat0){ 46 | data_cont <- data_cont[n1._mat >= MARGIN.THRES,] # on supprime les lignes dont la marge n'est pas supérieure au seuil 47 | data_cont <- data_cont[,n.1_mat >= MARGIN.THRES] # on supprime les colonnes dont la marge n'est pas supérieure au seuil 48 | n1._mat <- apply(data_cont,1,sum) # on recalcule les marges des lignes... 49 | n.1_mat <- apply(data_cont,2,sum) # ...et des colonnes 50 | } 51 | } 52 | ##--------------------------------------- 53 | coord <- which(data_cont != 0, arr.ind=TRUE) # on récupère les coordonnées des notifications (traduit par un nombre >=1 dans la matrice data_cont) 54 | coord <- coord[order(coord[,1]),] # la fonction which les a ordonnées par colonnes. On les veut ordonnées par lignes 55 | 56 | #data_net <- cbind(rownames(data_cont)[coord[,1]],colnames(data_cont)[coord[,2]],data_cont[coord]) # on compile les 57 | #libellés des médicaments, des effets indésirables et des notifications après le nettoyage sur les marges. (si pas de 58 | #nettoyage, cela revient à prendre data) 59 | 60 | # on récupère les nouvelles dimensions de la matrice 61 | Nb_n1. <- length(n1._mat) # nombre de lignes 62 | Nb_n.1 <- length(n.1_mat) # nombre de colonnes 63 | 64 | libel.medoc <- rownames(data_cont)[coord[,1]] # on conserve les libellés des médicaments qui restent 65 | libel.effet <- colnames(data_cont)[coord[,2]] # on conserve les libellés des effets indésirables qui restent 66 | n11 <- data_cont[coord] 67 | N <- sum(n11) # le nombre total de notifications 68 | n1. <- n1._mat[coord[,1]] # on affecte à chaque notification sa marge "ligne"... 69 | n.1 <- n.1_mat[coord[,2]] # ... et sa marge "colonne" 70 | 71 | 72 | RES <- vector(mode="list") 73 | #RES$PARAM <- data.frame(FILE,MARGIN.THRES) # input parameters # FILE, not necessary 74 | RES$L <- data.frame(libel.medoc,libel.effet) 75 | colnames(RES$L) <- coln[1:2] 76 | RES$data <- cbind(n11,n1.,n.1) # matrice "équivalente" à la matrice de départ avec en plus les marges et effectifs attendus 77 | rownames(RES$data) <- paste(libel.medoc,libel.effet) 78 | RES$N <- N # nb de notifications total 79 | RES 80 | } 81 | 82 | -------------------------------------------------------------------------------- /data/PhViDdata.frame.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cran/PhViD/bbb450c3837c6001710a328d382a27e856e601d8/data/PhViDdata.frame.rda -------------------------------------------------------------------------------- /inst/CITATION: -------------------------------------------------------------------------------- 1 | citHeader("To cite the PhViD package:") 2 | 3 | if(!exists("meta") || is.null(meta)) meta <- packageDescription("nlme") 4 | year <- sub(".*(2[[:digit:]]{3})-.*", "\\1", meta$Date) 5 | vers <- paste("R package version", meta$Version) 6 | 7 | citEntry( 8 | entry = "Manual", 9 | title = "PhViD: an R package for PharmacoVigilance signal Detection", 10 | author = personList(as.person("I. Ahmed"), as.person("A. Poncet")), 11 | year = year, 12 | note = vers, 13 | textVersion = paste("I. Ahmed & A. Poncet (", year, 14 | "). PhViD: an R package for PharmacoVigilance signal Detection. ", 15 | vers, ".", sep="") 16 | ) 17 | 18 | -------------------------------------------------------------------------------- /man/BCPNN.Rd: -------------------------------------------------------------------------------- 1 | \encoding{UTF-8} 2 | \name{BCPNN} 3 | \alias{BCPNN} 4 | %- Also NEED an '\alias' for EACH other topic documented here. 5 | \title{Bayesian confidence propagation neural network} 6 | \description{ 7 | Bayesian confidence propagation neural network (Bate et al. 1998, Noren et al. 2006) extended to the multiple comparison framework. 8 | } 9 | \usage{ 10 | BCPNN(DATABASE, RR0 = 1, MIN.n11 = 1, DECISION = 1, DECISION.THRES = 0.05, 11 | RANKSTAT = 1, MC = FALSE, NB.MC = 10000) 12 | } 13 | %- maybe also 'usage' for other objects documented here. 14 | \arguments{ 15 | \item{DATABASE}{Object returned by the function \code{as.PhViD}.} 16 | \item{RR0}{Value of the tested risk. By default, \code{RR0=1}.} 17 | \item{MIN.n11}{Minimum number of notifications for a couple to be potentially considered as a signal. By default, \code{MIN.n11 = 1}.} 18 | \item{DECISION}{Decision rule for the signal generation based on 19 | 20 | 1 = FDR (Default value) 21 | 22 | 2 = Number of signals 23 | 24 | 3 = Ranking statistic. See \code{RANKSTAT}} 25 | \item{DECISION.THRES}{Threshold for \code{DECISION}. Ex 0.05 for FDR (\code{DECISION}=1). } 26 | \item{RANKSTAT}{Statistic used for ranking the couples: 27 | 28 | 1 = Posterior probability of the null hypothesis 29 | 30 | 2 = 2.5\% quantile of the posterior distribution of IC.} 31 | \item{MC}{If \code{MC=TRUE}, the statistic of interest (see \code{RANKSTAT}) is calculated by Monte Carlo simulations which can be very long. If \code{MC=FALSE}, IC is approximated by a normal distribution (which can be very crude for small counts).} 32 | \item{NB.MC}{If \code{MC=TRUE}, \code{NB.MC} indicates the number of Monte Carlo simulations to be done} 33 | } 34 | \details{ 35 | The BCPNN method is based on the calculation of the Information Component IC. If \code{MC = FALSE}, the bayesian model used is the beta-binomial proposed by Bate et al. (1998). The statistic of interest (see \code{RANKSTAT}) is calculated by the normal approximation made in Bate et al. (1998) with the use of the exact expectation and variance proposed by Gould (2003). If \code{MC = TRUE}, the model is based on the Dirichlet-multinomial model proposed more recently in Noren et al. (2006). In this case, the statistic of interest is calculated by Monte Carlo simulations. 36 | } 37 | \value{ 38 | \item{ALLSIGNALS}{Data.frame summarizing the results of all couples with at least \code{MIN.n11} notifications ordered by \code{RANKSTAT}. It contains notably the labels, the cell counts, the expected counts (\eqn{n1. \times n.1 / N}{n1. * n.1 / N}, see \code{\link{as.PhViD}}), \code{RANKSTAT}, the ratios(count/expected count), the marginal counts and the estimations of FDR, FNR, Se et Sp. If \code{RANKSTAT!=1}, the last column is the posterior probability of the null hypothesis.} 39 | \item{SIGNALS}{Same Data.frame as \code{ALLSIGNALS} but restricted to the list of generated signals.} 40 | \item{NB.SIGNALS}{Number of generated signals.} 41 | \item{INPUT.PARAM}{Parameters entered in the function.} 42 | } 43 | \references{ 44 | Ahmed I, Haramburu F, Fourrier-Réglat A, Thiessard F, Kreft-Jais C, Miremont-Salamé G, Bégaud B, Tubert-Bitter P. Bayesian pharmacovigilance signal detection methods revisited in a multiple comparison setting. Stat Med. 2009 Jun 15;28(13):1774-1792. 45 | 46 | Bate A, Lindquist M, Edwards IR, Olsson S, Orre R, Lansner A, De Freitas RM, A Bayesian Neural Network Method for Adverse Drug Reaction Signal Generation European Journal of Clinical Pharmacology, 1998, 54, 315-321. 47 | 48 | Gould AL, Practical Pharmacovigilance Analysis Strategies Pharmacoepidemiology and Drug Safety, 2003, 12, 559-574 49 | 50 | Noren, GN, Bate A, Orre R, Edwards IR, Extending the methods used to screen the WHO drug safety database towards analysis of complex associations and improved accuracy for rare events Statistics in Medicine, 2006, 25, 3740-3757. 51 | } 52 | \examples{ 53 | ## start 54 | data(PhViDdata.frame) 55 | PhViDdata <- as.PhViD(PhViDdata.frame) 56 | # res <- BCPNN(PhViDdata) 57 | ## end 58 | } 59 | \author{\enc{Ismaïl}{Ismail} Ahmed & Antoine Poncet} 60 | \keyword{ htest } 61 | -------------------------------------------------------------------------------- /man/GPS.Rd: -------------------------------------------------------------------------------- 1 | \encoding{UTF-8} 2 | \name{GPS} 3 | \alias{GPS} 4 | %- Also NEED an '\alias' for EACH other topic documented here. 5 | \title{Gamma Poisson Shrinkage} 6 | \description{ 7 | Gamma Poisson Shrinkage model proposed by DuMouchel (1999) extended to the multiple comparison framework. 8 | } 9 | \usage{ 10 | GPS(DATABASE, RR0 = 1, MIN.n11 = 1, DECISION = 1, DECISION.THRES = 0.05, 11 | RANKSTAT = 1, TRONC = FALSE, TRONC.THRES = 1, 12 | PRIOR.INIT = c(alpha1 = 0.2, beta1 = 0.06, alpha2 = 1.4, 13 | beta2 = 1.8, w = 0.1), PRIOR.PARAM = NULL) 14 | } 15 | %- maybe also 'usage' for other objects documented here. 16 | \arguments{ 17 | \item{DATABASE}{Object returned by the function \code{as.PhViD}.} 18 | \item{RR0}{Value of the tested risk. By default, \code{RR0=1}.} 19 | \item{MIN.n11}{Minimum number of notifications for a couple to be potentially considered as a signal. This option does not affect the calculation of the hyper parameters. By default, \code{MIN.n11 = 1}.} 20 | \item{DECISION}{Decision rule for the signal generation based on 21 | 22 | 1 = FDR (Default value) 23 | 24 | 2 = Number of signals 25 | 26 | 3 = Ranking statistic. See \code{RANKSTAT}} 27 | \item{DECISION.THRES}{Threshold for \code{DECISION}. Ex 0.05 for FDR (\code{DECISION}=1). } 28 | \item{RANKSTAT}{Statistic used for ranking the couples: 29 | 30 | 1 = Posterior probability of the null hypothesis 31 | 32 | 2 = 5\% quantile of the posterior distribution of \eqn{\lambda}{lambda} 33 | 34 | 3 = Posterior Expectation of \eqn{\log_2(\lambda)}{log(lambda,2)}} 35 | \item{TRONC}{If TRUE, only the data with at least \code{TRONC.THRES} notifications are considered in the calculation of the hyper parameters and the likelihood is a product of mixture of two negative binomial truncated by \code{TRONC.THRES-1}. By default, \code{TRONC=F}} 36 | \item{TRONC.THRES}{See \code{TRONC} } 37 | \item{PRIOR.INIT}{Vector of initialization of the prior parameters \eqn{(\alpha_1, \beta_1, \alpha_2, \beta_2, w)}{(alpha1, beta1, alpha2, beta2, w)}. By default, \code{PRIOR.INIT} \eqn{= c(\alpha_1 = 0.2, \beta_1 = 0.06, \alpha_2 = 1.4, \beta_2 = 1.8, w = 0.1)}{= c(alpha1 = 0.2, beta1 = 0.06, alpha2 = 1.4, beta2 = 1.8, w = 0.1)}, ie the prior parameters found in DuMouchel (1999).} 38 | \item{PRIOR.PARAM}{Chosen hyper parameters. By default, \code{PRIOR.PARAM} = NULL which means that the hyperparameters are calculated by maximising the marginal likelihood.} 39 | } 40 | \details{ 41 | Each observed count \eqn{n_{11}}{n11} is assumed to be drawn from a Poisson distribution with parameters 42 | \eqn{e_{11}}{e11} where \eqn{e_{11}}{e11} is the expected count under the hypothesis of independence between the adverse events and the drugs (\eqn{n1. \times n.1 / N}{n1. * n.1 / N}, see \code{\link{as.PhViD}}). \eqn{\lambda}{lambda} is a priori assumed to be distributed according to a mixture of two gamma distributions: \eqn{\lambda \sim w \: \Gamma(\alpha_1,\beta_1) + (1-w) \: \Gamma(\alpha_2,\beta_2)}{lambda ~ w Ga(alpha1,beta1) + (1-w) Ga(alpha2,beta2)}.} 43 | \value{ 44 | \item{ALLSIGNALS}{Data.frame summarizing the results of all couples with at least \code{MIN.n11} notifications ordered by \code{RANKSTAT}. It contains notably the labels, the cell counts, the expected counts, \code{RANKSTAT}, the ratios(count/expected count), the marginal counts and the estimations of FDR, FNR, Se et Sp. If \code{RANKSTAT!=1}, the last column is the posterior probability of the null hypothesis.} 45 | \item{SIGNALS}{Same Data.frame as \code{ALLSIGNALS} but restricted to the list of generated signals.} 46 | \item{NB.SIGNALS}{Number of generated signals.} 47 | \item{INPUT.PARAM}{Parameters entered in the function.} 48 | \item{PARAM}{A list that contains the prior hyper parameters (\code{PRIOR.PARAM}). Additionally if \code{PRIOR.PARAM=NULL}, it also contains the prior hyper parameters initialization (\code{PRIOR.INIT}) and the convergence code (see \code{nlm()}).} 49 | } 50 | \references{ 51 | Ahmed I, Haramburu F, Fourrier-Réglat A, Thiessard F, Kreft-Jais C, Miremont-Salamé G, Bégaud B, Tubert-Bitter P. Bayesian pharmacovigilance signal detection methods revisited in a multiple comparison setting. Stat Med. 2009 Jun 15;28(13):1774-1792. 52 | 53 | DuMouchel W, Bayesian Data Mining in Large Frequency Tables, with an Application to the FDA Spontaneous Reporting System, The American Statistician, 1999, 53, 177-190. 54 | 55 | Szarfman A, Machado S, O'Neill R, Use of Screening Algorithms and Computer Systems to Efficiently Signal Higher-Than-Expected Combinations of Drugs and Events in the US FDA's Spontaneous Reports Database Drug Safety, 2002, 25, 381-392. 56 | 57 | } 58 | \examples{ 59 | ## start 60 | #data(PhViDdata.frame) 61 | 62 | 63 | #PhViDdata <- as.PhViD(PhViDdata.frame) 64 | #res <- GPS(PhViDdata) 65 | 66 | #List of signals generated by the decision rule proposed 67 | #by Szarfman et al. (2002) 68 | #res2 <- GPS(PhViDdata, DECISION = 3, DECISION.THRES = 2, RANKSTAT = 2) 69 | ## end 70 | } 71 | \author{\enc{Ismaïl}{Ismail} Ahmed & Antoine Poncet} 72 | \keyword{ htest } 73 | 74 | -------------------------------------------------------------------------------- /man/PRR.Rd: -------------------------------------------------------------------------------- 1 | \encoding{UTF-8} 2 | \name{PRR} 3 | \alias{PRR} 4 | %- Also NEED an '\alias' for EACH other topic documented here. 5 | \title{Proportional Reporting Ratio} 6 | \description{ 7 | Proportional Reporting Ratio proposed by Evans et al. (2001) extended to the multiple comparison framework. Note that the computed variance is different from the one used in van Puijenbroek et al. (2002) 8 | } 9 | \usage{ 10 | PRR(DATABASE, RR0 = 1, MIN.n11 = 1, DECISION = 1, 11 | DECISION.THRES = 0.05, RANKSTAT = 1) 12 | } 13 | %- maybe also 'usage' for other objects documented here. 14 | \arguments{ 15 | \item{DATABASE}{Object returned by the function \code{as.PhViD}.} 16 | \item{RR0}{Value of the tested relative risk. By default, \code{RR0=1}.} 17 | \item{MIN.n11}{Minimum number of notifications for a couple to be potentially considered as a signal. By default, \code{MIN.n11 = 1}.} 18 | \item{DECISION}{Decision rule for the signal generation based on 19 | 1 = FDR (Default value) 20 | 21 | 2 = Number of signals 22 | 23 | 3 = Ranking statistic. See \code{RANKSTAT}} 24 | \item{DECISION.THRES}{Threshold for \code{DECISION}. Ex 0.05 for FDR (\code{DECISION}=1). } 25 | \item{RANKSTAT}{Statistic used for ranking the couples: 26 | 27 | 1 = P-value 28 | 29 | 2 = Lower bound of the 95\% two sided confidence interval of log(PRR).} 30 | } 31 | \details{ 32 | The FDR is estimated with the LBE procedure proposed by Dalmasso et al. (2005). Note that the FDR can only be estimated if the statistic of interest is the P-value. 33 | } 34 | \value{ 35 | \item{ALLSIGNALS}{Data.frame summarizing the results of all couples with at least \code{MIN.n11} notifications ordered by \code{RANKSTAT}. It contains notably the labels, the cell counts, the expected counts (\eqn{n1. \times n.1 / N}{n1. * n.1 / N}, see \code{\link{as.PhViD}}), \code{RANKSTAT}, the observed relative risks (PRR), the marginal counts and the estimations of FDR (when \code{RANKSTAT=1}.)} 36 | \item{SIGNALS}{Same Data.frame as \code{ALLSIGNALS} but restricted to the list of generated signals.} 37 | \item{NB.SIGNALS}{Number of generated signals.} 38 | \item{INPUT.PARAM}{Parameters entered in the function.} 39 | } 40 | \references{ 41 | Ahmed I, Dalmasso C, Haramburu F, Thiessard F, \enc{Broët}{Broet} P, Tubert-Bitter P. False discovery rate estimation for frequentist pharmacovigilance signal detection methods. Biometrics. 2010 Mar;66(1):301-309. 42 | 43 | Dalmasso C, \enc{Broët}{Broet} P, Moreau T (2005), A simple procedure for estimating the false discovery rate, Bioinformatics, Bioinformatics, 21: 660 - 668. 44 | 45 | Evans SJ, Waller PC, Davis S, Use of Proportional Reporting Ratios (PRRs) for Signal Generation from Spontaneous Adverse Drug Reaction Reports Pharmacoepidemiology and Drug Safety, 2001, 10, 483-486. 46 | 47 | van Puijenbroek EP, Bate A, Leufkens HGM, Lindquist M, Orre R and Egberts ACG, A comparison of measures of disproportionality for signal detection in spontaneous reporting systems for adverse drug reactions, Pharmacoepidemiology and Drug Safety, 2002, 11, 3-10. 48 | 49 | 50 | 51 | } 52 | \examples{ 53 | ## start 54 | data(PhViDdata.frame) 55 | PhViDdata <- as.PhViD(PhViDdata.frame) 56 | # res <- PRR(PhViDdata) 57 | ## end 58 | } 59 | \author{\enc{Ismaïl}{Ismail} Ahmed & Antoine Poncet} 60 | \keyword{ htest } 61 | -------------------------------------------------------------------------------- /man/PhViD-package.Rd: -------------------------------------------------------------------------------- 1 | \name{PhViD-package} 2 | \encoding{UTF-8} 3 | \alias{PhViD-package} 4 | \alias{PhViD} 5 | \docType{package} 6 | \title{PhViD: an R package for PharmacoVigilance signal Detection} 7 | \description{ 8 | The \code{PhViD-package} proposes the main pharmacovigilance signal detection methods extended to the multiple comparison setting. For the frequentist methods, the package requires the LBE procedure that is stored in the Bioconductor website \url{http://bioconductor.org/}. LBE can be installed by entering \cr 9 | \code{source("http://bioconductor.org/biocLite.R")} \cr 10 | \code{biocLite("LBE")} \cr 11 | in the R console. 12 | } 13 | 14 | \author{ 15 | \enc{Ismaïl}{Ismail} Ahmed & Antoine Poncet 16 | 17 | Maintainer: \enc{Ismaïl}{Ismail} Ahmed 18 | } 19 | \references{ 20 | Ahmed I, Thiessard F, Miremont-Salamé G, Bégaud B, Tubert-Bitter P. Pharmacovigilance data mining with methods based on false discovery rates: a comparative simulation study. Clin. Pharmacol. Ther. 2010 Oct;88(4):492-498. 21 | 22 | Ahmed I, Dalmasso C, Haramburu F, Thiessard F, \enc{Broët}{Broet} P, Tubert-Bitter P. False discovery rate estimation for frequentist pharmacovigilance signal detection methods. Biometrics. 2010 Mar;66(1):301-309. 23 | 24 | Ahmed I, Haramburu F, Fourrier-Réglat A, Thiessard F, Kreft-Jais C, Miremont-Salamé G, Bégaud B, Tubert-Bitter P. Bayesian pharmacovigilance signal detection methods revisited in a multiple comparison setting. Stat Med. 2009 Jun 15;28(13):1774-1792. 25 | 26 | Bate A, Lindquist M, Edwards IR, Olsson S, Orre R, Lansner A, De Freitas RM. A Bayesian Neural Network Method for Adverse Drug Reaction Signal Generation European Journal of Clinical Pharmacology, 1998, 54, 315-321. 27 | 28 | Dalmasso C, Broet P, Moreau T (2005), A simple procedure for estimating the false discovery rate, Bioinformatics, Bioinformatics, 21: 660 - 668. 29 | 30 | DuMouchel W. Bayesian Data Mining in Large Frequency Tables, with an Application to the FDA Spontaneous Reporting System. The American Statistician. 1999, 53. 177-190. 31 | 32 | Evans SJ, Waller PC, Davis S, Use of Proportional Reporting Ratios (PRRs) for Signal Generation from Spontaneous Adverse Drug Reaction Reports Pharmacoepidemiology and Drug Safety, 2001, 10, 483-486. 33 | 34 | Noren, GN, Bate A, Orre R, Edwards IR, Extending the methods used to screen the WHO drug safety database towards analysis of complex associations and improved accuracy for rare events Statistics in Medicine, 2006, 25, 3740-3757. 35 | 36 | van Puijenbroek EP, Bate A, Leufkens HG, Lindquist M, Orre R, Egberts AC, A Comparison of Measures of Disproportionality for Signal Detection in Spontaneous Reporting Systems for Adverse Drug Reactions Pharmacoepidemiology and Drug Safety, 2002, 11, 3-1. 37 | 38 | } 39 | \keyword{ htest } 40 | 41 | -------------------------------------------------------------------------------- /man/PhViD.search.Rd: -------------------------------------------------------------------------------- 1 | \encoding{UTF-8} 2 | \name{PhViD.search} 3 | \alias{PhViD.search} 4 | %- Also NEED an '\alias' for EACH other topic documented here. 5 | \title{PhViD.search} 6 | \description{ 7 | This function makes possible to extract some information from the output of the PhViD functions for a given couple adverse event-drug, for a drug or for an adverse event. 8 | } 9 | \usage{ 10 | PhViD.search(RESULT, DRUG = NULL, EVENT = NULL) 11 | } 12 | %- maybe also 'usage' for other objects documented here. 13 | \arguments{ 14 | \item{RESULT}{\code{RESULT} must be the output of one the signal detection method functions (\code{ROR, PRR, RFET, GPS} or \code{BCPNN}} 15 | \item{DRUG}{The label of the drug. By default, \code{DRUG=FALSE}.} 16 | \item{EVENT}{The label of the adverse event. By default, \code{EVENT=FALSE}.} 17 | } 18 | 19 | \value{ 20 | \item{DRUG }{Recalls the label of the drug.} 21 | \item{EVENT}{Recalls the label of the event.} 22 | \item{EXIST_DRUG }{Indicates if the label of the drug exists in the database.} 23 | \item{EVENT}{Indicates if the label of the adverse event exists in the database.} 24 | \item{EXIST_COUPLE}{Indicates if the couple is present in the database.} 25 | \item{LIST}{It is a \code{dataframe} that contains the labels, the counts, the expected counts, the value of the statistic of interest, the rank and the estimated FDR for each couple.} 26 | } 27 | 28 | \author{Antoine Poncet & \enc{Ismaïl}{Ismail} Ahmed} 29 | \keyword{ manip } 30 | -------------------------------------------------------------------------------- /man/PhViDdata.frame.Rd: -------------------------------------------------------------------------------- 1 | \encoding{UTF-8} 2 | \name{PhViDdata.frame} 3 | \alias{PhViDdata.frame} 4 | \docType{data} 5 | \title{Simulated Pharmacovigilance data} 6 | \description{ 7 | This is a simulated data set aiming at mimicking the French database coded in ATC5 for the drugs and HLT for the adverse events. The simulation procedure is described in Ahmed et al. 8 | } 9 | \usage{data(PhViDdata.frame)} 10 | \format{ 11 | A data frame with 102483 observations on the following 3 variables. 12 | \describe{ 13 | \item{\code{Drug lab}}{a factor indicating the label of the 634 drugs.} 14 | \item{\code{AE lab}}{a factor indicating the label of the 756 adverse events.} 15 | \item{\code{n11}}{a numeric vector indicating the number of spontaneous reports of the corresponding couple.} 16 | } 17 | } 18 | \keyword{datasets} 19 | \author{\enc{Ismaïl}{Ismail} Ahmed & Antoine Poncet} 20 | -------------------------------------------------------------------------------- /man/RFET.Rd: -------------------------------------------------------------------------------- 1 | \encoding{UTF-8} 2 | \name{RFET} 3 | \alias{RFET} 4 | %- Also NEED an '\alias' for EACH other topic documented here. 5 | \title{Reporting Fisher's Exact Test} 6 | \description{ 7 | This function proposes the Fisher's Exact Test as an alternative to the PRR and ROR methods. The statistic of interest is the P-value or the mid-P-value resulting from the test (Ahmed et al., Biometrics). 8 | } 9 | \usage{ 10 | RFET(DATABASE, OR0 = 1, MIN.n11 = 1, DECISION = 1, 11 | DECISION.THRES = 0.05, MID.PVAL = FALSE) 12 | } 13 | %- maybe also 'usage' for other objects documented here. 14 | \arguments{ 15 | \item{DATABASE}{Object returned by the function \code{as.PhViD}.} 16 | \item{OR0}{Value of the tested odds ratio. By default, \code{OR0=1}.} 17 | \item{MIN.n11}{Minimum number of notifications for a couple to be potentially considered as a signal. By default, \code{MIN.n11 = 1}.} 18 | \item{DECISION}{Decision rule for the signal generation based on 19 | 20 | 1 = FDR (Default value) 21 | 22 | 2 = Number of signals 23 | 24 | 3 = P-values or mid-P-values. See \code{MID.PVAL}} 25 | \item{DECISION.THRES}{Threshold for \code{DECISION}. Ex 0.05 for FDR (\code{DECISION}=1). } 26 | \item{MID.PVAL}{if \code{MID.PVAL=TRUE}, the statistic of interest becomes the mid-P-values instead of the P-values resulting from the Fisher's exact test. By default \code{MID.PVAL=FALSE}.} 27 | } 28 | \details{ 29 | The FDR is estimated with the LBE procedure proposed by Dalmasso et al. (2005). 30 | } 31 | \value{ 32 | \item{ALLSIGNALS}{Data.frame summarizing the results of all couples with at least \code{MIN.n11} notifications ordered by \code{RANKSTAT}. It contains notably the labels, the cell counts, the expected count (\eqn{n1. \times n.1 / N}{n1. * n.1 / N}, see \code{\link{as.PhViD}}), \code{RANKSTAT}, the observed odds ratio (ROR), the marginal counts and the estimation of FDR.} 33 | \item{SIGNALS}{Same Data.frame as \code{ALLSIGNALS} but restricted to the list of generated signals.} 34 | \item{NB.SIGNALS}{Number of generated signals.} 35 | \item{INPUT.PARAM}{Parameters entered in the function.} 36 | } 37 | \references{ 38 | Ahmed I, Dalmasso C, Haramburu F, Thiessard F, \enc{Broët}{Broet} P, Tubert-Bitter P. False discovery rate estimation for frequentist pharmacovigilance signal detection methods. Biometrics. 2010 Mar;66(1):301-309. 39 | 40 | Dalmasso C, \enc{Broët}{Broet} P, Moreau T (2005), A simple procedure for estimating the false discovery rate, Bioinformatics, Bioinformatics, 21: 660 - 668. 41 | 42 | } 43 | \examples{ 44 | ## start 45 | #data(PhViDdata.frame) 46 | #PhViDdata <- as.PhViD(PhViDdata.frame) 47 | #res <- RFET(PhViDdata) 48 | ## end 49 | } 50 | 51 | \author{\enc{Ismaïl}{Ismail} Ahmed & Antoine Poncet} 52 | \keyword{ htest } 53 | -------------------------------------------------------------------------------- /man/ROR.Rd: -------------------------------------------------------------------------------- 1 | \encoding{UTF-8} 2 | \name{ROR} 3 | \alias{ROR} 4 | %- Also NEED an '\alias' for EACH other topic documented here. 5 | \title{Reporting Odds Ratio} 6 | \description{ 7 | Reporting Odds Ratio proposed by van Puijenbroak et al. (2002) extended to the multiple comparison framework. 8 | } 9 | \usage{ 10 | ROR(DATABASE, OR0 = 1, MIN.n11 = 1, DECISION = 1, 11 | DECISION.THRES = 0.05, RANKSTAT = 1) 12 | } 13 | %- maybe also 'usage' for other objects documented here. 14 | %- maybe also 'usage' for other objects documented here. 15 | \arguments{ 16 | \item{DATABASE}{Object returned by the function \code{as.PhViD}.} 17 | \item{OR0}{Value of the tested odds ratio. By default, \code{OR0=1}.} 18 | \item{MIN.n11}{Minimum number of notifications for a couple to be potentially considered as a signal. By default, \code{MIN.n11 = 1}.} 19 | \item{DECISION}{Decision rule for the signal generation based on 20 | 21 | 1 = FDR (Default value) 22 | 23 | 2 = Number of signals 24 | 25 | 3 = Ranking statistic. See \code{RANKSTAT}} 26 | \item{DECISION.THRES}{Threshold for \code{DECISION}. Ex 0.05 for FDR (\code{DECISION}=1). } 27 | \item{RANKSTAT}{Statistic used for ranking the couples: 28 | 29 | 1 = P-value 30 | 31 | 2 = Lower bound of the 95\% two sided confidence interval of log(ROR).} 32 | } 33 | \details{ 34 | The FDR is estimated with the LBE procedure proposed by Dalmasso et al. (2005). Note that the FDR can only be estimated if the statistic of interest is the P-value. 35 | } 36 | \value{ 37 | \item{ALLSIGNALS}{Data.frame summarizing the results of all couples with at least \code{MIN.n11} notifications ordered by \code{RANKSTAT}. It contains notably the labels, the cell counts, the expected counts (\eqn{n1. \times n.1 / N}{n1. * n.1 / N}, see \code{\link{as.PhViD}}), \code{RANKSTAT}, the observed odds ratios (ROR), the marginal counts and the estimations of FDR (when 38 | \code{RANKSTAT=1}.)} 39 | \item{SIGNALS}{Same Data.frame as \code{ALLSIGNALS} but restricted to the list of generated signals.} 40 | \item{NB.SIGNALS}{Number of generated signals.} 41 | \item{INPUT.PARAM}{Parameters entered in the function.} 42 | } 43 | \references{ 44 | Ahmed I, Dalmasso C, Haramburu F, Thiessard F, \enc{Broët}{Broet} P, Tubert-Bitter P. False discovery rate estimation for frequentist pharmacovigilance signal detection methods. Biometrics. 2010 Mar;66(1):301-309. 45 | 46 | Dalmasso C, \enc{Broët}{Broet} P, Moreau T (2005), A simple procedure for estimating the false discovery rate, Bioinformatics, Bioinformatics, 21: 660 - 668. 47 | 48 | van Puijenbroek EP, Bate A, Leufkens HG, Lindquist M, Orre R, Egberts AC, A Comparison of Measures of Disproportionality for Signal Detection in Spontaneous Reporting Systems for Adverse Drug Reactions Pharmacoepidemiology and Drug Safety, 2002, 11, 3-1. 49 | } 50 | \examples{ 51 | ## start 52 | data(PhViDdata.frame) 53 | PhViDdata <- as.PhViD(PhViDdata.frame) 54 | res <- ROR(PhViDdata, MIN.n11 = 3) 55 | 56 | # Decision rule proposed by van Puijenbroek et al. (2002) 57 | # res2 <- ROR(PhViDdata, MIN.n11 = 1, DECISION=3, DECISION.THRES=0, RANKSTAT=2) 58 | ## end 59 | } 60 | 61 | \author{\enc{Ismaïl}{Ismail} Ahmed & Antoine Poncet} 62 | \keyword{ htest } 63 | -------------------------------------------------------------------------------- /man/as.PhViD.Rd: -------------------------------------------------------------------------------- 1 | \encoding{UTF-8} 2 | \name{as.PhViD} 3 | \alias{as.PhViD} 4 | %- Also NEED an '\alias' for EACH other topic documented here. 5 | \title{data.frame to PhViD data} 6 | \description{ 7 | \code{as.PhViD} is a function that converts a data.frame into an object that can be used in the signal detection method functions. 8 | } 9 | \usage{ 10 | as.PhViD(DATA.FRAME, MARGIN.THRES = 1) 11 | } 12 | %- maybe also 'usage' for other objects documented here. 13 | \arguments{ 14 | \item{DATA.FRAME}{The \code{data.frame} has to be structured as follows 15 | 16 | 1st column: label of the drugs 17 | 18 | 2nd column: label of the adverse events 19 | 20 | 3rd column: Number of spontaneous reports of the corresponding couple drug-adverse event. 21 | } 22 | \item{MARGIN.THRES}{ This option can be used to eliminate the drugs and the adverse events for which the marginal counts are less than \code{MARGIN.THRES}.} 23 | } 24 | \value{ 25 | \item{L}{\code{data.frame} that contains the labels of the drugs and the adverse events.} 26 | \item{N}{sum of the spontaneous reports counts.} 27 | \item{data}{\code{data.frame} that contains the number of spontaneous reports (\code{n11}) and the corresponding marginal counts as well (\code{n1.} and \code{n.1}).} 28 | } 29 | 30 | \author{\enc{Ismaïl}{Ismail} Ahmed & Antoine Poncet} 31 | \keyword{ manip } 32 | --------------------------------------------------------------------------------