function (content, measure, year, pmid, sortby, lefthand, righthand, type, cofactorlabel, topic, theme) { temp <- content temp <- gsub("\n", "", fixed = TRUE, temp, perl = TRUE) temp <- gsub("\t", " ", fixed = TRUE, temp) temp <- gsub(",", "\",\"", fixed = TRUE, temp) temp <- paste("\"", temp, "\"", sep = "") temp <- paste("Mymatrix <- matrix(c(", temp, "), ncol=8, byrow=TRUE, dimnames = list(NULL, c(\"Study\",\"year\", \"pmid\", \"TP\", \"FP\",\"FN\",\"TN\",\"cofactor\")))") x <- eval(parse(file = "", n = NULL, text = temp)) myframe <- data.frame(x) myframe$Study <- gsub("'", "", fixed = TRUE, myframe$Study) myframe$Study <- as.character(str_trim(myframe$Study)) myframe$year <- as.numeric(as.character(str_trim(myframe$year))) myframe$pmid <- as.numeric(as.character(str_trim(myframe$pmid))) myframe$TP <- as.numeric(as.character(str_trim(myframe$TP))) myframe$FP <- as.numeric(as.character(str_trim(myframe$FP))) myframe$FN <- as.numeric(as.character(str_trim(myframe$FN))) myframe$TN <- as.numeric(as.character(str_trim(myframe$TN))) myframe$studysize <- (myframe$TP + myframe$FP + myframe$FN + myframe$TN) myframe$prevalence <- (myframe$TP + myframe$FN)/myframe$studysize myframe$withoutcome <- (myframe$TP + myframe$FN) myframe$sensitivity <- myframe$TP/(myframe$TP + myframe$FN) myframe$specificity <- myframe$TN/(myframe$FP + myframe$TN) myframe$dor <- (myframe$TP/myframe$FP)/(myframe$FN/myframe$TN) msg = "" if (sortby == "study") { sortvalue <- myframe$Study } if (sortby == "year") { sortvalue <- myframe$year } if (sortby == "prevalence") { sortvalue <- myframe$prevalence } if (sortby == "sensitivity") { sortvalue <- myframe$sensitivity } if (sortby == "specificity") { sortvalue <- myframe$specificity } if (sortby == "cofactor") { sortvalue <- myframe$cofactor } if (sortby == "studysize") { sortvalue <- myframe$studysize } if (sortby == "weight") { sortvalue <- myframe$weight } myframe <- myframe[order(sortvalue), ] attach(myframe) KUBlue = "#0022B4" SkyBlue = "#6DC6E7" pubbiastext = "Test for funnel plot asymmetry" analyticmethod = "Hierarchical model (bivariate)" msg = "" meta1 <- madad(TP = TP, FN = FN, TN = TN, FP = FP, names = Study, data = myframe, correction = 0.5, correction.control = "all") height = 295 + length(myframe$Study) * 20 svgtext = paste("<?xml version=\"1.0\" encoding=\"UTF-8\"?><svg x=\"0\" y=\"0\" width=\"800px\" height=\"", height, "px\" viewBox=\"0 0 800 ", height, "\" style=\"font-family:Arial, Helvetica, sans-serif\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">", sep = "") svgtext = paste(svgtext, "<text x=\"10\" y=\"20\" style=\"font-weight:bold;font-size: 1.17em\">", topic, "</text>", sep = "") svgtext = paste(svgtext, "<!-- Header of plot--><text x=\"10\" y=\"45\" fill=\"black\" style=\"font-weight:bold\">Study</text><text x=\"200\" y=\"45\" fill=\"black\" style=\"font-weight:bold\">Prev. (%)</text><text x=\"325\" y=\"45\" fill=\"black\" style=\"font-weight:bold\">Sensitivity (%)</text><text x=\"550\" y=\"45\" fill=\"black\" style=\"font-weight:bold\">Specificity (%)</text><text x=\"700\" y=\"45\" fill=\"black\" style=\"font-weight:bold\"><!--DOR--></text><!-- Start of studies-->", sep = "") for (i in 1:length(myframe$Study)) { svgtext = paste(svgtext, "<a xlink:href=\"http://pubmed.gov/", myframe$pmid[i], "\" xlink:title=\"Study size is ", myframe$studysize[i], ". Prevalence of the outcome is ", round(myframe$prevalence[i] * 100, 0), "%. Click citation to open abstract at PubMed in a new window.\" target=\"_blank\"><text x=\"10\" y=\"", 45 + i * 20, "\" fill=\"rgba(0,0,255,1)\">", myframe$Study[i], ", ", myframe$year[i], "</text></a>", sep = "") svgtext = paste(svgtext, "<text x=\"230\" y=\"", 45 + i * 20, "\" fill=\"black\" style=\"font-weight:normal\">", round(myframe$prevalence[i] * 100, 0), "</text>", sep = "") x = 375 + 100 * meta1$sens[[1]][i] svgtext = paste(svgtext, "<text x=\"275\" y=\"", 45 + i * 20, "\" fill=\"black\" style=\"font-weight:normal\">", round(meta1$sens[[1]][i] * 100, 0), " (", round(meta1$sens$sens.ci[i, 1] * 100, 0), " - ", round(meta1$sens$sens.ci[i, 2] * 100, 0), ")</text>", sep = "") svgtext = paste(svgtext, "<circle cx=\"", x, "\" cy=\"", 40 + i * 20, "\" r=\"3\" stroke-width=\"0\" style=\"fill:black;\"/>", sep = "") cl.lower = 375 + 100 * meta1$sens$sens.ci[i, 1] ci.upper = 375 + 100 * meta1$sens$sens.ci[i, 2] svgtext = paste(svgtext, "<line x1=\"", cl.lower, "\" y1=\"", 40 + i * 20, "\" x2=\"", ci.upper, "\" y2=\"", 40 + i * 20, "\" style=\"stroke:rgba(0,0,0,1);stroke-width:2\" />", sep = "") x = 600 + 100 * meta1$spec[[1]][i] svgtext = paste(svgtext, "<text x=\"500\" y=\"", 45 + i * 20, "\" fill=\"black\" style=\"font-weight:normal\">", round(meta1$spec[[1]][i] * 100, 0), " (", round(meta1$spec$spec.ci[i, 1] * 100, 0), " - ", round(meta1$spec$spec.ci[i, 2] * 100, 0), ")</text>", sep = "") svgtext = paste(svgtext, "<circle cx=\"", x, "\" cy=\"", 40 + i * 20, "\" r=\"3\" stroke-width=\"0\" style=\"fill:black;\"/>", sep = "") cl.lower = 600 + 100 * meta1$spec$spec.ci[i, 1] ci.upper = 600 + 100 * meta1$spec$spec.ci[i, 2] svgtext = paste(svgtext, "<line x1=\"", cl.lower, "\" y1=\"", 40 + i * 20, "\" x2=\"", ci.upper, "\" y2=\"", 40 + i * 20, "\" style=\"stroke:rgba(0,0,0,1);stroke-width:2\" />", sep = "") } svgtext = paste(svgtext, "<!-- Bottom of plot--><!-- Axes --><g style=\"stroke:rgba(0,0,0,0.2);stroke-width:2\">", sep = "") svgtext = paste(svgtext, "<line x1=\"375\" y1=\"", 55 + i * 20, "\" x2=\"475\" y2=\"", 55 + i * 20, "\" />", sep = "") svgtext = paste(svgtext, "<line x1=\"600\" y1=\"", 55 + i * 20, "\" x2=\"700\" y2=\"", 55 + i * 20, "\" /></g>", sep = "") svgtext = paste(svgtext, "<!-- Ticks -->", sep = "") svgtext = paste(svgtext, "<g stroke=\"rgba(0,0,0,0.2)\" stroke-width=\"1\" fill=\"rgba(0,0,0,0.2)\">", sep = "") svgtext = paste(svgtext, "<g transform=\"translate(475,", 55 + i * 20, ") rotate(180)\"><path d=\"M 0,0 L 0,5 M 50,0 L 50,5 M 100,0 L 100,5\" /></g>", sep = "") svgtext = paste(svgtext, "<g transform=\"translate(700,", 55 + i * 20, ") rotate(180)\"><path d=\"M 0,0 L 0,5 M 50,0 L 50,5 M 100,0 L 100,5\" /></g></g>", sep = "") if (type == "ignore") { meta2 <- fit.bivar(TP = TP, FN = FN, TN = TN, FP = FP, study = Study, data = myframe) meta2 <- summary(meta2$bi.simple) sensitivity = c(meta2$coefficients[1, 1], meta2$coefficients[1, 1] - qnorm(0.975) * meta2$coefficients[1, 2], meta2$coefficients[1, 1] + qnorm(0.975) * meta2$coefficients[1, 2]) sensitivity = plogis(sensitivity) sensitivity = round(100 * sensitivity, 1) specificity = c(meta2$coefficients[2, 1], meta2$coefficients[2, 1] - qnorm(0.975) * meta2$coefficients[2, 2], meta2$coefficients[2, 1] + qnorm(0.975) * meta2$coefficients[2, 2]) specificity = plogis(specificity) specificity = round(100 * specificity, 1) meta2 <- perfect.trees(TP = TP, FN = FN, TN = TN, FP = FP, study = Study, data = myframe) svgtext = paste(svgtext, "<!-- Vertical summary lines -->", sep = "") svgtext = paste(svgtext, "<g style=\"stroke:rgba(0,0,0,0.2);stroke-width:2\" ><line x1=\"", 375 + sensitivity[1], "\" y1=\"55\" x2=\"", 375 + sensitivity[1], "\" y2=\"", 55 + i * 20, "\" />", sep = "") svgtext = paste(svgtext, "<line x1=\"", 600 + specificity[1], "\" y1=\"55\" x2=\"", 600 + specificity[1], "\" y2=\"", 55 + i * 20, "\"/></g>", sep = "") svgtext = paste(svgtext, "<!-- Summary text --><g fill=\"black\" style=\"color:black;opacity:1\"><text x=\"10\" y=\"", 70 + i * 20, "\" style=\"font-weight:bold\">Summary</text>", sep = "") pooledprevalence = (sum(TP) + sum(FN))/sum(studysize) svgtext = paste(svgtext, "<text x=\"230\" y=\"", 70 + i * 20, "\" fill=\"black\" style=\"font-weight:bold\">", round(pooledprevalence * 100, 0), "</text>", sep = "") svgtext = paste(svgtext, "<text x=\"275\" y=\"", 70 + i * 20, "\" fill=\"black\" style=\"font-weight:bold\">", round(sensitivity[1], 0), " (", round(sensitivity[2], 0), " - ", round(sensitivity[3], 0), ")</text>", sep = "") svgtext = paste(svgtext, "<text x=\"", 375 + -10 + round(sensitivity[1], 0), "\" y=\"", 70 + i * 20, "\" fill=\"black\" style=\"font-weight:bold\">", round(sensitivity[1], 0), "</text>", sep = "") svgtext = paste(svgtext, "<text x=\"500\" y=\"", 70 + i * 20, "\" fill=\"black\" style=\"font-weight:bold\">", round(specificity[1], 0), " (", round(specificity[2], 0), " - ", round(specificity[3], 0), ")</text>", sep = "") svgtext = paste(svgtext, "<text x=\"", 600 + -10 + round(specificity[1], 0), "\" y=\"", 70 + i * 20, "\" fill=\"black\" style=\"font-weight:bold\">", round(specificity[1], 0), "</text>", sep = "") LRpos = meta2$coef[[2]][1]/(1 - meta2$coef[[3]][1]) LRneg = (1 - meta2$coef[[2]][1])/meta2$coef[[3]][1] auc <- AUC(phm(myframe)) svgtext = paste(svgtext, "<text x=\"10\" y=\"", 125 + i * 20, "\" style=\"font-weight:bold\">Area under the ROC curve: ", round(auc$AUC[[1]][1], 3), "</text>", sep = "") meta3 <- madauni(myframe, correction = 0.5, correction.control = "all") I2 <- summary(meta3)$Isq svgtext = paste(svgtext, "<text x=\"10\" y=\"", 145 + i * 20, "\" style=\"font-weight:bold\">Heterogeneity: ", round(I2, 1), "%</text>", sep = "") svgtext = paste(svgtext, "<text x=\"10\" y=\"", 160 + i * 20, "\" style=\"font-weight:normal\">(For diagnostic odds ratio: Q = ", round(meta3$CQ["Q"], 1), ", DF = ", meta3$CQ["df"], ")</text>", sep = "") svgtext = paste(svgtext, "<text x=\"10\" y=\"", 180 + i * 20, "\" style=\"font-weight:bold\">Predictive values:</text>", sep = "") PreTestOdds = pooledprevalence/(1 - pooledprevalence) PostTestOdds = PreTestOdds * LRpos ppv = sprintf("%.1f", (PostTestOdds/(1 + PostTestOdds) * 100)) PostTestOdds = PreTestOdds * LRneg npv = PostTestOdds/(1 + PostTestOdds) npv = sprintf("%.1f", (npv * 100)) svgtext = paste(svgtext, "<text x=\"10\" y=\"", 200 + i * 20, "\">At the prevalences studied (mean ", round(pooledprevalence * 100, 0), "%, median ", round(median(prevalence * 100, ), 0), "%, range ", round(min(prevalence * 100), 0), " - ", round(max(prevalence * 100), 0), ", odds ", round(PreTestOdds, 2), "):</text>", sep = "") svgtext = paste(svgtext, "<text x=\"20\" y=\"", 215 + i * 20, "\">Positive ", ppv, "%; negative ", 100 - as.numeric(npv), "%; 1- negative ", npv, "%</text>", sep = "") svgtext = paste(svgtext, "<a xlink:href=\"http://sumsearch.org/calc/calc.aspx?calc_dx_SnSp.aspx?prevalence=", round(pooledprevalence * 100, 0), "&sensitivity=", round(meta2$coefficients[[2]][1] * 100, 0), "&specificity=", round(meta2$coefficients[[3]][1] * 100, 0), "\" xlink:title=\"Adjust prevalence and recalculate predictive values\" target=\"_blank\"><text x=\"20\" y=\"", 230 + i * 20, "\" fill=\"rgba(0,0,255,1)\" style=\"font-weight:normal;text-decoration:underline;\">Click here to recalculate predictive values at other prevalences</text></a>", sep = "") svgtext = paste(svgtext, "<!-- About the studies --><text x=\"10\" y=\"", 255 + i * 20, "\" style=\"font-weight:bold\">About the studies:</text>", sep = "") svgtext = paste(svgtext, "<text x=\"10\" y=\"", 275 + i * 20, "\">", prettyNum(sum(studysize), big.mark = ","), " persons (median ", prettyNum(median(studysize), big.mark = ","), ", range ", min(studysize), " - ", max(studysize), ") in ", length(myframe$Study), " studies.</text>", sep = "") svgtext = paste(svgtext, "<text x=\"10\" y=\"", 290 + i * 20, "\">", prettyNum(sum(withoutcome), big.mark = ","), " persons with the outcome (median ", prettyNum(round(median(withoutcome, 0)), big.mark = ","), ", range ", min(withoutcome), " - ", max(withoutcome), ").</text>", sep = "") } svgtext = paste(svgtext, "</g>", sep = "") if (type == "subgroup") { msg = "Under construction (s)" } if (type == "metaregression (m)") { msg = "Under construction" } svgtext = paste(svgtext, "Sorry, your browser does not support inline SVG for dynamic graphics.</svg>") msg = svgtext msg = paste(msg, "<table style=\"background-color:#CFCFCF\" border=\"0\"><tbody><tr><td><a class=\"selectall\" href=\"javascript:document.getElementById('svgfile').select()\">Select source code for graphics below</a> (then press control and C together to copy.)<br><textarea id=\"svgfile\" cols=\"80\" rows=\"10\" wrap=\"virtual\" onfocus=\"this.select()\">", svgtext, "</textarea></td></tr></tbody></table>", sep = "") list(message = msg) } <bytecode: 0x5572ee8f5df0> <environment: namespace:home>