diff --git a/LegendMedCentral/DataPulls.R b/LegendMedCentral/DataPulls.R
new file mode 100644
index 00000000..cbb68181
--- /dev/null
+++ b/LegendMedCentral/DataPulls.R
@@ -0,0 +1,496 @@
+getExposureName <- function(connection, exposureId) {
+ sql <- "SELECT exposure_name FROM single_exposure_of_interest WHERE exposure_id = @exposure_id
+ UNION ALL SELECT exposure_name FROM combi_exposure_of_interest WHERE exposure_id = @exposure_id"
+ sql <- SqlRender::renderSql(sql, exposure_id = exposureId)$sql
+ sql <- SqlRender::translateSql(sql, targetDialect = connection@dbms)$sql
+ exposureName <- querySql(connection, sql)
+ return(exposureName[1, 1])
+}
+
+getExposureDescription <- function(connection, exposureId) {
+ sql <- "SELECT description FROM single_exposure_of_interest WHERE exposure_id = @exposure_id
+ UNION ALL SELECT exposure_name FROM combi_exposure_of_interest WHERE exposure_id = @exposure_id"
+ sql <- SqlRender::renderSql(sql, exposure_id = exposureId)$sql
+ sql <- SqlRender::translateSql(sql, targetDialect = connection@dbms)$sql
+ exposureDescription <- querySql(connection, sql)
+ return(exposureDescription[1, 1])
+}
+
+getOutcomeName <- function(connection, outcomeId) {
+ sql <- "SELECT outcome_name FROM outcome_of_interest WHERE outcome_id = @outcome_id"
+ sql <- SqlRender::renderSql(sql, outcome_id = outcomeId)$sql
+ sql <- SqlRender::translateSql(sql, targetDialect = connection@dbms)$sql
+ outcomeName <- querySql(connection, sql)
+ return(outcomeName[1, 1])
+}
+
+getIndications <- function(connection) {
+ sql <- "SELECT indication_id, indication_name FROM indication"
+ sql <- SqlRender::translateSql(sql, targetDialect = connection@dbms)$sql
+ indications <- querySql(connection, sql)
+ colnames(indications) <- SqlRender::snakeCaseToCamelCase(colnames(indications))
+ return(indications)
+}
+
+getSubgroups <- function(connection) {
+ sql <- "SELECT DISTINCT interaction_covariate_id AS subgroup_id, covariate_name AS subgroup_name
+ FROM (
+ SELECT DISTINCT interaction_covariate_id
+ FROM cm_interaction_result
+ ) ids
+ INNER JOIN covariate
+ ON interaction_covariate_id = covariate_id"
+ sql <- SqlRender::translateSql(sql, targetDialect = connection@dbms)$sql
+ subgroups <- querySql(connection, sql)
+ colnames(subgroups) <- SqlRender::snakeCaseToCamelCase(colnames(subgroups))
+ subgroups$subgroupName <- gsub("Subgroup: ", "", subgroups$subgroupName)
+ return(subgroups)
+}
+
+
+getExposures <- function(connection, filterByCmResults = TRUE) {
+ sql <- "SELECT * FROM (
+ SELECT exposure_id, exposure_name, indication_id FROM single_exposure_of_interest
+ UNION ALL SELECT exposure_id, exposure_name, indication_id FROM combi_exposure_of_interest
+ ) exposure
+ INNER JOIN exposure_group
+ ON exposure.exposure_id = exposure_group.exposure_id
+ {@filter_by_cm_results} ? {
+ INNER JOIN exposure_ids
+ ON exposure_ids.exposure_id = exposure.exposure_id
+ }
+ ;"
+ sql <- SqlRender::renderSql(sql, filter_by_cm_results = filterByCmResults)$sql
+ sql <- SqlRender::translateSql(sql, targetDialect = connection@dbms)$sql
+ exposures <- querySql(connection, sql)
+ colnames(exposures) <- SqlRender::snakeCaseToCamelCase(colnames(exposures))
+ return(exposures)
+}
+
+getOutcomes <- function(connection) {
+ sql <- "SELECT outcome_id, outcome_name, indication_id FROM outcome_of_interest"
+ sql <- SqlRender::translateSql(sql, targetDialect = connection@dbms)$sql
+ outcomes <- querySql(connection, sql)
+ colnames(outcomes) <- SqlRender::snakeCaseToCamelCase(colnames(outcomes))
+ return(outcomes)
+}
+
+getAnalyses <- function(connection) {
+ sql <- "SELECT analysis_id, description FROM cohort_method_analysis"
+ sql <- SqlRender::translateSql(sql, targetDialect = connection@dbms)$sql
+ analyses <- querySql(connection, sql)
+ colnames(analyses) <- SqlRender::snakeCaseToCamelCase(colnames(analyses))
+ return(analyses)
+}
+
+getDatabases <- function(connection) {
+ sql <- "SELECT * FROM database"
+ sql <- SqlRender::translateSql(sql, targetDialect = connection@dbms)$sql
+ databases <- querySql(connection, sql)
+ colnames(databases) <- SqlRender::snakeCaseToCamelCase(colnames(databases))
+ return(databases)
+}
+
+getDatabaseDetails <- function(connection, databaseId) {
+ sql <- "SELECT * FROM database WHERE database_id = '@database_id'"
+ sql <- SqlRender::renderSql(sql, database_id = databaseId)$sql
+ sql <- SqlRender::translateSql(sql, targetDialect = connection@dbms)$sql
+ databaseDetails <- querySql(connection, sql)
+ colnames(databaseDetails) <- SqlRender::snakeCaseToCamelCase(colnames(databaseDetails))
+ databaseDetails$description <- sub("\\n", " ", databaseDetails$description)
+ databaseDetails$description <- sub("JDMC", "JMDC", databaseDetails$description) # TODO Fix in schema
+ return(databaseDetails)
+}
+
+getIndicationForExposure <- function(connection,
+ exposureIds = c()) {
+ sql <- "SELECT exposure_id, indication_id FROM single_exposure_of_interest WHERE"
+ sql <- paste(sql, paste0("exposure_id IN (", paste(exposureIds, collapse = ", "), ")"))
+
+ sql <- SqlRender::translateSql(sql, targetDialect = connection@dbms)$sql
+ indications <- querySql(connection, sql)
+ colnames(indications) <- SqlRender::snakeCaseToCamelCase(colnames(indications))
+ return(indications)
+}
+
+getTcoDbs <- function(connection,
+ targetIds = c(),
+ comparatorIds = c(),
+ outcomeIds = c(),
+ databaseIds = c(),
+ operator = "AND") {
+ sql <- "SELECT target_id, comparator_id, outcome_id, database_id FROM cohort_method_result WHERE analysis_id = 1"
+ parts <- c()
+ if (length(targetIds) != 0) {
+ parts <- c(parts, paste0("target_id IN (", paste(targetIds, collapse = ", "), ")"))
+ }
+ if (length(comparatorIds) != 0) {
+ parts <- c(parts, paste0("comparator_id IN (", paste(comparatorIds, collapse = ", "), ")"))
+ }
+ if (length(outcomeIds) != 0) {
+ parts <- c(parts, paste0("outcome_id IN (", paste(outcomeIds, collapse = ", "), ")"))
+ }
+ if (length(databaseIds) != 0) {
+ parts <- c(parts, paste0("database_id IN ('", paste(databaseIds, collapse = "', '"), "')"))
+ }
+ if (length(parts) != 0) {
+ if (operator == "AND") {
+ sql <- paste(sql, "AND", paste(parts, collapse = " AND "))
+ } else {
+ sql <- paste(sql, "AND", paste(parts, collapse = " OR "))
+ }
+ }
+ sql <- SqlRender::translateSql(sql, targetDialect = connection@dbms)$sql
+ tcoDbs <- querySql(connection, sql)
+ colnames(tcoDbs) <- SqlRender::snakeCaseToCamelCase(colnames(tcoDbs))
+ return(tcoDbs)
+}
+
+getTcoDbsStrict <- function(connection, exposureIds = c(), outcomeIds = c(), databaseIds = c()) {
+ sql <- "SELECT target_id, comparator_id, outcome_id, database_id FROM cohort_method_result WHERE analysis_id = 1"
+ parts <- c()
+ if (length(exposureIds) != 0) {
+ for (exposureId in exposureIds) {
+ parts <- c(parts,
+ paste0("(target_id = ", exposureId, " OR comparator_id = ", exposureId, ")"))
+ }
+ }
+ if (length(outcomeIds) != 0) {
+ parts <- c(parts, paste0("outcome_id IN (", paste(outcomeIds, collapse = ", "), ")"))
+ }
+ if (length(databaseIds) != 0) {
+ parts <- c(parts, paste0("database_id IN ('", paste(databaseIds, collapse = "', '"), "')"))
+ }
+ if (length(parts) != 0) {
+ sql <- paste(sql, "AND", paste(parts, collapse = " AND "))
+ }
+ sql <- SqlRender::translateSql(sql, targetDialect = connection@dbms)$sql
+ tcoDbs <- querySql(connection, sql)
+ colnames(tcoDbs) <- SqlRender::snakeCaseToCamelCase(colnames(tcoDbs))
+ return(tcoDbs)
+}
+
+getMainResults <- function(connection,
+ targetIds = c(),
+ comparatorIds = c(),
+ outcomeIds = c(),
+ databaseIds = c(),
+ analysisIds = c(),
+ estimatesOnly = FALSE) {
+ if (estimatesOnly) {
+ sql <- "SELECT calibrated_log_rr, calibrated_se_log_rr, calibrated_ci_95_lb, calibrated_ci_95_ub FROM cohort_method_result"
+ } else {
+ sql <- "SELECT * FROM cohort_method_result"
+ }
+ parts <- c()
+ if (length(targetIds) != 0) {
+ parts <- c(parts, paste0("target_id IN (", paste(targetIds, collapse = ", "), ")"))
+ }
+ if (length(comparatorIds) != 0) {
+ parts <- c(parts, paste0("comparator_id IN (", paste(comparatorIds, collapse = ", "), ")"))
+ }
+ if (length(outcomeIds) != 0) {
+ parts <- c(parts, paste0("outcome_id IN (", paste(outcomeIds, collapse = ", "), ")"))
+ }
+ if (length(databaseIds) != 0) {
+ parts <- c(parts, paste0("database_id IN ('", paste(databaseIds, collapse = "', '"), "')"))
+ }
+ if (length(analysisIds) != 0) {
+ parts <- c(parts, paste0("analysis_id IN ('", paste(analysisIds, collapse = "', '"), "')"))
+ }
+ if (length(parts) != 0) {
+ sql <- paste(sql, "WHERE", paste(parts, collapse = " AND "))
+ }
+ sql <- SqlRender::translateSql(sql, targetDialect = connection@dbms)$sql
+ results <- querySql(connection, sql)
+ colnames(results) <- SqlRender::snakeCaseToCamelCase(colnames(results))
+ return(results)
+}
+
+getSubgroupResults <- function(connection,
+ targetIds = c(),
+ comparatorIds = c(),
+ outcomeIds = c(),
+ databaseIds = c(),
+ analysisIds = c(),
+ subgroupIds = c(),
+ estimatesOnly = FALSE) {
+ if (estimatesOnly) {
+ sql <- "
+ SELECT ci_95_lb,
+ ci_95_ub,
+ log_rrr,
+ se_log_rrr
+ FROM cm_interaction_result
+ "
+ } else {
+ sql <- "SELECT target_id,
+ comparator_id,
+ outcome_id,
+ cm_interaction_result.analysis_id,
+ cohort_method_analysis.description AS analysis_description,
+ cm_interaction_result.database_id,
+ interaction_covariate_id,
+ covariate_name AS interaction_covariate_name,
+ rrr,
+ ci_95_lb,
+ ci_95_ub,
+ p,
+ calibrated_p,
+ i_2,
+ log_rrr,
+ se_log_rrr,
+ target_subjects,
+ comparator_subjects,
+ target_days,
+ comparator_days,
+ target_outcomes,
+ comparator_outcomes
+ FROM cm_interaction_result
+ INNER JOIN covariate
+ ON cm_interaction_result.interaction_covariate_id = covariate.covariate_id
+ AND cm_interaction_result.database_id = covariate.database_id
+ INNER JOIN cohort_method_analysis
+ ON cm_interaction_result.analysis_id = cohort_method_analysis.analysis_id"
+ }
+ parts <- c()
+ if (length(targetIds) != 0) {
+ parts <- c(parts, paste0("target_id IN (", paste(targetIds, collapse = ", "), ")"))
+ }
+ if (length(comparatorIds) != 0) {
+ parts <- c(parts, paste0("comparator_id IN (", paste(comparatorIds, collapse = ", "), ")"))
+ }
+ if (length(outcomeIds) != 0) {
+ parts <- c(parts, paste0("outcome_id IN (", paste(outcomeIds, collapse = ", "), ")"))
+ }
+ if (length(databaseIds) != 0) {
+ parts <- c(parts, paste0("cm_interaction_result.database_id IN ('",
+ paste(databaseIds, collapse = "', '"),
+ "')"))
+ }
+ if (length(analysisIds) != 0) {
+ parts <- c(parts, paste0("cm_interaction_result.analysis_id IN (", paste(analysisIds, collapse = ", "), ")"))
+ }
+ if (length(subgroupIds) != 0) {
+ parts <- c(parts, paste0("interaction_covariate_id IN (", paste(subgroupIds, collapse = ", "), ")"))
+ }
+
+ if (length(parts) != 0) {
+ sql <- paste(sql, "WHERE", paste(parts, collapse = " AND "))
+ }
+ sql <- SqlRender::translateSql(sql, targetDialect = connection@dbms)$sql
+ results <- querySql(connection, sql)
+ colnames(results) <- SqlRender::snakeCaseToCamelCase(colnames(results))
+ return(results)
+}
+
+getControlResults <- function(connection, targetId, comparatorId, analysisId, databaseId) {
+ sql <- "SELECT *
+ FROM cohort_method_result
+ INNER JOIN (
+ SELECT outcome_id,
+ outcome_name,
+ CAST(1 AS FLOAT) AS effect_size
+ FROM negative_control_outcome
+
+ UNION ALL
+
+ SELECT outcome_id,
+ outcome_name,
+ effect_size
+ FROM positive_control_outcome
+ ) outcomes
+ ON cohort_method_result.outcome_id = outcomes.outcome_id
+ WHERE target_id = @target_id
+ AND comparator_id = @comparator_id
+ AND database_id = '@database_id'
+ AND analysis_id = @analysis_id"
+ sql <- SqlRender::renderSql(sql,
+ target_id = targetId,
+ comparator_id = comparatorId,
+ database_id = databaseId,
+ analysis_id = analysisId)$sql
+ results <- querySql(connection, sql)
+ colnames(results) <- SqlRender::snakeCaseToCamelCase(colnames(results))
+ return(results)
+}
+
+getCmFollowUpDist <- function(connection,
+ targetId,
+ comparatorId,
+ outcomeId,
+ databaseId,
+ analysisId) {
+ sql <- "SELECT target_min_days,
+ target_p10_days,
+ target_p25_days,
+ target_median_days,
+ target_p75_days,
+ target_p90_days,
+ target_max_days,
+ comparator_min_days,
+ comparator_p10_days,
+ comparator_p25_days,
+ comparator_median_days,
+ comparator_p75_days,
+ comparator_p90_days,
+ comparator_max_days
+ FROM cm_follow_up_dist
+ WHERE target_id = @target_id
+ AND comparator_id = @comparator_id
+ AND outcome_id = @outcome_id
+ AND database_id = '@database_id'
+ AND analysis_id = @analysis_id"
+ sql <- SqlRender::renderSql(sql,
+ target_id = targetId,
+ comparator_id = comparatorId,
+ outcome_id = outcomeId,
+ database_id = databaseId,
+ analysis_id = analysisId)$sql
+ sql <- SqlRender::translateSql(sql, targetDialect = connection@dbms)$sql
+ followUpDist <- querySql(connection, sql)
+ colnames(followUpDist) <- SqlRender::snakeCaseToCamelCase(colnames(followUpDist))
+ return(followUpDist)
+}
+
+getCovariateBalance <- function(connection,
+ targetId,
+ comparatorId,
+ databaseId,
+ analysisId,
+ outcomeId = NULL) {
+ sql <- "SELECT covariate.covariate_id, covariate_name, covariate_analysis_id,
+ target_mean_before,
+ comparator_mean_before,
+ std_diff_before,
+ target_mean_after,
+ comparator_mean_after,
+ std_diff_after
+ FROM covariate_balance
+ INNER JOIN covariate
+ ON covariate_balance.covariate_id = covariate.covariate_id
+ AND covariate_balance.database_id = covariate.database_id
+ WHERE target_id = @target_id
+ AND comparator_id = @comparator_id
+ AND covariate.database_id = '@database_id'
+ AND analysis_id = @analysis_id
+ AND interaction_covariate_id IS NULL
+ {@outcome_id == \"\"} ? {AND outcome_id IS NULL} : {AND outcome_id = @outcome_id}"
+ sql <- SqlRender::renderSql(sql,
+ target_id = targetId,
+ comparator_id = comparatorId,
+ database_id = databaseId,
+ analysis_id = analysisId,
+ outcome_id = outcomeId)$sql
+ sql <- SqlRender::translateSql(sql, targetDialect = connection@dbms)$sql
+ balance <- querySql(connection, sql)
+ colnames(balance) <- c("covariateId",
+ "covariateName",
+ "analysisId",
+ "beforeMatchingMeanTreated",
+ "beforeMatchingMeanComparator",
+ "beforeMatchingStdDiff",
+ "afterMatchingMeanTreated",
+ "afterMatchingMeanComparator",
+ "afterMatchingStdDiff")
+ balance$absBeforeMatchingStdDiff <- abs(balance$beforeMatchingStdDiff)
+ balance$absAfterMatchingStdDiff <- abs(balance$afterMatchingStdDiff)
+ return(balance)
+}
+
+getPs <- function(connection, targetIds, comparatorIds, databaseId) {
+ sql <- "SELECT target_id,
+ comparator_id,
+ preference_score,
+ target_density,
+ comparator_density
+ FROM preference_score_dist
+ WHERE target_id IN (@target_ids)
+ AND comparator_id IN (@comparator_ids)
+ AND database_id = '@database_id'"
+ sql <- SqlRender::renderSql(sql,
+ target_ids = targetIds,
+ comparator_ids = comparatorIds,
+ database_id = databaseId)$sql
+ sql <- SqlRender::translateSql(sql, targetDialect = connection@dbms)$sql
+ ps <- querySql(connection, sql)
+ colnames(ps) <- SqlRender::snakeCaseToCamelCase(colnames(ps))
+ return(ps)
+}
+
+getKaplanMeier <- function(connection, targetId, comparatorId, outcomeId, databaseId, analysisId) {
+ sql <- "SELECT time,
+ target_at_risk,
+ comparator_at_risk,
+ target_survival,
+ target_survival_lb,
+ target_survival_ub,
+ comparator_survival,
+ comparator_survival_lb,
+ comparator_survival_ub
+ FROM kaplan_meier_dist
+ WHERE target_id = @target_id
+ AND comparator_id = @comparator_id
+ AND outcome_id = @outcome_id
+ AND database_id = '@database_id'
+ AND analysis_id = @analysis_id"
+ sql <- SqlRender::renderSql(sql,
+ target_id = targetId,
+ comparator_id = comparatorId,
+ outcome_id = outcomeId,
+ database_id = databaseId,
+ analysis_id = analysisId)$sql
+ sql <- SqlRender::translateSql(sql, targetDialect = connection@dbms)$sql
+ ps <- querySql(connection, sql)
+ colnames(ps) <- SqlRender::snakeCaseToCamelCase(colnames(ps))
+ return(ps)
+}
+
+getAttrition <- function(connection, targetId, comparatorId, outcomeId, analysisId, databaseId) {
+ sql <- "SELECT exposure_id,
+ sequence_number,
+ description,
+ subjects
+ FROM attrition
+ WHERE (target_id IS NULL OR target_id = @target_id)
+ AND (comparator_id IS NULL OR comparator_id = @comparator_id)
+ AND (outcome_id IS NULL OR outcome_id = @outcome_id)
+ AND (exposure_id = @target_id OR exposure_id = @comparator_id)
+ AND (analysis_id IS NULL OR analysis_id = @analysis_id)
+ AND database_id = '@database_id'"
+ sql <- SqlRender::renderSql(sql,
+ target_id = targetId,
+ comparator_id = comparatorId,
+ outcome_id = outcomeId,
+ analysis_id = analysisId,
+ database_id = databaseId)$sql
+ sql <- SqlRender::translateSql(sql, targetDialect = connection@dbms)$sql
+ attrition <- querySql(connection, sql)
+ colnames(attrition) <- SqlRender::snakeCaseToCamelCase(colnames(attrition))
+ targetAttrition <- attrition[attrition$exposureId == targetId, ]
+ comparatorAttrition <- attrition[attrition$exposureId == comparatorId, ]
+ colnames(targetAttrition)[colnames(targetAttrition) == "subjects"] <- "targetPersons"
+ targetAttrition$exposureId <- NULL
+ colnames(comparatorAttrition)[colnames(comparatorAttrition) == "subjects"] <- "comparatorPersons"
+ comparatorAttrition$exposureId <- NULL
+ attrition <- merge(targetAttrition, comparatorAttrition)
+ attrition <- attrition[order(attrition$sequenceNumber), ]
+ return(attrition)
+}
+
+getStudyPeriod <- function(connection, targetId, comparatorId, databaseId) {
+ sql <- "SELECT min_date,
+ max_date
+ FROM comparison_summary
+ WHERE target_id = @target_id
+ AND comparator_id = @comparator_id
+ AND database_id = '@database_id'"
+ sql <- SqlRender::renderSql(sql,
+ target_id = targetId,
+ comparator_id = comparatorId,
+ database_id = databaseId)$sql
+ sql <- SqlRender::translateSql(sql, targetDialect = connection@dbms)$sql
+ studyPeriod <- querySql(connection, sql)
+ colnames(studyPeriod) <- SqlRender::snakeCaseToCamelCase(colnames(studyPeriod))
+ return(studyPeriod)
+}
diff --git a/LegendMedCentral/LegendMedCentral.Rproj b/LegendMedCentral/LegendMedCentral.Rproj
new file mode 100644
index 00000000..8e3c2ebc
--- /dev/null
+++ b/LegendMedCentral/LegendMedCentral.Rproj
@@ -0,0 +1,13 @@
+Version: 1.0
+
+RestoreWorkspace: Default
+SaveWorkspace: Default
+AlwaysSaveHistory: Default
+
+EnableCodeIndexing: Yes
+UseSpacesForTab: Yes
+NumSpacesForTab: 2
+Encoding: UTF-8
+
+RnwWeave: Sweave
+LaTeX: pdfLaTeX
diff --git a/LegendMedCentral/MyArticle.Rmd b/LegendMedCentral/MyArticle.Rmd
new file mode 100644
index 00000000..49cf5aca
--- /dev/null
+++ b/LegendMedCentral/MyArticle.Rmd
@@ -0,0 +1,722 @@
+---
+params:
+ databaseId: "CCAE"
+ targetId: 1308842
+ comparatorId: 40226742
+ outcomeId: 2
+ indicationId: "Hypertension"
+ root: "."
+ primary: 1
+ ot: 1
+ itt: 2
+ matchOt: 3
+ matchItt: 4
+ title: "Acute myocardial infarction risk in new-users of valsartan versus olmesartan for hypertension in the JMDC database"
+ abstract: "We conduct a large-scale study on the incidence of acute myocardial infarction among new users of valsartan and olmesartan from 2006 to 2017 in the JMDC database. Outcomes of interest are estimates of the hazard ratio (HR) for incident events between comparable new users under on-treatment and intent-to-treat risk window assumptions. Secondary analyses entertain possible clinically relevant subgroup interaction with the HR. We identify 7316 valsartan and 9744 olmesartan patients for the on-treatment design, totaling 9093 and 9673 patient-years of observation, and 11 and 16 events respectively. We control for measured confounding using propensity score trimming and stratification or matching based on an expansive propensity score model that includes all measured patient features before treatment initiation. We account for unmeasured confounding using negative and positive controls to estimate and adjust for residual systematic bias in the study design and data source, providing calibrated confidence intervals and p-values. In terms of acute myocardial infarction, valsartan has a similar risk as compared to olmesartan [HR: 0.88, 95% confidence interval (CI) 0.39 - 2.01]."
+ save: NULL
+ load: NULL
+
+title: "`r params$title`"
+
+# Corresponding author: Martijn J. Schuemie, Janssen R&D, 1125 Trenton Harbourton Road, Titusville, NJ, 08560, Phone: +31 631793897, schuemie@ohdsi.org
+author:
+
+ - name: Martijn J. Schuemie
+ affiliation: a,b,c
+ - name: Patrick B. Ryan
+ affiliation: a,b,d
+ - name: Seng Chan You
+ affiliation: a,e
+ - name: Nicole Pratt
+ affiliation: a,f
+ - name: David Madigan
+ affiliation: a,g
+ - name: George Hripcsak
+ affiliation: a,d
+ - name: Marc A. Suchard
+ affiliation: a,c,h,i
+address:
+ - code: a
+ address: Observational Health Data Sciences and Informatics, New York, NY, USA
+ - code: b
+ address: Janssen Research & Development, Titusville, NJ, USA
+ - code: c
+ address: Department of Biostatistics, University of California, Los Angeles, CA
+ - code: d
+ address: Department of Biomedical Informatics, Columbia University, New York, NY
+ - code: e
+ address: Department of Biomedical Informatics, Ajou University, Suwon, South Korea
+ - code: f
+ address: Sansom Institute, University of South Australia, Adelaide SA, Australia
+ - code: g
+ address: Department of Statistics, Columbia University, New York, NY
+ - code: h
+ address: Department of Biomathematics, University of California, Los Angeles, CA
+ - code: i
+ address: Department of Human Genetics, University of California, Los Angeles, CA
+lead_author_surname: Schuemie et al.
+
+# Place DOI URL or CRAN Package URL here
+# doi: "https://cran.r-project.org/package=YourPackage"
+
+# Abstract
+abstract: "`r params$abstract`"
+
+# Optional: Acknowledgements
+# acknowledgements: |
+# This template package builds upon, and extends, the work of the excellent
+# [rticles](https://cran.r-project.org/package=rticles) package, and both packages rely on the
+# [PNAS LaTeX](http://www.pnas.org/site/authors/latex.xhtml) macros. Both these sources are
+# gratefully acknowledged as this work would not have been possible without them. Our extensions
+# are under the same respective licensing term
+# ([GPL-3](https://www.gnu.org/licenses/gpl-3.0.en.html) and
+# [LPPL (>= 1.3)](https://www.latex-project.org/lppl/)).
+
+# Optional: One or more keywords
+keywords:
+ - new-user cohort design
+ - comparative effectiveness
+ - drug safety
+
+# Paper size for the document, values of letterpaper and a4paper
+papersize: letter
+
+# Font size of the document, values of 9pt (default), 10pt, 11pt and 12pt
+fontsize: 9pt
+
+# Optional: Force one-column layout, default is two-column
+#one_column: true
+
+# Optional: Enables lineno mode, but only if one_column mode is also true
+#lineno: true
+
+# Optional: Enable one-sided layout, default is two-sided
+#one_sided: true
+
+# Optional: Enable section numbering, default is unnumbered
+#numbersections: true
+
+# Optional: Specify the depth of section number, default is 5
+#secnumdepth: 5
+
+# Optional: Skip inserting final break between acknowledgements, default is false
+skip_final_break: true
+
+# Optional: Bibliography
+# bibliography: pinp
+
+# Optional: Enable a 'Draft' watermark on the document
+watermark: true
+
+# Customize footer, eg by referencing the vignette
+footer_contents: OHDSI version 1.0
+
+# Produce a pinp document
+output:
+ pdf_document:
+ template: blank_template.tex
+ citation_package: natbib
+pnas_type: pnasresearcharticle
+bibliography: ohdsi.bib
+#csl: pnas.csl
+#output: rticles::pnas_article
+
+author_declaration: MJS and PBR are employees and share-holders of Janssen Research. MAS receives contract support from Janssen Research.
+
+# Required: Vignette metadata for inclusion in a package.
+vignette: >
+ %\VignetteIndexEntry{YourPackage-vignetteentry}
+ %\VignetteKeywords{YourPackage, r, anotherkeyword}
+ %\VignettePackage{YourPackage}
+ %\VignetteEngine{knitr::rmarkdown}
+
+---
+
+```{r, setup, echo=FALSE, message=FALSE,comment=FALSE,warning=FALSE}
+library(DatabaseConnector)
+library(knitr)
+library(xtable)
+library(ggplot2)
+# library(kableExtra)
+source("DataPulls.R")
+source("PlotsAndTables.R")
+options(knitr.kable.NA = '')
+
+extraCriteria <- list(
+ depression = "Further, we exclude patients with diagnoses of bipolar disorder or schizophrenia on or prior to their index date."
+)
+
+extraCovariates <- list(
+ depression = "Prior number of depression treatments (1, 2, 3, 4, 5 or higher)"
+)
+
+negativeControls <- list(
+ hypertension = 76
+)
+
+totalOutcomes <- list(
+ hypertension = 57
+)
+
+totalExposures <- list(
+ hypertension = "56 different anti-hypertensive medications, representing 15 different drug-class levels and 7 major drug class levels",
+ stuff = "at least 2500 patients in both target and comparator cohors"
+)
+
+# params <- list(databaseId = "CCAE",
+# targetId = 1308842,
+# comparatorId = 40226742,
+# outcomeId = 2,
+# indicationId = "Hypertension",
+# root = ".",
+# primary = 1,
+# ot = 1,
+# itt = 2,
+# matchOt = 3,
+# matchItt = 4,
+# title = "Acute myocardial infarction risk in new-users of valsartan versus olmesartan for hypertension in the JMDC database",
+# abstract = "We conduct a large-scale study on the incidence of acute myocardial infarction among new users of valsartan and olmesartan from 2006 to 2017 in the JMDC database. Outcomes of interest are estimates of the hazard ratio (HR) for incident events between comparable new users under on-treatment and intent-to-treat risk window assumptions. Secondary analyses entertain possible clinically relevant subgroup interaction with the HR. We identify 7316 valsartan and 9744 olmesartan patients for the on-treatment design, totaling 9093 and 9673 patient-years of observation, and 11 and 16 events respectively. We control for measured confounding using propensity score trimming and stratification or matching based on an expansive propensity score model that includes all measured patient features before treatment initiation. We account for unmeasured confounding using negative and positive controls to estimate and adjust for residual systematic bias in the study design and data source, providing calibrated confidence intervals and p-values. In terms of acute myocardial infarction, valsartan has a similar risk as compared to olmesartan [HR: 0.88, 95% confidence interval (CI) 0.39 - 2.01].")
+
+```
+
+```{r, loadData, echo=FALSE, message=FALSE, comment=FALSE, warning=FALSE, results='hide'}
+
+if (is.null(params$load)) {
+ connectionDetails <- createConnectionDetails(dbms = "postgresql",
+ server = paste(Sys.getenv("legendServer"),
+ Sys.getenv("legendDatabase"), sep = "/"),
+ port = Sys.getenv("legendPort"),
+ user = Sys.getenv("legendUser"),
+ password = Sys.getenv("legendPw"),
+ schema = Sys.getenv("legendSchema"))
+ connection <- connect(connectionDetails)
+
+ targetName <- getExposureName(connection = connection, exposureId = params$targetId)
+ comparatorName <- getExposureName(connection = connection, exposureId = params$comparatorId)
+ outcomeName <- getOutcomeName(connection = connection, outcomeId = params$outcomeId)
+ analyses <- getAnalyses(connection = connection)
+ databaseDetails <- getDatabaseDetails(connection = connection,
+ databaseId = params$databaseId)
+ studyPeriod <- getStudyPeriod(connection = connection,
+ targetId = params$targetId,
+ comparatorId = params$comparatorId,
+ databaseId = params$databaseId)
+
+ mainResults <- getMainResults(connection = connection,
+ targetIds = params$targetId,
+ comparatorIds = params$comparatorId,
+ outcomeIds = params$outcomeId,
+ databaseIds = params$databaseId,
+ analysisIds = c(1, 2, 3, 4))
+
+ subgroupResults <- getSubgroupResults(connection = connection,
+ targetIds = params$targetId,
+ comparatorIds = params$comparatorId,
+ outcomeIds = params$outcomeId,
+ databaseIds = params$databaseId)
+
+ controlResults <- getControlResults(connection = connection,
+ targetId = params$targetId,
+ comparatorId = params$comparatorId,
+ analysisId = 1,
+ databaseId = params$databaseId)
+
+ attrition <- getAttrition(connection = connection,
+ targetId = params$targetId,
+ comparatorId = params$comparatorId,
+ outcomeId = params$outcomeId,
+ analysisId = 1,
+ databaseId = params$databaseId)
+
+ followUpDist <- getCmFollowUpDist(connection = connection,
+ targetId = params$targetId,
+ comparatorId = params$comparatorId,
+ outcomeId = params$outcomeId,
+ databaseId = params$databaseId,
+ analysisId = 1)
+
+ balance <- getCovariateBalance(connection = connection,
+ targetId = params$targetId,
+ comparatorId = params$comparatorId,
+ databaseId = params$databaseId,
+ analysisId = 2)
+
+ popCharacteristics <- getCovariateBalance(connection = connection,
+ targetId = params$targetId,
+ comparatorId = params$comparatorId,
+ databaseId = params$databaseId,
+ analysisId = 1,
+ outcomeId = params$outcomeId)
+
+ ps <- getPs(connection = connection,
+ targetIds = params$targetId,
+ comparatorIds = params$comparatorId,
+ databaseId = params$databaseId)
+
+ kaplanMeier <- getKaplanMeier(connection = connection,
+ targetId = params$targetId,
+ comparatorId = params$comparatorId,
+ outcomeId = params$outcomeId,
+ databaseId = params$databaseId,
+ analysisId = 2)
+
+ DatabaseConnector::disconnect(connection)
+
+ if (!is.null(params$save)) {
+ save(targetName, comparatorName, outcomeName, analyses, databaseDetails,
+ studyPeriod, mainResults, subgroupResults, controlResults,
+ attrition, followUpDist, balance, popCharacteristics, ps, kaplanMeier,
+ file = params$save)
+ }
+} else {
+ load(params$load)
+}
+
+targetName <- uncapitalize(targetName)
+comparatorName <- uncapitalize(comparatorName)
+outcomeName <- uncapitalize(outcomeName)
+indicationName <- uncapitalize(params$indicationId)
+
+databaseName <- databaseDetails$databaseName
+
+minYear <- substr(studyPeriod$minDate, 1, 4)
+maxYear <- substr(studyPeriod$maxDate, 1, 4)
+
+coverage <- getCoverage(controlResults)
+```
+
+\dropcap{T}he Large-scale Evidence Generation and Evaluation in a Network of Databases (LEGEND) project aims to generate reliable evidence on the effects of medical interventions using observational healthcare data to support clinical decision making.
+LEGEND follows ten guiding principles (see [Supporting Information](#suppinfo)); chief among these stand that we generate evidence at large-scale to achieve completeness and faciliate analysis of the overall distribution of effect size estimates across treatments and outcomes.
+We also generate evidence consistently by applying a systematic approach across all research questions and disseminate evidence regardless on the estimates effects to avoid publication bias. These aims help overcome the questionable reliable of observational research \citep{schuemie2018improving}.
+This LEGEND document reports the risk of `r outcomeName` between new users of `r targetName` and `r comparatorName` treated for `r params$indicationId`.
+
+\begin{itemize}
+ \item Add short introduction to indication.
+\end{itemize}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# Methods
+
+## Data source
+
+We conduct a new-user cohort study comparing new users of `r targetName` with new users of `r comparatorName` in the `r databaseName` (`r params$databaseId`) database encoded in the Observational Medical Outcomes Partnership (OMOP) common data model (CDM) version 5
+\citep{hripcsak2015observational,overhage2012validation,ryan2013empirical}.
+`r sub(paste0(".*\\(",databaseDetails$databaseId,"\\)"), paste0("The ", databaseDetails$databaseId), databaseDetails$description)`
+The study period spans from `r studyPeriod$minDate` to `r studyPeriod$maxDate`.
+
+## Study design
+
+This study follows a retrospective, observational, comparative cohort design \citep{ryan2013empirical}
+.
+We include patients who are first time users of `r targetName` or `r comparatorName`, and who have a diagnosis of `r indicationName` on or prior to treatment initation.
+We require that patients have continuous observation in the database for at least 365 days prior to treatment initiation.
+We exclude patients with prior `r outcomeName` events and less than 1 day at risk. `r if (indicationName %in% names(extraCriteria)) { extraCriteria[indicationName] }` Links to full cohort details, include concept codes, are provided in the [Supporting Information](#suppinfo).
+The outcome of interest is `r outcomeName`.
+We begin the outcome risk window 1 day after treatment initation and consider two design choices to define the window end.
+First, we end the outcome time-at-risk window at first cessation of continuous drug exposure, analogous to an on-treatment design and, second, we end the outcome time-at-risk window when the patient is no longer observable in the database, analogous to an intent-to-treat design.
+Continuous drug exposures are constructed from the available longitudinal data by considering sequential prescriptions that have fewer than 30 days gap between prescriptions.
+
+## Statistical analysis
+
+We conduct our cohort study using the open-source OHDSI CohortMethod R package \citep{schuemie2018cohortmethod}
+, with large-scale analytics achieved through the Cyclops R package \citep{suchard2013massive}
+.
+We use propensity scores (PSs) -- estimates of treatment exposure probability conditional on pre-treatment baseline features in the one year prior to treatment initiation -- to control for potential measured confoudning and improve balance between the target (`r targetName`) and comparator (`r comparatorName`) cohorts \citep{rosenbaum1983central}
+.
+We use an expansive PS model that includes all available patient demographics, drug, condition and procedure covariates generated through the FeatureExtraction R package \citep{schuemie2018featureextration}
+ instead of a prespecified set of investigator-selected confounders.
+ We perform PS stratification or variable-ratio matching and then estimate comparative `r targetName`-vs-`r comparatorName` hazard ratios (HRs) using a Cox proportional hazards model.
+ Detailed covariate and methods informations are provided in the
+ [Supporting Information](#suppinfo).
+ We present PS and covariate balance metrics to assess successful confounding control, and provide HR estimates and Kaplan-Meier survival plots for the outcome of `r outcomeName`.
+ We additionally estimate HRs for pre-specified subgroups to evaluate interactions with the treatment effect.
+For efficiency reasons, we fit subgroup Cox models using PS stratification only.
+
+Residual study bias from unmeasured and systematic sources can exist in observational studies after controlling for measured confounding \citep{schuemie2014interpreting,schuemie2016robust}
+.
+To estimate such residual bias, we conduct negative control outcome experiments with `r length(unique(controlResults$outcomeName))` negative control outcomes
+identified through a data-rich algorithm \citep{voss2017accuracy}.
+We fit the negative control estimates to an empirical null distribution that characterizes the study residual bias and is an important artifact from which to assess the study design \citep{schuemie2018improving}
+.
+Using the empirical null distribution and synthetic positive controls \citep{schuemie2018empirical}
+, we additionally calibrate all HR estimates, their 95\% confidence intervals (CIs) and the $p$-value to reject the null hypothesis of no differential effect (HR = 1).
+Empirical calibration serves as an important diagnostic tool to evaluate if residual systematic error is sufficient to cast doubt on the accuracy of the unknown effect estimate.
+
+# Results
+
+## Population characteristics
+
+```{r, attrition_plot, echo=FALSE, cache=TRUE, warning=FALSE, fig.align="center", fig.width=6, fig.height=10, out.width = '90%', fig.cap=paste("\\textbf{Attrition diagram for selecting new-users of", targetName, "and", comparatorName, "from the", params$databaseId, "database.\\label{fig:attrition}}")}
+drawAttritionDiagram(attrition, targetName, comparatorName)
+```
+
+Figure \ref{fig:attrition} diagrams the inclusion of study subjects from the `r params$databaseId` database under the on-treatment with stratification design.
+We augment these counts with cohort sizes we identify for the remaining designs in Table \ref{tab:power}.
+This table also reports total patient follow-up time, numbers of `r outcomeName` events these patients experience and unadjusted incidence rates.
+Table \ref{tab:demographics} compares base-line characteristics between patient cohorts.
+\begin{table*}
+\caption{\textbf{Patient cohorts.}
+Target (T) cohort is `r targetName` new-users. Comparative (C) cohort is `r comparatorName` new-users.
+We report total number of patients, follow-up time (in years), number of `r outcomeName` events, and event incidence rate (IR) per 1,000 patient years (PY) in patient cohorts, as well as the their minimum detectable relative risk (MDRR).
+Note that the IR does not account for any stratification or matching.
+}\label{tab:power}
+\vspace*{-0.5em}
+\centering{
+\rowcolors{2}{gray!6}{white}
+\begin{tabular}{lrrrrrrrrr}
+\hiderowcolors
+\toprule
+ &
+\multicolumn{2}{c}{Patients} &
+\multicolumn{2}{c}{PYs} &
+\multicolumn{2}{c}{Events} &
+\multicolumn{2}{c}{IR} &
+\\
+\cmidrule(lr){2-3} \cmidrule(lr){4-5} \cmidrule(lr){6-7} \cmidrule(lr){8-9}
+\multicolumn{1}{c}{Design} &
+\multicolumn{1}{c}{T} & \multicolumn{1}{c}{C} &
+\multicolumn{1}{c}{T} & \multicolumn{1}{c}{C} &
+\multicolumn{1}{c}{T} & \multicolumn{1}{c}{C} &
+\multicolumn{1}{c}{T} & \multicolumn{1}{c}{C} &
+\multicolumn{1}{c}{MDRR} \\
+\midrule
+\showrowcolors
+```{r, outcomes, echo=FALSE, results="asis", cache=TRUE, warning=FALSE}
+table <- preparePowerTable(mainResults, analyses)
+
+print(xtable(table, format = "latex"),
+ include.rownames = FALSE,
+ include.colnames = FALSE,
+ hline.after = NULL,
+ only.contents = TRUE,
+ add.to.row = list(pos = list(nrow(table)), command = c("\\bottomrule")),
+ sanitize.text.function = identity)
+```
+\end{tabular}
+}
+\end{table*}
+
+\begin{table}
+\caption{\textbf{Patient demographics.} We report the standardized difference of population means (StdDiff) before and after stratification for selected base-line patient characteristics.}\label{tab:demographics}
+\vspace*{-0.5em}
+\centerline{
+\resizebox{0.5\textwidth}{!}{
+\rowcolors{2}{gray!6}{white}
+\begin{tabular}{lrrrrrr}
+\hiderowcolors
+\toprule
+& \multicolumn{3}{c}{Before stratification}
+& \multicolumn{3}{c}{After stratification} \\
+\cmidrule(lr){2-4} \cmidrule(lr){5-7}
+\multicolumn{1}{c}{Characteristic}
+ & \multicolumn{1}{c}{T (\%)}
+ & \multicolumn{1}{c}{C (\%)}
+ & \multicolumn{1}{c}{StdDiff}
+ & \multicolumn{1}{c}{T (\%)}
+ & \multicolumn{1}{c}{C (\%)}
+ & \multicolumn{1}{c}{StdDiff} \\
+\midrule
+\showrowcolors
+```{r, features, echo=FALSE, results="asis", cache=TRUE, warning=FALSE}
+table <- prepareTable1(balance, pathToCsv = file.path(params$root, "Table1Specs.csv"))
+table <- table[3:nrow(table),]
+
+print(xtable(table, format = "latex", align = c("l","l","r","r","r","r","r","r")),
+ include.rownames = FALSE,
+ include.colnames = FALSE,
+ hline.after = NULL,
+ only.contents = TRUE,
+ add.to.row = list(pos = list(nrow(table)), command = c("\\bottomrule")),
+ sanitize.text.function = identity)
+```
+\end{tabular}
+}
+}
+\end{table}
+
+## Patient characteristics balance
+
+```{r, make_ps, echo=FALSE, warning=FALSE, fig.align='center', fig.width=5, fig.height=5, out.width='70%', fig.cap=paste("\\textbf{Preference score distribution for", targetName, "and", comparatorName, "new-users.}", "The preference score is a transformation of the propensity score that adjusts for prevalence differences between populations. A higher overlap indicates that subjects in the two populations are more similar in terms of their predicted probability of receiving one treatment over the other.\\label{fig:ps}")}
+plotPs(ps, targetName, comparatorName)
+```
+
+Figure \ref{fig:ps} plots the preference score distributions, re-scalings of PS estimates to adjust for differential treatment prevalences, for patients treated with `r targetName` and `r comparatorName`.
+We assess characteristics balance achieved through PS adjustment by comparing all characteristics' standardized difference (StdDiff) between treatment group means before and after PS trimming and stratification (Table \ref{tab:demographics}).
+Figure \ref{fig:balance} plots StdDiff for all `r nrow(balance)` base-line patient features that serve as input for the PS model.
+Before stratification, `r sum(na.omit(balance$beforeMatchingStdDiff) > 0.1)` features have a StdDiff $> 0.1$. After stratification, the count is `r sum(na.omit(balance$afterMatchingStdDiff) > 0.1)`.
+
+
+```{r, make_balance, echo=FALSE, warning=FALSE, warning=FALSE, fig.align='center', fig.width=5, fig.height=5, out.width='70%', fig.cap="\\textbf{Patient characteristics balance before and after stratification.} As a rule-of-thum, all values $<0.1$ is generall considered well-balance \\citep{austin2009balance}."}
+plotCovariateBalanceScatterPlot(balance,
+ beforeLabel = "Before stratification",
+ afterLabel = "After stratification")
+```
+
+## Outcome assessment
+
+\begin{table*}
+\caption{Time-at-risk distributions as percentiles in the target and comparator cohorts after stratification.}
+\label{tab:fu}
+\centering{
+\rowcolors{2}{gray!6}{white}
+\begin{tabular}{crrrrrrr}
+\hiderowcolors
+\toprule
+&
+\multicolumn{1}{c}{min} &
+\multicolumn{1}{c}{10\%} &
+\multicolumn{1}{c}{25\%} &
+\multicolumn{1}{c}{50\%} &
+\multicolumn{1}{c}{75\%} &
+\multicolumn{1}{c}{90\%} &
+\multicolumn{1}{c}{max} \\
+\midrule
+\showrowcolors
+```{r, fu, echo=FALSE, results='asis', warning=FALSE}
+table <- prepareFollowUpDistTable(followUpDist)
+table$Cohort <- c(targetName, comparatorName)
+
+print(xtable(table, format = "latex"),
+ include.rownames = FALSE,
+ include.colnames = FALSE,
+ hline.after = NULL,
+ only.contents = TRUE,
+ add.to.row = list(pos = list(nrow(table)), command = c("\\bottomrule")),
+ sanitize.text.function = identity)
+```
+\end{tabular}
+}
+\end{table*}
+
+Table \ref{tab:fu} details the time to first `r outcomeName` or censoring distributions for patients in the `r targetName` and `r comparatorName` cohorts.
+We report in Table \ref{tab:hr} estimated HRs comparing `r targetName` to `r comparatorName` for the on-treatment and intent-to-treat designs with stratification or matching.
+Figure \ref{fig:km} plots Kaplan-Meier survival curves for patients under the intent-to-treat design.
+To examine possible subgroup differences in treatment-effect, we include Table{tab:subgroups} that reports HR estimates separately for children (age $<$ 18), the elderly (age $\ge$ 65), female patients, pregnant women, patients with hepatic impairment and patients with renal impairment, using PS stratification.
+
+```{r, km, echo=FALSE, results='hide', fig.width=6, fig.height=6, fig.align='center', out.width='80%', fig.cap=paste0("\\textbf{Kaplan Meier plot of ", outcomeName, "-free survival.} This plot is adjusted for the propensity score stratification; the ", targetName, " curve shows the actual observed survival. The ", comparatorName, " curve applies reweighting to approximate the counterfactual of what ", targetName, " survival would look like had the ", targetName, " cohort been exposed to ", comparatorName, " instead. The shaded area denotes the 95\\% CI.")}
+plotKm <- plotKaplanMeier(kaplanMeier, targetName, comparatorName)
+```
+
+\begin{table*}
+\caption{
+Hazard ratio (HR) estimates and their confidence intervals (CIs) and $p$-value to reject the null hypothesis of no difference (HR = 1) under various designs.
+}
+\label{tab:hr}
+\centering{
+\rowcolors{2}{gray!6}{white}
+\begin{tabular}{lrrrr}
+\hiderowcolors
+\toprule
+& \multicolumn{2}{c}{Uncalibrated} & \multicolumn{2}{c}{Calibrated} \\
+\cmidrule(lr){2-3} \cmidrule(lr){4-5}
+\multicolumn{1}{c}{Design}
+& \multicolumn{1}{c}{HR (95\% CI)} & \multicolumn{1}{c}{$p$}
+& \multicolumn{1}{c}{HR (95\% CI)} & \multicolumn{1}{c}{$p$} \\
+\midrule
+\showrowcolors
+```{r, result_table, echo=FALSE, results='asis'}
+table <- mainResults
+table$hr <- sprintf("%.2f (%.2f - %.2f)", mainResults$rr, mainResults$ci95Lb, mainResults$ci95Ub)
+table$p <- sprintf("%.2f", table$p)
+table$calHr <- sprintf("%.2f (%.2f - %.2f)", mainResults$calibratedRr, mainResults$calibratedCi95Lb, mainResults$calibratedCi95Ub)
+table$calibratedP <- sprintf("%.2f", table$calibratedP)
+table <- merge(table, analyses)
+table <- table[, c("description", "hr", "p", "calHr", "calibratedP")]
+
+print(xtable(table),
+ include.rownames = FALSE,
+ include.colnames = FALSE,
+ hline.after = NULL,
+ only.contents = TRUE,
+ add.to.row = list(pos = list(nrow(table)), command = c("\\bottomrule")),
+ sanitize.text.function = identity)
+```
+\end{tabular}
+}
+\end{table*}
+
+\begin{table*}
+\caption{
+Subgroup analyses. We report HR estimates, their 95\% CIs and uncalibrated and calibrated (cal) $p$-values to reject the null hypothesis of no difference in five pre-specified patient subgroups.
+}
+\label{tab:subgroups}
+\centering{
+\rowcolors{2}{gray!6}{white}
+\begin{tabular}{lrrrrrrrr}
+\hiderowcolors
+\toprule
+&
+\multicolumn{2}{c}{Subjects} &
+\multicolumn{3}{c}{On-treatment} &
+\multicolumn{3}{c}{Intent-to-treat} \\
+\cmidrule(lr){2-3} \cmidrule(lr){4-6} \cmidrule(lr){7-9}
+\multicolumn{1}{c}{Subgroup} &
+\multicolumn{1}{c}{T} &
+\multicolumn{1}{c}{C} &
+\multicolumn{1}{c}{HR (95\% CI)} &
+\multicolumn{1}{c}{$p$} &
+\multicolumn{1}{c}{cal-$p$} &
+\multicolumn{1}{c}{HR (95\% CI)} &
+\multicolumn{1}{c}{$p$} &
+\multicolumn{1}{c}{cal-$p$} \\
+\midrule
+\showrowcolors
+```{r, subgroups, echo=FALSE, results='asis', warning=FALSE}
+if (nrow(subgroupResults) > 0) {
+ table <- prepareSubgroupTable(subgroupResults)
+ print(xtable(table),
+ include.rownames = FALSE,
+ include.colnames = FALSE,
+ hline.after = NULL,
+ only.contents = TRUE,
+ add.to.row = list(pos = list(nrow(table)), command = c("\\bottomrule")),
+ sanitize.text.function = identity)
+}
+```
+\end{tabular}
+}
+\end{table*}
+
+## Residual systematic error
+
+In the absense of bias, we expect 95\% of negative and positive control estimate 95\% confidence intervals to include their presumed HR. In the case of negative controls, the presumed HR = 1. Figure \ref{fig:negatives} describes the negative and positive control estimates under the on-treatment with PS stratification design.
+Before calibration, negative and positive controls demonstrate `r judgeCoverage(coverage[coverage$group == "Uncalibrated", "coverage"])` coverage. After calibration, controls demonstrate `r judgeCoverage(coverage[coverage$group == "Calibrated", "coverage"])` coverage.
+
+```{r, make_error, echo=FALSE, warning=FALSE}
+plot <- plotScatter(controlResults)
+suppressMessages(ggsave(paste0(opts_chunk$get("fig.path"), "error.pdf"), plot,
+ width = 14, height = 4, units = "in"))
+```
+\begin{figure*}
+\centerline{
+\includegraphics[width=1.0\textwidth]{`r opts_chunk$get("fig.path")`error}
+}
+\caption{
+\textbf{Evaluation of effect estimation between `r targetName` and `r comparatorName` new-users}. The top plots HRs and their corresponding standard errors before calibration for each negative and synthetic positive control. The bottom plots the same estimates after calibration.
+}
+\label{fig:negatives}
+\end{figure*}
+
+# Conclusions
+
+We find that `r targetName` has a `r judgeHazardRatio(mainResults[params$primary,"calibratedCi95Lb"], mainResults[params$primary,"calibratedCi95Ub"])` risk of `r outcomeName` as compared to `r comparatorName` within the population that the `r params$databaseId` represents.
+
+
+
+# Supporting Information {#suppinfo}
+
+Here we enumerate the guiding principles of LEGEND and provide linking details on study cohorts and design.
+
+## LEGEND principles
+
+\begin{enumerate}[noitemsep]
+ \item Evidence will be generated at large-scale.
+ \item Dissemination of the evidence will not depend on the estimated effects.
+ \item Evidence will be generated by consistently applying a systematic approach across all research questions.
+ \item Evidence will be generated using a pre-specified analysis design.
+ \item Evidence will be generated using open source software that is freely available to all.
+ \item Evidence generation process will be empirically evaluated by including control research questions where the true effect size is known.
+ \item Evidence will be generated using best-practices.
+ \item LEGEND will not be used to evaluate methods.
+ \item Evidence will be updated on a regular basis.
+ \item No patient-level data will be shared between sites in the network, only aggregated data.
+\end{enumerate}
+
+## Study cohorts
+
+Please see the LEGEND `r indicationName` Study protocol (https://github.com/OHDSI/Legend/tree/master/Documents) for complete specification of the `r targetName`, `r comparatorName` and `r outcomeName` cohorts using ATLAS (http://www.ohdsi.org/web/atlas).
+
+## Negative controls
+
+We selected negative controls using a process similar to that outlined by \cite{voss2017accuracy}.
+We first construct a list of all conditions that satisfy the following criteria with respect to all drug exposures in the LEGEND `r indicationName` study:
+\begin{itemize}[noitemsep]
+ \item No Medline abstract where the MeSH terms suggests a drug-condition association \citep{winnenburg2015leveraging},
+ \item No mention of the drug-condition pair on a US product label in the ``Adverse Drug Reactions'' or ``Postmarketing'' section \citep{duke2013consistency},
+ \item No US spontaneous reports suggesting that the pair is in an adverse event relationship \citep{evans2001use,banda2016curated},
+ \item OMOP vocabulary does not suggest that the drug is indicated for the condition,
+ \item Vocabulary conditional concepts are usable (i.e., not too broad, not suggestive of an adverse event relationship, no pregnancy related), and
+ \item Exact condition concept itself is used in patient level data.
+\end{itemize}
+
+```{r, echo=FALSE}
+negatives <- controlResults[controlResults$effectSize == 1.0 & !is.na(controlResults$rr), ]
+```
+
+
+We optimize remaining condition concepts, such that parent concepts remove children as defined by the OMOP vocabulary and perform manual review to exclude any pairs that may still be in a causal relationship or too similar to the study outcome.
+For `r indicationName`, this process led to a candidate list of `r negativeControls[indicationName]` negative controls for which table can be found in study protocol [TODO URL].
+In the comparison of `r targetName` and `r comparatorName` in the `r params$databaseId` database, `r nrow(negatives)` negative controls had sufficient outcomes to return estimable HRs. We list these conditions in Table \ref{tab:negatives}
+
+\begin{table}
+\caption{Negative controls employed in the comparison of `r targetName` and `r comparatorName` in the `r params$databaseId` database.}
+\label{tab:negatives}
+\centering{
+\rowcolors{2}{gray!6}{white}
+\begin{tabular}{l}
+\hiderowcolors
+\toprule
+\multicolumn{1}{c}{Condition} \\
+\midrule
+\showrowcolors
+```{r, echo=FALSE, results='asis'}
+table <- data.frame(outcomeName = sort(negatives[,"outcomeName"]))
+print(xtable(table),
+ include.rownames = FALSE,
+ include.colnames = FALSE,
+ hline.after = NULL,
+ only.contents = TRUE,
+ add.to.row = list(pos = list(nrow(table)), command = c("\\bottomrule")),
+ sanitize.text.function = identity)
+```
+\end{tabular}
+}
+\end{table}
+
+## Covariate sets
+
+\begin{itemize}[noitemsep]
+\item Demographics (age in 5-year bands, gender, index year, index month)
+\item Conditions (condition occurrence in lookback window)
+ \begin{itemize}[noitemsep]
+ \item in 365 days prior to index date
+ \item in 30 days prior to index date
+ \end{itemize}
+\item Condition aggregation
+ \begin{itemize}[noitemsep]
+ \item SMOMED
+ \end{itemize}
+\item Drugs (drug occurrence in lookback window)
+ \begin{itemize}[noitemsep]
+ \item in 365 days prior to index date
+ \item in 30 days prior to index date
+ \end{itemize}
+\item Drug aggregation
+ \begin{itemize}[noitemsep]
+ \item Ingredient
+ \item ATC class
+ \end{itemize}
+\item Risk Scores (Charlson comorbidity index)
+`r if (indicationName %in% names(extraCovariates)) { paste("\\item", extraCovariates[indicationName]) }`
+\end{itemize}
+
+We exclude all covariates that occur in fewer than 0.1\% of patients within the target and comparator cohorts prior to model fitting for computational efficiency.
+
diff --git a/LegendMedCentral/MyArticle_cache/latex/__packages b/LegendMedCentral/MyArticle_cache/latex/__packages
new file mode 100644
index 00000000..3e24bd12
--- /dev/null
+++ b/LegendMedCentral/MyArticle_cache/latex/__packages
@@ -0,0 +1,7 @@
+base
+shiny
+DatabaseConnector
+DT
+ggplot2
+knitr
+xtable
diff --git a/LegendMedCentral/MyArticle_cache/latex/attrition_plot_bb844da3fadeafe9509ca9d614b0f16a.RData b/LegendMedCentral/MyArticle_cache/latex/attrition_plot_bb844da3fadeafe9509ca9d614b0f16a.RData
new file mode 100644
index 00000000..f44abf48
Binary files /dev/null and b/LegendMedCentral/MyArticle_cache/latex/attrition_plot_bb844da3fadeafe9509ca9d614b0f16a.RData differ
diff --git a/LegendMedCentral/MyArticle_cache/latex/attrition_plot_bb844da3fadeafe9509ca9d614b0f16a.rdb b/LegendMedCentral/MyArticle_cache/latex/attrition_plot_bb844da3fadeafe9509ca9d614b0f16a.rdb
new file mode 100644
index 00000000..e69de29b
diff --git a/LegendMedCentral/MyArticle_cache/latex/attrition_plot_bb844da3fadeafe9509ca9d614b0f16a.rdx b/LegendMedCentral/MyArticle_cache/latex/attrition_plot_bb844da3fadeafe9509ca9d614b0f16a.rdx
new file mode 100644
index 00000000..1c0ec057
Binary files /dev/null and b/LegendMedCentral/MyArticle_cache/latex/attrition_plot_bb844da3fadeafe9509ca9d614b0f16a.rdx differ
diff --git a/LegendMedCentral/MyArticle_cache/latex/features_6d986e09d41579c8f9ee29fca5436df7.RData b/LegendMedCentral/MyArticle_cache/latex/features_6d986e09d41579c8f9ee29fca5436df7.RData
new file mode 100644
index 00000000..d28a9cf0
Binary files /dev/null and b/LegendMedCentral/MyArticle_cache/latex/features_6d986e09d41579c8f9ee29fca5436df7.RData differ
diff --git a/LegendMedCentral/MyArticle_cache/latex/features_6d986e09d41579c8f9ee29fca5436df7.rdb b/LegendMedCentral/MyArticle_cache/latex/features_6d986e09d41579c8f9ee29fca5436df7.rdb
new file mode 100644
index 00000000..31e48887
Binary files /dev/null and b/LegendMedCentral/MyArticle_cache/latex/features_6d986e09d41579c8f9ee29fca5436df7.rdb differ
diff --git a/LegendMedCentral/MyArticle_cache/latex/features_6d986e09d41579c8f9ee29fca5436df7.rdx b/LegendMedCentral/MyArticle_cache/latex/features_6d986e09d41579c8f9ee29fca5436df7.rdx
new file mode 100644
index 00000000..69a25be4
Binary files /dev/null and b/LegendMedCentral/MyArticle_cache/latex/features_6d986e09d41579c8f9ee29fca5436df7.rdx differ
diff --git a/LegendMedCentral/MyArticle_cache/latex/outcomes_d4ffa24859cd40dfadb04e06d5ea9412.RData b/LegendMedCentral/MyArticle_cache/latex/outcomes_d4ffa24859cd40dfadb04e06d5ea9412.RData
new file mode 100644
index 00000000..e3f5cfc2
Binary files /dev/null and b/LegendMedCentral/MyArticle_cache/latex/outcomes_d4ffa24859cd40dfadb04e06d5ea9412.RData differ
diff --git a/LegendMedCentral/MyArticle_cache/latex/outcomes_d4ffa24859cd40dfadb04e06d5ea9412.rdb b/LegendMedCentral/MyArticle_cache/latex/outcomes_d4ffa24859cd40dfadb04e06d5ea9412.rdb
new file mode 100644
index 00000000..ca69a484
Binary files /dev/null and b/LegendMedCentral/MyArticle_cache/latex/outcomes_d4ffa24859cd40dfadb04e06d5ea9412.rdb differ
diff --git a/LegendMedCentral/MyArticle_cache/latex/outcomes_d4ffa24859cd40dfadb04e06d5ea9412.rdx b/LegendMedCentral/MyArticle_cache/latex/outcomes_d4ffa24859cd40dfadb04e06d5ea9412.rdx
new file mode 100644
index 00000000..65d8d814
Binary files /dev/null and b/LegendMedCentral/MyArticle_cache/latex/outcomes_d4ffa24859cd40dfadb04e06d5ea9412.rdx differ
diff --git a/LegendMedCentral/PlotsAndTables.R b/LegendMedCentral/PlotsAndTables.R
new file mode 100644
index 00000000..216360e6
--- /dev/null
+++ b/LegendMedCentral/PlotsAndTables.R
@@ -0,0 +1,973 @@
+createTitle <- function(tcoDbs) {
+ tcoDbs$targetName <- exposures$exposureName[match(tcoDbs$targetId, exposures$exposureId)]
+ tcoDbs$comparatorName <- exposures$exposureName[match(tcoDbs$comparatorId, exposures$exposureId)]
+ tcoDbs$outcomeName <- outcomes$outcomeName[match(tcoDbs$outcomeId, outcomes$outcomeId)]
+ tcoDbs$indicationId <- exposures$indicationId[match(tcoDbs$targetId, exposures$exposureId)]
+
+ titles <- paste(tcoDbs$outcomeName,
+ "risk in new-users of",
+ tcoDbs$targetName,
+ "versus",
+ tcoDbs$comparatorName,
+ "for",
+ uncapitalize(tcoDbs$indicationId),
+ "in the",
+ tcoDbs$databaseId,
+ "database")
+ return(titles)
+}
+
+createAuthors <- function() {
+ authors <- paste0(
+ "Martijn J. Schuemie", ", ",
+ "Patrick B. Ryan", ", ",
+ "Seng Chan You", ", ",
+ "Nicole Pratt", ", ",
+ "David Madigan", ", ",
+ "George Hripcsak", " and ",
+ "Marc A. Suchard"
+ )
+}
+
+
+
+
+createAbstract <- function(connection, tcoDb) {
+ targetName <- uncapitalize(exposures$exposureName[match(tcoDb$targetId, exposures$exposureId)])
+ comparatorName <- uncapitalize(exposures$exposureName[match(tcoDb$comparatorId, exposures$exposureId)])
+ outcomeName <- uncapitalize(outcomes$outcomeName[match(tcoDb$outcomeId, outcomes$outcomeId)])
+ indicationId <- uncapitalize(exposures$indicationId[match(tcoDb$targetId, exposures$exposureId)])
+
+ results <- getMainResults(connection,
+ targetIds = tcoDb$targetId,
+ comparatorIds = tcoDb$comparatorId,
+ outcomeIds = tcoDb$outcomeId,
+ databaseIds = tcoDb$databaseId)
+
+ studyPeriod <- getStudyPeriod(connection = connection,
+ targetId = tcoDb$targetId,
+ comparatorId = tcoDb$comparatorId,
+ databaseId = tcoDb$databaseId)
+
+ writeAbstract(outcomeName, targetName, comparatorName, tcoDb$databaseId, studyPeriod, results)
+}
+
+writeAbstract <- function(outcomeName,
+ targetName,
+ comparatorName,
+ databaseId,
+ studyPeriod,
+ mainResults) {
+
+ minYear <- substr(studyPeriod$minDate, 1, 4)
+ maxYear <- substr(studyPeriod$maxDate, 1, 4)
+
+ abstract <- paste0(
+ "We conduct a large-scale study on the incidence of ", outcomeName, " among new users of ", targetName, " and ", comparatorName, " from ", minYear, " to ", maxYear, " in the ", databaseId, " database. ",
+ "Outcomes of interest are estimates of the hazard ratio (HR) for incident events between comparable new users under on-treatment and intent-to-treat risk window assumptions. ",
+ "Secondary analyses entertain possible clinically relevant subgroup interaction with the HR. ",
+ "We identify ", mainResults[1, "targetSubjects"], " ", targetName, " and ", mainResults[1, "comparatorSubjects"], " ", comparatorName, " patients for the on-treatment design, totaling ", round(mainResults[1, "targetDays"] / 365.24), " and ", round(mainResults[1, "comparatorDays"] / 365.24), " patient-years of observation, and ", mainResults[1, "targetOutcomes"], " and ", mainResults[1, "comparatorOutcomes"], " events respectively. ",
+ "We control for measured confounding using propensity score trimming and stratification or matching based on an expansive propensity score model that includes all measured patient features before treatment initiation. ",
+ "We account for unmeasured confounding using negative and positive controls to estimate and adjust for residual systematic bias in the study design and data source, providing calibrated confidence intervals and p-values. ",
+ "In terms of ", outcomeName, ", ", targetName, " has a ", judgeHazardRatio(mainResults[1, "calibratedCi95Lb"], mainResults[1, "calibratedCi95Ub"]),
+ " risk as compared to ", comparatorName, " [HR: ", prettyHr(mainResults[1, "calibratedRr"]), ", 95% confidence interval (CI) ",
+ prettyHr(mainResults[1, "calibratedCi95Lb"]), " - ", prettyHr(mainResults[1, "calibratedCi95Ub"]), "]."
+ )
+
+ abstract
+}
+
+prepareFollowUpDistTable <- function(followUpDist) {
+ targetRow <- data.frame(Cohort = "Target",
+ Min = followUpDist$targetMinDays,
+ P10 = followUpDist$targetP10Days,
+ P25 = followUpDist$targetP25Days,
+ Median = followUpDist$targetMedianDays,
+ P75 = followUpDist$targetP75Days,
+ P90 = followUpDist$targetP90Days,
+ Max = followUpDist$targetMaxDays)
+ comparatorRow <- data.frame(Cohort = "Comparator",
+ Min = followUpDist$comparatorMinDays,
+ P10 = followUpDist$comparatorP10Days,
+ P25 = followUpDist$comparatorP25Days,
+ Median = followUpDist$comparatorMedianDays,
+ P75 = followUpDist$comparatorP75Days,
+ P90 = followUpDist$comparatorP90Days,
+ Max = followUpDist$comparatorMaxDays)
+ table <- rbind(targetRow, comparatorRow)
+ table$Min <- formatC(table$Min, big.mark = ",", format = "d")
+ table$P10 <- formatC(table$P10, big.mark = ",", format = "d")
+ table$P25 <- formatC(table$P25, big.mark = ",", format = "d")
+ table$Median <- formatC(table$Median, big.mark = ",", format = "d")
+ table$P75 <- formatC(table$P75, big.mark = ",", format = "d")
+ table$P90 <- formatC(table$P90, big.mark = ",", format = "d")
+ table$Max <- formatC(table$Max, big.mark = ",", format = "d")
+ return(table)
+}
+
+prepareMainResultsTable <- function(mainResults, analyses) {
+ table <- mainResults
+ table$hr <- sprintf("%.2f (%.2f - %.2f)", mainResults$rr, mainResults$ci95Lb, mainResults$ci95Ub)
+ table$p <- sprintf("%.2f", table$p)
+ table$calHr <- sprintf("%.2f (%.2f - %.2f)",
+ mainResults$calibratedRr,
+ mainResults$calibratedCi95Lb,
+ mainResults$calibratedCi95Ub)
+ table$calibratedP <- sprintf("%.2f", table$calibratedP)
+ table <- merge(table, analyses)
+ table <- table[, c("description", "hr", "p", "calHr", "calibratedP")]
+ colnames(table) <- c("Analysis", "HR (95% CI)", "P", "Cal. HR (95% CI)", "Cal. p")
+ return(table)
+}
+
+preparePowerTable <- function(mainResults, analyses) {
+ table <- merge(mainResults, analyses)
+ alpha <- 0.05
+ power <- 0.8
+ z1MinAlpha <- qnorm(1 - alpha/2)
+ zBeta <- -qnorm(1 - power)
+ pA <- table$targetSubjects/(table$targetSubjects + table$comparatorSubjects)
+ pB <- 1 - pA
+ totalEvents <- abs(table$targetOutcomes) + (table$comparatorOutcomes)
+ table$mdrr <- exp(sqrt((zBeta + z1MinAlpha)^2/(totalEvents * pA * pB)))
+ table$targetYears <- table$targetDays/365.25
+ table$comparatorYears <- table$comparatorDays/365.25
+ table$targetIr <- 1000 * table$targetOutcomes/table$targetYears
+ table$comparatorIr <- 1000 * table$comparatorOutcomes/table$comparatorYears
+ table <- table[, c("description",
+ "targetSubjects",
+ "comparatorSubjects",
+ "targetYears",
+ "comparatorYears",
+ "targetOutcomes",
+ "comparatorOutcomes",
+ "targetIr",
+ "comparatorIr",
+ "mdrr")]
+ table$targetSubjects <- formatC(table$targetSubjects, big.mark = ",", format = "d")
+ table$comparatorSubjects <- formatC(table$comparatorSubjects, big.mark = ",", format = "d")
+ table$targetYears <- formatC(table$targetYears, big.mark = ",", format = "d")
+ table$comparatorYears <- formatC(table$comparatorYears, big.mark = ",", format = "d")
+ table$targetOutcomes <- formatC(table$targetOutcomes, big.mark = ",", format = "d")
+ table$comparatorOutcomes <- formatC(table$comparatorOutcomes, big.mark = ",", format = "d")
+ table$targetIr <- sprintf("%.2f", table$targetIr)
+ table$comparatorIr <- sprintf("%.2f", table$comparatorIr)
+ table$mdrr <- sprintf("%.2f", table$mdrr)
+ table$targetSubjects <- gsub("^-", "<", table$targetSubjects)
+ table$comparatorSubjects <- gsub("^-", "<", table$comparatorSubjects)
+ table$targetOutcomes <- gsub("^-", "<", table$targetOutcomes)
+ table$comparatorOutcomes <- gsub("^-", "<", table$comparatorOutcomes)
+ table$targetIr <- gsub("^-", "<", table$targetIr)
+ table$comparatorIr <- gsub("^-", "<", table$comparatorIr)
+ idx <- (table$targetOutcomes < 0 | table$comparatorOutcomes < 0)
+ table$mdrr[idx] <- paste0(">", table$mdrr[idx])
+ return(table)
+}
+
+
+prepareSubgroupTable <- function(subgroupResults, output = "latex") {
+ rnd <- function(x) {
+ ifelse(x > 10, sprintf("%.1f", x), sprintf("%.2f", x))
+ }
+
+ subgroupResults$hrr <- paste0(rnd(subgroupResults$rrr),
+ " (",
+ rnd(subgroupResults$ci95Lb),
+ " - ",
+ rnd(subgroupResults$ci95Ub),
+ ")")
+
+ subgroupResults$hrr[is.na(subgroupResults$rrr)] <- ""
+ subgroupResults$p <- sprintf("%.2f", subgroupResults$p)
+ subgroupResults$p[subgroupResults$p == "NA"] <- ""
+ subgroupResults$calibratedP <- sprintf("%.2f", subgroupResults$calibratedP)
+ subgroupResults$calibratedP[subgroupResults$calibratedP == "NA"] <- ""
+
+ if (any(grepl("on-treatment", subgroupResults$analysisDescription)) &&
+ any(grepl("intent-to-treat", subgroupResults$analysisDescription))) {
+ idx <- grepl("on-treatment", subgroupResults$analysisDescription)
+ onTreatment <- subgroupResults[idx, c("interactionCovariateName",
+ "targetSubjects",
+ "comparatorSubjects",
+ "hrr",
+ "p",
+ "calibratedP")]
+ itt <- subgroupResults[!idx, c("interactionCovariateName", "hrr", "p", "calibratedP")]
+ colnames(onTreatment)[4:6] <- paste("onTreatment", colnames(onTreatment)[4:6], sep = "_")
+ colnames(itt)[2:4] <- paste("itt", colnames(itt)[2:4], sep = "_")
+ table <- merge(onTreatment, itt)
+ } else {
+ table <- subgroupResults[, c("interactionCovariateName",
+ "targetSubjects",
+ "comparatorSubjects",
+ "hrr",
+ "p",
+ "calibratedP")]
+ }
+ table$interactionCovariateName <- gsub("Subgroup: ", "", table$interactionCovariateName)
+ if (output == "latex") {
+ table$interactionCovariateName <- gsub(">=", "$\\\\ge$ ", table$interactionCovariateName)
+ }
+ table$targetSubjects <- formatC(table$targetSubjects, big.mark = ",", format = "d")
+ table$targetSubjects <- gsub("^-", "<", table$targetSubjects)
+ table$comparatorSubjects <- formatC(table$comparatorSubjects, big.mark = ",", format = "d")
+ table$comparatorSubjects <- gsub("^-", "<", table$comparatorSubjects)
+ table$comparatorSubjects <- gsub("^<", "$<$", table$comparatorSubjects)
+ return(table)
+}
+
+prepareTable1 <- function(balance,
+ beforeLabel = "Before stratification",
+ afterLabel = "After stratification",
+ targetLabel = "Target",
+ comparatorLabel = "Comparator",
+ percentDigits = 1,
+ stdDiffDigits = 2,
+ output = "latex",
+ pathToCsv = "Table1Specs.csv") {
+ if (output == "latex") {
+ space <- " "
+ } else {
+ space <- " "
+ }
+ specifications <- read.csv(pathToCsv, stringsAsFactors = FALSE)
+
+ fixCase <- function(label) {
+ idx <- (toupper(label) == label)
+ if (any(idx)) {
+ label[idx] <- paste0(substr(label[idx], 1, 1),
+ tolower(substr(label[idx], 2, nchar(label[idx]))))
+ }
+ return(label)
+ }
+
+ formatPercent <- function(x) {
+ result <- format(round(100 * x, percentDigits), digits = percentDigits + 1, justify = "right")
+ result <- gsub("^-", "<", result)
+ result <- gsub("NA", "", result)
+ result <- gsub(" ", space, result)
+ return(result)
+ }
+
+ formatStdDiff <- function(x) {
+ result <- format(round(x, stdDiffDigits), digits = stdDiffDigits + 1, justify = "right")
+ result <- gsub("NA", "", result)
+ result <- gsub(" ", space, result)
+ return(result)
+ }
+
+ resultsTable <- data.frame()
+ for (i in 1:nrow(specifications)) {
+ if (specifications$analysisId[i] == "") {
+ resultsTable <- rbind(resultsTable,
+ data.frame(Characteristic = specifications$label[i], value = ""))
+ } else {
+ idx <- balance$analysisId == specifications$analysisId[i]
+ if (any(idx)) {
+ if (specifications$covariateIds[i] != "") {
+ covariateIds <- as.numeric(strsplit(specifications$covariateIds[i], ";")[[1]])
+ idx <- balance$covariateId %in% covariateIds
+ } else {
+ covariateIds <- NULL
+ }
+ if (any(idx)) {
+ balanceSubset <- balance[idx, ]
+ if (is.null(covariateIds)) {
+ balanceSubset <- balanceSubset[order(balanceSubset$covariateId), ]
+ } else {
+ balanceSubset <- merge(balanceSubset, data.frame(covariateId = covariateIds,
+ rn = 1:length(covariateIds)))
+ balanceSubset <- balanceSubset[order(balanceSubset$rn, balanceSubset$covariateId), ]
+ }
+ balanceSubset$covariateName <- fixCase(gsub("^.*: ", "", balanceSubset$covariateName))
+ if (specifications$covariateIds[i] == "" || length(covariateIds) > 1) {
+ resultsTable <- rbind(resultsTable, data.frame(Characteristic = specifications$label[i],
+ beforeMatchingMeanTreated = NA,
+ beforeMatchingMeanComparator = NA,
+ beforeMatchingStdDiff = NA,
+ afterMatchingMeanTreated = NA,
+ afterMatchingMeanComparator = NA,
+ afterMatchingStdDiff = NA,
+ stringsAsFactors = FALSE))
+ resultsTable <- rbind(resultsTable, data.frame(Characteristic = paste0(space,
+ space,
+ space,
+ space,
+ balanceSubset$covariateName),
+ beforeMatchingMeanTreated = balanceSubset$beforeMatchingMeanTreated,
+ beforeMatchingMeanComparator = balanceSubset$beforeMatchingMeanComparator,
+ beforeMatchingStdDiff = balanceSubset$beforeMatchingStdDiff,
+ afterMatchingMeanTreated = balanceSubset$afterMatchingMeanTreated,
+ afterMatchingMeanComparator = balanceSubset$afterMatchingMeanComparator,
+ afterMatchingStdDiff = balanceSubset$afterMatchingStdDiff,
+ stringsAsFactors = FALSE))
+ } else {
+ resultsTable <- rbind(resultsTable, data.frame(Characteristic = specifications$label[i],
+ beforeMatchingMeanTreated = balanceSubset$beforeMatchingMeanTreated,
+ beforeMatchingMeanComparator = balanceSubset$beforeMatchingMeanComparator,
+ beforeMatchingStdDiff = balanceSubset$beforeMatchingStdDiff,
+ afterMatchingMeanTreated = balanceSubset$afterMatchingMeanTreated,
+ afterMatchingMeanComparator = balanceSubset$afterMatchingMeanComparator,
+ afterMatchingStdDiff = balanceSubset$afterMatchingStdDiff,
+ stringsAsFactors = FALSE))
+ }
+ }
+ }
+ }
+ }
+ resultsTable$beforeMatchingMeanTreated <- formatPercent(resultsTable$beforeMatchingMeanTreated)
+ resultsTable$beforeMatchingMeanComparator <- formatPercent(resultsTable$beforeMatchingMeanComparator)
+ resultsTable$beforeMatchingStdDiff <- formatStdDiff(resultsTable$beforeMatchingStdDiff)
+ resultsTable$afterMatchingMeanTreated <- formatPercent(resultsTable$afterMatchingMeanTreated)
+ resultsTable$afterMatchingMeanComparator <- formatPercent(resultsTable$afterMatchingMeanComparator)
+ resultsTable$afterMatchingStdDiff <- formatStdDiff(resultsTable$afterMatchingStdDiff)
+
+ headerRow <- as.data.frame(t(rep("", ncol(resultsTable))))
+ colnames(headerRow) <- colnames(resultsTable)
+ headerRow$beforeMatchingMeanTreated <- targetLabel
+ headerRow$beforeMatchingMeanComparator <- comparatorLabel
+ headerRow$afterMatchingMeanTreated <- targetLabel
+ headerRow$afterMatchingMeanComparator <- comparatorLabel
+
+ subHeaderRow <- as.data.frame(t(rep("", ncol(resultsTable))))
+ colnames(subHeaderRow) <- colnames(resultsTable)
+ subHeaderRow$Characteristic <- "Characteristic"
+ subHeaderRow$beforeMatchingMeanTreated <- "%"
+ subHeaderRow$beforeMatchingMeanComparator <- "%"
+ subHeaderRow$beforeMatchingStdDiff <- "Std. diff"
+ subHeaderRow$afterMatchingMeanTreated <- "%"
+ subHeaderRow$afterMatchingMeanComparator <- "%"
+ subHeaderRow$afterMatchingStdDiff <- "Std. diff"
+
+ resultsTable <- rbind(headerRow, subHeaderRow, resultsTable)
+
+ colnames(resultsTable) <- rep("", ncol(resultsTable))
+ colnames(resultsTable)[2] <- beforeLabel
+ colnames(resultsTable)[5] <- afterLabel
+ return(resultsTable)
+}
+
+plotPs <- function(ps, targetName, comparatorName) {
+ ps <- rbind(data.frame(x = ps$preferenceScore, y = ps$targetDensity, group = targetName),
+ data.frame(x = ps$preferenceScore, y = ps$comparatorDensity, group = comparatorName))
+ ps$group <- factor(ps$group, levels = c(as.character(targetName), as.character(comparatorName)))
+ levels(ps$group) <- paste0(" " , levels(ps$group), " ") # Add space between legend labels
+ theme <- ggplot2::element_text(colour = "#000000", size = 12)
+ plot <- ggplot2::ggplot(ps,
+ ggplot2::aes(x = x, y = y, color = group, group = group, fill = group)) +
+ ggplot2::geom_density(stat = "identity") +
+ ggplot2::scale_fill_manual(values = c(rgb(0.8, 0, 0, alpha = 0.5),
+ rgb(0, 0, 0.8, alpha = 0.5))) +
+ ggplot2::scale_color_manual(values = c(rgb(0.8, 0, 0, alpha = 0.5),
+ rgb(0, 0, 0.8, alpha = 0.5))) +
+ ggplot2::scale_x_continuous("Preference score", limits = c(0, 1)) +
+ ggplot2::scale_y_continuous("Density") +
+ ggplot2::theme(legend.title = ggplot2::element_blank(),
+ panel.grid.major = ggplot2::element_blank(),
+ panel.grid.minor = ggplot2::element_blank(),
+ legend.position = "top",
+ legend.text = theme,
+ axis.text = theme,
+ axis.title = theme)
+ return(plot)
+}
+
+plotAllPs <- function(ps) {
+ ps <- rbind(data.frame(targetName = ps$targetName,
+ comparatorName = ps$comparatorName,
+ x = ps$preferenceScore,
+ y = ps$targetDensity,
+ group = "Target"),
+ data.frame(targetName = ps$targetName,
+ comparatorName = ps$comparatorName,
+ x = ps$preferenceScore,
+ y = ps$comparatorDensity,
+ group = "Comparator"))
+ ps$group <- factor(ps$group, levels = c("Target", "Comparator"))
+ plot <- ggplot2::ggplot(ps, ggplot2::aes(x = x, y = y, color = group, group = group, fill = group)) +
+ ggplot2::geom_density(stat = "identity") +
+ ggplot2::scale_fill_manual(values = c(rgb(0.8, 0, 0, alpha = 0.5), rgb(0, 0, 0.8, alpha = 0.5))) +
+ ggplot2::scale_color_manual(values = c(rgb(0.8, 0, 0, alpha = 0.5), rgb(0, 0, 0.8, alpha = 0.5))) +
+ ggplot2::scale_x_continuous("Preference score", limits = c(0, 1)) +
+ ggplot2::scale_y_continuous("Density") +
+ ggplot2::facet_grid(targetName ~ comparatorName) +
+ ggplot2::theme(legend.title = ggplot2::element_blank(),
+ axis.title.x = ggplot2::element_blank(),
+ axis.text.x = ggplot2::element_blank(),
+ axis.ticks.x = ggplot2::element_blank(),
+ axis.title.y = ggplot2::element_blank(),
+ axis.text.y = ggplot2::element_blank(),
+ axis.ticks.y = ggplot2::element_blank(),
+ panel.grid.major = ggplot2::element_blank(),
+ panel.grid.minor = ggplot2::element_blank(),
+ strip.text.x = ggplot2::element_text(size = 12, angle = 90, vjust = 0),
+ strip.text.y = ggplot2::element_text(size = 12, angle = 0, hjust = 0),
+ panel.spacing = ggplot2::unit(0.1, "lines"),
+ legend.position = "none")
+ return(plot)
+}
+
+
+plotCovariateBalanceScatterPlot <- function(balance, beforeLabel = "Before stratification", afterLabel = "After stratification") {
+ limits <- c(min(c(balance$absBeforeMatchingStdDiff, balance$absAfterMatchingStdDiff),
+ na.rm = TRUE),
+ max(c(balance$absBeforeMatchingStdDiff, balance$absAfterMatchingStdDiff),
+ na.rm = TRUE))
+ theme <- ggplot2::element_text(colour = "#000000", size = 12)
+ plot <- ggplot2::ggplot(balance, ggplot2::aes(x = absBeforeMatchingStdDiff, y = absAfterMatchingStdDiff)) +
+ ggplot2::geom_point(color = rgb(0, 0, 0.8, alpha = 0.3), shape = 16, size = 2) +
+ ggplot2::geom_abline(slope = 1, intercept = 0, linetype = "dashed") +
+ ggplot2::geom_hline(yintercept = 0) +
+ ggplot2::geom_vline(xintercept = 0) +
+ ggplot2::scale_x_continuous(beforeLabel, limits = limits) +
+ ggplot2::scale_y_continuous(afterLabel, limits = limits) +
+ ggplot2::theme(text = theme)
+
+ return(plot)
+}
+
+plotKaplanMeier <- function(kaplanMeier, targetName, comparatorName) {
+ data <- rbind(data.frame(time = kaplanMeier$time,
+ s = kaplanMeier$targetSurvival,
+ lower = kaplanMeier$targetSurvivalLb,
+ upper = kaplanMeier$targetSurvivalUb,
+ strata = paste0(" ", targetName, " ")),
+ data.frame(time = kaplanMeier$time,
+ s = kaplanMeier$comparatorSurvival,
+ lower = kaplanMeier$comparatorSurvivalLb,
+ upper = kaplanMeier$comparatorSurvivalUb,
+ strata = paste0(" ", comparatorName)))
+
+ xlims <- c(-max(data$time)/40, max(data$time))
+ ylims <- c(min(data$lower), 1)
+ xLabel <- "Time in days"
+ yLabel <- "Survival probability"
+ xBreaks <- kaplanMeier$time[!is.na(kaplanMeier$targetAtRisk)]
+ plot <- ggplot2::ggplot(data, ggplot2::aes(x = time,
+ y = s,
+ color = strata,
+ fill = strata,
+ ymin = lower,
+ ymax = upper)) +
+ ggplot2::geom_ribbon(color = rgb(0, 0, 0, alpha = 0)) +
+ ggplot2::geom_step(size = 1) +
+ ggplot2::scale_color_manual(values = c(rgb(0.8, 0, 0, alpha = 0.8),
+ rgb(0, 0, 0.8, alpha = 0.8))) +
+ ggplot2::scale_fill_manual(values = c(rgb(0.8, 0, 0, alpha = 0.3),
+ rgb(0, 0, 0.8, alpha = 0.3))) +
+ ggplot2::scale_x_continuous(xLabel, limits = xlims, breaks = xBreaks) +
+ ggplot2::scale_y_continuous(yLabel, limits = ylims) +
+ ggplot2::theme(legend.title = ggplot2::element_blank(),
+ legend.position = "top",
+ legend.key.size = ggplot2::unit(1, "lines"),
+ plot.title = ggplot2::element_text(hjust = 0.5)) +
+ ggplot2::theme(axis.title.y = ggplot2::element_text(vjust = -10))
+
+ targetAtRisk <- kaplanMeier$targetAtRisk[!is.na(kaplanMeier$targetAtRisk)]
+ comparatorAtRisk <- kaplanMeier$comparatorAtRisk[!is.na(kaplanMeier$comparatorAtRisk)]
+ labels <- data.frame(x = c(0, xBreaks, xBreaks),
+ y = as.factor(c("Number at risk",
+ rep(targetName, length(xBreaks)),
+ rep(comparatorName, length(xBreaks)))),
+ label = c("",
+ formatC(targetAtRisk, big.mark = ",", mode = "integer"),
+ formatC(comparatorAtRisk, big.mark = ",", mode = "integer")))
+ labels$y <- factor(labels$y, levels = c(comparatorName, targetName, "Number at risk"))
+ dataTable <- ggplot2::ggplot(labels, ggplot2::aes(x = x, y = y, label = label)) + ggplot2::geom_text(size = 3.5, vjust = 0.5) + ggplot2::scale_x_continuous(xLabel,
+ limits = xlims,
+ breaks = xBreaks) + ggplot2::theme(panel.grid.major = ggplot2::element_blank(),
+ panel.grid.minor = ggplot2::element_blank(),
+ legend.position = "none",
+ panel.border = ggplot2::element_blank(),
+ panel.background = ggplot2::element_blank(),
+ axis.text.x = ggplot2::element_text(color = "white"),
+ axis.title.x = ggplot2::element_text(color = "white"),
+ axis.title.y = ggplot2::element_blank(),
+ axis.ticks = ggplot2::element_line(color = "white"))
+ plots <- list(plot, dataTable)
+ grobs <- widths <- list()
+ for (i in 1:length(plots)) {
+ grobs[[i]] <- ggplot2::ggplotGrob(plots[[i]])
+ widths[[i]] <- grobs[[i]]$widths[2:5]
+ }
+ maxwidth <- do.call(grid::unit.pmax, widths)
+ for (i in 1:length(grobs)) {
+ grobs[[i]]$widths[2:5] <- as.list(maxwidth)
+ }
+ plot <- gridExtra::grid.arrange(grobs[[1]], grobs[[2]], heights = c(400, 100))
+ return(plot)
+}
+
+judgeCoverage <- function(values) {
+ ifelse(any(values < 0.9), "poor", "acceptable")
+}
+
+getCoverage <- function(controlResults) {
+ d <- rbind(data.frame(yGroup = "Uncalibrated",
+ logRr = controlResults$logRr,
+ seLogRr = controlResults$seLogRr,
+ ci95Lb = controlResults$ci95Lb,
+ ci95Ub = controlResults$ci95Ub,
+ trueRr = controlResults$effectSize),
+ data.frame(yGroup = "Calibrated",
+ logRr = controlResults$calibratedLogRr,
+ seLogRr = controlResults$calibratedSeLogRr,
+ ci95Lb = controlResults$calibratedCi95Lb,
+ ci95Ub = controlResults$calibratedCi95Ub,
+ trueRr = controlResults$effectSize))
+ d <- d[!is.na(d$logRr), ]
+ d <- d[!is.na(d$ci95Lb), ]
+ d <- d[!is.na(d$ci95Ub), ]
+ if (nrow(d) == 0) {
+ return(NULL)
+ }
+
+ d$Group <- as.factor(d$trueRr)
+ d$Significant <- d$ci95Lb > d$trueRr | d$ci95Ub < d$trueRr
+
+ temp2 <- aggregate(Significant ~ Group + yGroup, data = d, mean)
+ temp2$coverage <- (1 - temp2$Significant)
+
+ data.frame(true = temp2$Group, group = temp2$yGroup, coverage = temp2$coverage)
+}
+
+plotScatter <- function(controlResults) {
+ size <- 2
+ labelY <- 0.7
+ d <- rbind(data.frame(yGroup = "Uncalibrated",
+ logRr = controlResults$logRr,
+ seLogRr = controlResults$seLogRr,
+ ci95Lb = controlResults$ci95Lb,
+ ci95Ub = controlResults$ci95Ub,
+ trueRr = controlResults$effectSize),
+ data.frame(yGroup = "Calibrated",
+ logRr = controlResults$calibratedLogRr,
+ seLogRr = controlResults$calibratedSeLogRr,
+ ci95Lb = controlResults$calibratedCi95Lb,
+ ci95Ub = controlResults$calibratedCi95Ub,
+ trueRr = controlResults$effectSize))
+ d <- d[!is.na(d$logRr), ]
+ d <- d[!is.na(d$ci95Lb), ]
+ d <- d[!is.na(d$ci95Ub), ]
+ if (nrow(d) == 0) {
+ return(NULL)
+ }
+ d$Group <- as.factor(d$trueRr)
+ d$Significant <- d$ci95Lb > d$trueRr | d$ci95Ub < d$trueRr
+ temp1 <- aggregate(Significant ~ Group + yGroup, data = d, length)
+ temp2 <- aggregate(Significant ~ Group + yGroup, data = d, mean)
+ temp1$nLabel <- paste0(formatC(temp1$Significant, big.mark = ","), " estimates")
+ temp1$Significant <- NULL
+
+ temp2$meanLabel <- paste0(formatC(100 * (1 - temp2$Significant), digits = 1, format = "f"),
+ "% of CIs include ",
+ temp2$Group)
+ temp2$Significant <- NULL
+ dd <- merge(temp1, temp2)
+ dd$tes <- as.numeric(as.character(dd$Group))
+
+ breaks <- c(0.1, 0.25, 0.5, 1, 2, 4, 6, 8, 10)
+ theme <- ggplot2::element_text(colour = "#000000", size = 12)
+ themeRA <- ggplot2::element_text(colour = "#000000", size = 12, hjust = 1)
+ themeLA <- ggplot2::element_text(colour = "#000000", size = 12, hjust = 0)
+
+ d$Group <- paste("True hazard ratio =", d$Group)
+ dd$Group <- paste("True hazard ratio =", dd$Group)
+ alpha <- 1 - min(0.95 * (nrow(d)/nrow(dd)/50000)^0.1, 0.95)
+ plot <- ggplot2::ggplot(d, ggplot2::aes(x = logRr, y = seLogRr), environment = environment()) +
+ ggplot2::geom_vline(xintercept = log(breaks), colour = "#AAAAAA", lty = 1, size = 0.5) +
+ ggplot2::geom_abline(ggplot2::aes(intercept = (-log(tes))/qnorm(0.025), slope = 1/qnorm(0.025)),
+ colour = rgb(0.8, 0, 0),
+ linetype = "dashed",
+ size = 1,
+ alpha = 0.5,
+ data = dd) +
+ ggplot2::geom_abline(ggplot2::aes(intercept = (-log(tes))/qnorm(0.975), slope = 1/qnorm(0.975)),
+ colour = rgb(0.8, 0, 0),
+ linetype = "dashed",
+ size = 1,
+ alpha = 0.5,
+ data = dd) +
+ ggplot2::geom_point(size = size,
+ color = rgb(0, 0, 0, alpha = 0.05),
+ alpha = alpha,
+ shape = 16) +
+ ggplot2::geom_hline(yintercept = 0) +
+ ggplot2::geom_label(x = log(0.15),
+ y = 0.9,
+ alpha = 1,
+ hjust = "left",
+ ggplot2::aes(label = nLabel),
+ size = 5,
+ data = dd) +
+ ggplot2::geom_label(x = log(0.15),
+ y = labelY,
+ alpha = 1,
+ hjust = "left",
+ ggplot2::aes(label = meanLabel),
+ size = 5,
+ data = dd) +
+ ggplot2::scale_x_continuous("Hazard ratio",
+ limits = log(c(0.1, 10)),
+ breaks = log(breaks),
+ labels = breaks) +
+ ggplot2::scale_y_continuous("Standard Error", limits = c(0, 1)) +
+ ggplot2::facet_grid(yGroup ~ Group) +
+ ggplot2::theme(panel.grid.minor = ggplot2::element_blank(),
+ panel.background = ggplot2::element_blank(),
+ panel.grid.major = ggplot2::element_blank(),
+ axis.ticks = ggplot2::element_blank(),
+ axis.text.y = themeRA,
+ axis.text.x = theme,
+ axis.title = theme,
+ legend.key = ggplot2::element_blank(),
+ strip.text.x = theme,
+ strip.text.y = theme,
+ strip.background = ggplot2::element_blank(),
+ legend.position = "none")
+
+ return(plot)
+}
+
+plotLargeScatter <- function(d, xLabel) {
+ d$Significant <- d$ci95Lb > 1 | d$ci95Ub < 1
+
+ oneRow <- data.frame(nLabel = paste0(formatC(nrow(d), big.mark = ","), " estimates"),
+ meanLabel = paste0(formatC(100 *
+ mean(!d$Significant, na.rm = TRUE), digits = 1, format = "f"), "% of CIs includes 1"))
+
+ breaks <- c(0.1, 0.25, 0.5, 1, 2, 4, 6, 8, 10)
+ theme <- ggplot2::element_text(colour = "#000000", size = 12)
+ themeRA <- ggplot2::element_text(colour = "#000000", size = 12, hjust = 1)
+ themeLA <- ggplot2::element_text(colour = "#000000", size = 12, hjust = 0)
+
+ alpha <- 1 - min(0.95 * (nrow(d)/50000)^0.1, 0.95)
+ plot <- ggplot2::ggplot(d, ggplot2::aes(x = logRr, y = seLogRr)) +
+ ggplot2::geom_vline(xintercept = log(breaks), colour = "#AAAAAA", lty = 1, size = 0.5) +
+ ggplot2::geom_abline(ggplot2::aes(intercept = 0, slope = 1/qnorm(0.025)),
+ colour = rgb(0.8, 0, 0),
+ linetype = "dashed",
+ size = 1,
+ alpha = 0.5) +
+ ggplot2::geom_abline(ggplot2::aes(intercept = 0, slope = 1/qnorm(0.975)),
+ colour = rgb(0.8, 0, 0),
+ linetype = "dashed",
+ size = 1,
+ alpha = 0.5) +
+ ggplot2::geom_point(size = 2, color = rgb(0, 0, 0, alpha = 0.05), alpha = alpha, shape = 16) +
+ ggplot2::geom_hline(yintercept = 0) +
+ ggplot2::geom_label(x = log(0.11),
+ y = 1,
+ alpha = 1,
+ hjust = "left",
+ ggplot2::aes(label = nLabel),
+ size = 5,
+ data = oneRow) +
+ ggplot2::geom_label(x = log(0.11),
+ y = 0.935,
+ alpha = 1,
+ hjust = "left",
+ ggplot2::aes(label = meanLabel),
+ size = 5,
+ data = oneRow) +
+ ggplot2::scale_x_continuous(xLabel, limits = log(c(0.1,
+ 10)), breaks = log(breaks), labels = breaks) +
+ ggplot2::scale_y_continuous("Standard Error", limits = c(0, 1)) +
+ ggplot2::theme(panel.grid.minor = ggplot2::element_blank(),
+ panel.background = ggplot2::element_blank(),
+ panel.grid.major = ggplot2::element_blank(),
+ axis.ticks = ggplot2::element_blank(),
+ axis.text.y = themeRA,
+ axis.text.x = theme,
+ axis.title = theme,
+ legend.key = ggplot2::element_blank(),
+ strip.text.x = theme,
+ strip.background = ggplot2::element_blank(),
+ legend.position = "none")
+ return(plot)
+}
+
+
+
+drawAttritionDiagram <- function(attrition,
+ targetLabel = "Target",
+ comparatorLabel = "Comparator") {
+ addStep <- function(data, attrition, row) {
+ label <- paste(strwrap(as.character(attrition$description[row]), width = 30), collapse = "\n")
+ data$leftBoxText[length(data$leftBoxText) + 1] <- label
+ data$rightBoxText[length(data$rightBoxText) + 1] <- paste(targetLabel,
+ ": n = ",
+ data$currentTarget - attrition$targetPersons[row],
+ "\n",
+ comparatorLabel,
+ ": n = ",
+ data$currentComparator - attrition$comparatorPersons[row],
+ sep = "")
+ data$currentTarget <- attrition$targetPersons[row]
+ data$currentComparator <- attrition$comparatorPersons[row]
+ return(data)
+ }
+ data <- list(leftBoxText = c(paste("Exposed:\n",
+ targetLabel,
+ ": n = ",
+ attrition$targetPersons[1],
+ "\n",
+ comparatorLabel,
+ ": n = ",
+ attrition$comparatorPersons[1],
+ sep = "")), rightBoxText = c(""), currentTarget = attrition$targetPersons[1], currentComparator = attrition$comparatorPersons[1])
+ for (i in 2:nrow(attrition)) {
+ data <- addStep(data, attrition, i)
+ }
+
+
+ data$leftBoxText[length(data$leftBoxText) + 1] <- paste("Study population:\n",
+ targetLabel,
+ ": n = ",
+ data$currentTarget,
+ "\n",
+ comparatorLabel,
+ ": n = ",
+ data$currentComparator,
+ sep = "")
+ leftBoxText <- data$leftBoxText
+ rightBoxText <- data$rightBoxText
+ nSteps <- length(leftBoxText)
+
+ boxHeight <- (1/nSteps) - 0.03
+ boxWidth <- 0.45
+ shadowOffset <- 0.01
+ arrowLength <- 0.01
+ x <- function(x) {
+ return(0.25 + ((x - 1)/2))
+ }
+ y <- function(y) {
+ return(1 - (y - 0.5) * (1/nSteps))
+ }
+
+ downArrow <- function(p, x1, y1, x2, y2) {
+ p <- p + ggplot2::geom_segment(ggplot2::aes_string(x = x1, y = y1, xend = x2, yend = y2))
+ p <- p + ggplot2::geom_segment(ggplot2::aes_string(x = x2,
+ y = y2,
+ xend = x2 + arrowLength,
+ yend = y2 + arrowLength))
+ p <- p + ggplot2::geom_segment(ggplot2::aes_string(x = x2,
+ y = y2,
+ xend = x2 - arrowLength,
+ yend = y2 + arrowLength))
+ return(p)
+ }
+ rightArrow <- function(p, x1, y1, x2, y2) {
+ p <- p + ggplot2::geom_segment(ggplot2::aes_string(x = x1, y = y1, xend = x2, yend = y2))
+ p <- p + ggplot2::geom_segment(ggplot2::aes_string(x = x2,
+ y = y2,
+ xend = x2 - arrowLength,
+ yend = y2 + arrowLength))
+ p <- p + ggplot2::geom_segment(ggplot2::aes_string(x = x2,
+ y = y2,
+ xend = x2 - arrowLength,
+ yend = y2 - arrowLength))
+ return(p)
+ }
+ box <- function(p, x, y) {
+ p <- p + ggplot2::geom_rect(ggplot2::aes_string(xmin = x - (boxWidth/2) + shadowOffset,
+ ymin = y - (boxHeight/2) - shadowOffset,
+ xmax = x + (boxWidth/2) + shadowOffset,
+ ymax = y + (boxHeight/2) - shadowOffset), fill = rgb(0,
+ 0,
+ 0,
+ alpha = 0.2))
+ p <- p + ggplot2::geom_rect(ggplot2::aes_string(xmin = x - (boxWidth/2),
+ ymin = y - (boxHeight/2),
+ xmax = x + (boxWidth/2),
+ ymax = y + (boxHeight/2)), fill = rgb(0.94,
+ 0.94,
+ 0.94), color = "black")
+ return(p)
+ }
+ label <- function(p, x, y, text, hjust = 0) {
+ p <- p + ggplot2::geom_text(ggplot2::aes_string(x = x, y = y, label = paste("\"", text, "\"",
+ sep = "")),
+ hjust = hjust,
+ size = 3.7)
+ return(p)
+ }
+
+ p <- ggplot2::ggplot()
+ for (i in 2:nSteps - 1) {
+ p <- downArrow(p, x(1), y(i) - (boxHeight/2), x(1), y(i + 1) + (boxHeight/2))
+ p <- label(p, x(1) + 0.02, y(i + 0.5), "Y")
+ }
+ for (i in 2:(nSteps - 1)) {
+ p <- rightArrow(p, x(1) + boxWidth/2, y(i), x(2) - boxWidth/2, y(i))
+ p <- label(p, x(1.5), y(i) - 0.02, "N", 0.5)
+ }
+ for (i in 1:nSteps) {
+ p <- box(p, x(1), y(i))
+ }
+ for (i in 2:(nSteps - 1)) {
+ p <- box(p, x(2), y(i))
+ }
+ for (i in 1:nSteps) {
+ p <- label(p, x(1) - boxWidth/2 + 0.02, y(i), text = leftBoxText[i])
+ }
+ for (i in 2:(nSteps - 1)) {
+ p <- label(p, x(2) - boxWidth/2 + 0.02, y(i), text = rightBoxText[i])
+ }
+ p <- p + ggplot2::theme(legend.position = "none",
+ plot.background = ggplot2::element_blank(),
+ panel.grid.major = ggplot2::element_blank(),
+ panel.grid.minor = ggplot2::element_blank(),
+ panel.border = ggplot2::element_blank(),
+ panel.background = ggplot2::element_blank(),
+ axis.text = ggplot2::element_blank(),
+ axis.title = ggplot2::element_blank(),
+ axis.ticks = ggplot2::element_blank())
+
+ return(p)
+}
+
+judgeHazardRatio <- function(hrLower, hrUpper) {
+ nonZeroHazardRatio(hrLower, hrUpper, c("lower", "higher", "similar"))
+}
+
+nonZeroHazardRatio <- function(hrLower, hrUpper, terms) {
+ if (hrUpper < 1) {
+ return(terms[1])
+ } else if (hrLower > 1) {
+ return(terms[2])
+ } else {
+ return(terms[3])
+ }
+}
+
+judgeEffectiveness <- function(hrLower, hrUpper) {
+ nonZeroHazardRatio(hrLower, hrUpper, c("less", "more", "as"))
+}
+
+prettyHr <- function(x) {
+ result <- sprintf("%.2f", x)
+ result[is.na(x) | x > 100] <- "NA"
+ return(result)
+}
+
+goodPropensityScore <- function(value) {
+ return(value > 1)
+}
+
+goodSystematicBias <- function(value) {
+ return(value > 1)
+}
+
+judgePropensityScore <- function(ps, bias) {
+ paste0(" ",
+ ifelse(goodPropensityScore(ps), "substantial", "inadequate"),
+ " control of measured confounding by propensity score adjustment, and ",
+ ifelse(goodSystematicBias(bias), "minimal", "non-negligible"),
+ " residual systematic bias through negative and positive control experiments",
+ ifelse(goodPropensityScore(ps) && goodSystematicBias(bias),
+ ", lending credibility to our effect estimates",
+ ""))
+}
+
+uncapitalize <- function(x) {
+ if (length(x) > 1) {
+ x <- x[1]
+ }
+ terms <- strsplit(x, split = " & ")
+ terms <- sapply(terms, FUN = function(y) {
+ substr(y, 1, 1) <- tolower(substr(y, 1, 1))
+ y <- gsub("aCE", "ACE", y)
+ y <- gsub("CCB)", "CCBs)", y)
+ y
+ })
+ result <- paste(terms, collapse = " and ")
+ names(result) <- NULL
+ result
+}
+
+capitalize <- function(x) {
+ substr(x, 1, 1) <- toupper(substr(x, 1, 1))
+ x
+}
+
+createDocument <- function(targetId,
+ comparatorId,
+ outcomeId,
+ databaseId,
+ indicationId,
+ outputFile,
+ template = "template.Rnw",
+ workingDirectory = "temp",
+ emptyWorkingDirectory = TRUE) {
+
+ if (missing(outputFile)) {
+ stop("Must provide an output file name")
+ }
+
+ currentDirectory <- getwd()
+ on.exit(setwd(currentDirectory))
+
+ input <- file(template, "r")
+
+ name <- paste0("paper_", targetId, "_", comparatorId, "_", outcomeId, "_", databaseId)
+
+ if (!dir.exists(workingDirectory)) {
+ dir.create(workingDirectory)
+ }
+
+ workingDirectory <- file.path(workingDirectory, name)
+
+ if (!dir.exists(workingDirectory)) {
+ dir.create(workingDirectory)
+ }
+
+ if (is.null(setwd(workingDirectory))) {
+ stop(paste0("Unable to change directory into: ", workingDirectory))
+ }
+
+ system(paste0("cp ", file.path(currentDirectory, "pnas-new.cls"), " ."))
+ system(paste0("cp ", file.path(currentDirectory, "widetext.sty"), " ."))
+ system(paste0("cp ", file.path(currentDirectory, "pnasresearcharticle.sty"), " ."))
+ system(paste0("cp ", file.path(currentDirectory, "Sweave.sty"), " ."))
+
+ texName <- paste0(name, ".Rnw")
+ output <- file(texName, "w")
+
+ while (TRUE) {
+ line <- readLines(input, n = 1)
+ if (length(line) == 0) {
+ break
+ }
+ line <- sub("DATABASE_ID_TAG", paste0("\"", databaseId, "\""), line)
+ line <- sub("TARGET_ID_TAG", targetId, line)
+ line <- sub("COMPARATOR_ID_TAG", comparatorId, line)
+ line <- sub("OUTCOME_ID_TAG", outcomeId, line)
+ line <- sub("INDICATION_ID_TAG", indicationId, line)
+ line <- sub("CURRENT_DIRECTORY", currentDirectory, line)
+ writeLines(line, output)
+ }
+ close(input)
+ close(output)
+
+ Sweave(texName)
+ system(paste0("pdflatex ", name))
+ system(paste0("pdflatex ", name))
+
+ # Save result
+ workingName <- file.path(workingDirectory, name)
+ workingName <- paste0(workingName, ".pdf")
+
+ setwd(currentDirectory)
+
+ system(paste0("cp ", workingName, " ", outputFile))
+
+ if (emptyWorkingDirectory) {
+ # deleteName = file.path(workingDirectory, "*")
+ # system(paste0("rm ", deleteName))
+ unlink(workingDirectory, recursive = TRUE)
+ }
+
+ invisible(outputFile)
+}
+
diff --git a/LegendMedCentral/Sweave.sty b/LegendMedCentral/Sweave.sty
new file mode 100644
index 00000000..45db4057
--- /dev/null
+++ b/LegendMedCentral/Sweave.sty
@@ -0,0 +1,39 @@
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{Sweave}{}
+
+\RequirePackage{ifthen}
+\newboolean{Sweave@gin}
+\setboolean{Sweave@gin}{true}
+\newboolean{Sweave@ae}
+\setboolean{Sweave@ae}{true}
+
+\DeclareOption{nogin}{\setboolean{Sweave@gin}{false}}
+\DeclareOption{noae}{\setboolean{Sweave@ae}{false}}
+\ProcessOptions
+
+\RequirePackage{graphicx,fancyvrb}
+\IfFileExists{upquote.sty}{\RequirePackage{upquote}}{}
+
+\ifthenelse{\boolean{Sweave@gin}}{\setkeys{Gin}{width=0.8\textwidth}}{}%
+\ifthenelse{\boolean{Sweave@ae}}{%
+ \RequirePackage[T1]{fontenc}
+ \RequirePackage{ae}
+}{}%
+
+\DefineVerbatimEnvironment{Sinput}{Verbatim}{fontshape=sl}
+\DefineVerbatimEnvironment{Soutput}{Verbatim}{}
+\DefineVerbatimEnvironment{Scode}{Verbatim}{fontshape=sl}
+
+\newenvironment{Schunk}{}{}
+
+\newcommand{\Sconcordance}[1]{%
+ \ifx\pdfoutput\undefined%
+ \csname newcount\endcsname\pdfoutput\fi%
+ \ifcase\pdfoutput\special{#1}%
+ \else%
+ \begingroup%
+ \pdfcompresslevel=0%
+ \immediate\pdfobj stream{#1}%
+ \pdfcatalog{/SweaveConcordance \the\pdflastobj\space 0 R}%
+ \endgroup%
+ \fi}
diff --git a/LegendMedCentral/Table1Specs.csv b/LegendMedCentral/Table1Specs.csv
new file mode 100644
index 00000000..6389f2be
--- /dev/null
+++ b/LegendMedCentral/Table1Specs.csv
@@ -0,0 +1,9 @@
+label,analysisId,covariateIds
+Age group,3,
+Gender: female,1,8532001
+Race,4,
+Ethnicity,5,
+Medical history: General,210,4006969210;438409210;4212540210;255573210;201606210;4182210210;440383210;201820210;318800210;192671210;439727210;432867210;316866210;4104000210;433736210;80180210;255848210;140168210;4030518210;80809210;435783210;4279309210;81893210;81902210;197494210;4134440210
+Medical history: Cardiovascular disease,210,313217210;381591210;317576210;321588210;316139210;4185932210;321052210;440417210;444247210
+Medical history: Neoplasms,210,4044013210;432571210;40481902210;443392210;4112853210;4180790210;443388210;197508210;200962210
+Medication use,410,21601782410;21602796410;21604686410;21604389410;21603932410;21601387410;21602028410;21600960410;21601664410;21601744410;21601461410;21600046410;21603248410;21600712410;21603890410;21601853410;21604254410;21604489410;21604752410
diff --git a/LegendMedCentral/bibliography.bib b/LegendMedCentral/bibliography.bib
new file mode 100644
index 00000000..8bb87f7e
--- /dev/null
+++ b/LegendMedCentral/bibliography.bib
@@ -0,0 +1,419 @@
+% 27592566
+@Article{pmid27592566,
+ Author="Schuemie, M. J. and Hripcsak, G. and Ryan, P. B. and Madigan, D. and Suchard, M. A. ",
+ Title="{{R}obust empirical calibration of p-values using observational data}",
+ Journal="Stat Med",
+ Year="2016",
+ Volume="35",
+ Number="22",
+ Pages="3883--3888",
+ Month="Sep"
+}
+
+% 23900808
+@Article{pmid23900808,
+ Author="Schuemie, M. J. and Ryan, P. B. and DuMouchel, W. and Suchard, M. A. and Madigan, D. ",
+ Title="{{I}nterpreting observational studies: why empirical calibration is needed to correct p-values}",
+ Journal="Stat Med",
+ Year="2014",
+ Volume="33",
+ Number="2",
+ Pages="209--218",
+ Month="Jan"
+}
+
+% 27993747
+@Article{pmid27993747,
+ Author="Voss, E. A. and Boyce, R. D. and Ryan, P. B. and van der Lei, J. and Rijnbeek, P. R. and Schuemie, M. J. ",
+ Title="{{A}ccuracy of an {A}utomated {K}nowledge {B}ase for {I}dentifying {D}rug {A}dverse {R}eactions}",
+ Journal="J Biomed Inform",
+ Year="2016",
+ Month="Dec"
+}
+
+% 16091054
+@Article{pmid16091054,
+ Author="Tata, L. J. and Fortun, P. J. and Hubbard, R. B. and Smeeth, L. and Hawkey, C. J. and Smith, C. J. and Whitaker, H. J. and Farrington, C. P. and Card, T. R. and West, J. ",
+ Title="{{D}oes concurrent prescription of selective serotonin reuptake inhibitors and non-steroidal anti-inflammatory drugs substantially increase the risk of upper gastrointestinal bleeding?}",
+ Journal="Aliment. Pharmacol. Ther.",
+ Year="2005",
+ Volume="22",
+ Number="3",
+ Pages="175--181",
+ Month="Aug"
+}
+
+5821
+@Article{pmid27695821,
+ Author="Graham, D. J. and Reichman, M. E. and Wernecke, M. and Hsueh, Y. H. and Izem, R. and Southworth, M. R. and Wei, Y. and Liao, J. and Goulding, M. R. and Mott, K. and Chillarige, Y. and MaCurdy, T. E. and Worrall, C. and Kelman, J. A. ",
+ Title="{{S}troke, {B}leeding, and {M}ortality {R}isks in {E}lderly {M}edicare {B}eneficiaries {T}reated {W}ith {D}abigatran or {R}ivaroxaban for {N}onvalvular {A}trial {F}ibrillation}",
+ Journal="JAMA Intern Med",
+ Year="2016",
+ Volume="176",
+ Number="11",
+ Pages="1662--1671",
+ Month="Nov"
+}
+
+% 23484796
+@Article{pmid23484796,
+ Author="Southworth, M. R. and Reichman, M. E. and Unger, E. F. ",
+ Title="{{D}abigatran and postmarketing reports of bleeding}",
+ Journal="N. Engl. J. Med.",
+ Year="2013",
+ Volume="368",
+ Number="14",
+ Pages="1272--1274",
+ Month="Apr"
+}
+
+% 25005708
+@Article{pmid25005708,
+ Author="Noren, G. N. and Caster, O. and Juhlin, K. and Lindquist, M. ",
+ Title="{{Z}oo or savannah? {C}hoice of training ground for evidence-based pharmacovigilance}",
+ Journal="Drug Saf",
+ Year="2014",
+ Volume="37",
+ Number="9",
+ Pages="655--659",
+ Month="Sep"
+}
+
+@article{tibshirani1996regression,
+ title={Regression shrinkage and selection via the lasso},
+ author={Tibshirani, Robert},
+ journal={Journal of the Royal Statistical Society. Series B (Methodological)},
+ pages={267--288},
+ year={1996},
+ publisher={JSTOR}
+}
+
+@article{Suchard2013,
+ author = {Suchard, Marc A. and Simpson, Shawn E. and Zorych, Ivan and Ryan, Patrick and Madigan, David},
+ title = {Massive Parallelization of Serial Inference Algorithms for a Complex Generalized Linear Model},
+ journal = {ACM Trans. Model. Comput. Simul.},
+ issue_date = {January 2013},
+ volume = {23},
+ number = {1},
+ month = jan,
+ year = {2013},
+ issn = {1049-3301},
+ pages = {10:1--10:17},
+ articleno = {10},
+ numpages = {17},
+ url = {http://doi.acm.org/10.1145/2414416.2414791},
+ doi = {10.1145/2414416.2414791},
+ acmid = {2414791},
+ publisher = {ACM},
+ address = {New York, NY, USA},
+ keywords = {Optimization, big data, parallel processing},
+}
+
+
+@article{jamaNegControls,
+author = {Arnold, BF and Ercumen, A},
+title = {Negative control outcomes: A tool to detect bias in randomized trials},
+journal = {JAMA},
+volume = {316},
+number = {24},
+pages = {2597-2598},
+year = {2016},
+doi = {10.1001/jama.2016.17700},
+URL = { + http://dx.doi.org/10.1001/jama.2016.17700},
+eprint = {/data/journals/jama/935941/jvp160163.pdf}
+}
+
+% 27993747
+@Article{pmid27993747,
+ Author="Voss, E. A. and Boyce, R. D. and Ryan, P. B. and van der Lei, J. and Rijnbeek, P. R. and Schuemie, M. J. ",
+ Title="{{A}ccuracy of an {A}utomated {K}nowledge {B}ase for {I}dentifying {D}rug {A}dverse {R}eactions}",
+ Journal="J Biomed Inform",
+ Year="2016",
+ Month="Dec"
+}
+
+
+% 20335814
+@Article{pmid20335814,
+ Author="Lipsitch, M. and Tchetgen Tchetgen, E. and Cohen, T. ",
+ Title="{{N}egative controls: a tool for detecting confounding and bias in observational studies}",
+ Journal="Epidemiology",
+ Year="2010",
+ Volume="21",
+ Number="3",
+ Pages="383--388",
+ Month="May"
+}
+
+% 27182642
+@Article{pmid27182642,
+ Author="Arnold, B. F. and Ercumen, A. and Benjamin-Chung, J. and Colford, J. M. ",
+ Title="{{B}rief {R}eport: {N}egative {C}ontrols to {D}etect {S}election {B}ias and {M}easurement {B}ias in {E}pidemiologic {S}tudies}",
+ Journal="Epidemiology",
+ Year="2016",
+ Volume="27",
+ Number="5",
+ Pages="637--641",
+ Month="Sep"
+}
+
+@Article{pmid23321761,
+ Author="Prasad, V. and Jena, A. B. ",
+ Title="{{P}respecified falsification end points: can they validate true observational associations?}",
+ Journal="JAMA",
+ Year="2013",
+ Volume="309",
+ Number="3",
+ Pages="241--242",
+ Month="Jan"
+}
+
+% 18208871
+@Article{pmid18208871,
+ Author="Zaadstra, B. M. and Chorus, A. M. and van Buuren, S. and Kalsbeek, H. and van Noort, J. M. ",
+ Title="{{S}elective association of multiple sclerosis with infectious mononucleosis}",
+ Journal="Mult. Scler.",
+ Year="2008",
+ Volume="14",
+ Number="3",
+ Pages="307--313",
+ Month="Apr"
+}
+
+% 28430842
+@Article{pmid28430842,
+ Author="Flanders, W. D. and Strickland, M. J. and Klein, M. ",
+ Title="{{A} {N}ew {M}ethod for {P}artial {C}orrection of {R}esidual {C}onfounding in {T}ime-{S}eries and {O}ther {O}bservational {S}tudies}",
+ Journal="Am. J. Epidemiol.",
+ Year="2017",
+ Pages="1--9",
+ Month="Apr"
+}
+
+% 26050254
+@Article{pmid26050254,
+ Author="Herrett, E. and Gallagher, A. M. and Bhaskaran, K. and Forbes, H. and Mathur, R. and van Staa, T. and Smeeth, L. ",
+ Title="{{D}ata {R}esource {P}rofile: {C}linical {P}ractice {R}esearch {D}atalink ({C}{P}{R}{D})}",
+ Journal="Int J Epidemiol",
+ Year="2015",
+ Volume="44",
+ Number="3",
+ Pages="827--836",
+ Month="Jun"
+}
+
+% 18092305
+@Article{pmid18092305,
+ Author="van Staa, T. P. and Parkinson, J. ",
+ Title="{{R}esponse to: {V}alidation studies of the health improvement network ({T}{H}{I}{N}) database for pharmacoepidemiology research by {L}ewis et al}",
+ Journal="Pharmacoepidemiol Drug Saf",
+ Year="2008",
+ Volume="17",
+ Number="1",
+ Pages="103--104",
+ Month="Jan"
+}
+
+% 28027378
+@Article{pmid28027378,
+ Author="Arnold, B. F. and Ercumen, A. ",
+ Title="{{N}egative {C}ontrol {O}utcomes: {A} {T}ool to {D}etect {B}ias in {R}andomized {T}rials}",
+ Journal="JAMA",
+ Year="2016",
+ Volume="316",
+ Number="24",
+ Pages="2597--2598",
+ Month="12"
+}
+
+% 27592566
+@Article{pmid27592566,
+ Author="Schuemie, M. J. and Hripcsak, G. and Ryan, P. B. and Madigan, D. and Suchard, M. A. ",
+ Title="{{R}obust empirical calibration of p-values using observational data}",
+ Journal="Stat Med",
+ Year="2016",
+ Volume="35",
+ Number="22",
+ Pages="3883--3888",
+ Month="Sep"
+}
+
+% 27182642
+@Article{pmid27182642,
+ Author="Arnold, B. F. and Ercumen, A. and Benjamin-Chung, J. and Colford, J. M. ",
+ Title="{{B}rief {R}eport: {N}egative {C}ontrols to {D}etect {S}election {B}ias and {M}easurement {B}ias in {E}pidemiologic {S}tudies}",
+ Journal="Epidemiology",
+ Year="2016",
+ Volume="27",
+ Number="5",
+ Pages="637--641",
+ Month="Sep"
+}
+
+% 27029385
+@Article{pmid27029385,
+ Author="Tuccori, M. and Filion, K. B. and Yin, H. and Yu, O. H. and Platt, R. W. and Azoulay, L. ",
+ Title="{{P}ioglitazone use and risk of bladder cancer: population based cohort study}",
+ Journal="BMJ",
+ Year="2016",
+ Volume="352",
+ Pages="i1541",
+ Month="Mar"
+}
+
+% 26846201
+@Article{pmid26846201,
+ Author="Alves, C. and Penedones, A. and Mendes, D. and Batel Marques, F. ",
+ Title="{{A} systematic review and meta-analysis of the association between systemic fluoroquinolones and retinal detachment}",
+ Journal="Acta Ophthalmol",
+ Year="2016",
+ Volume="94",
+ Number="5",
+ Pages="e251--259",
+ Month="Aug"
+}
+
+% 25598384
+@Article{pmid25598384,
+ Author="Dusetzina, S. B. and Brookhart, M. A. and Maciejewski, M. L. ",
+ Title="{{C}ontrol {O}utcomes and {E}xposures for {I}mproving {I}nternal {V}alidity of {N}onrandomized {S}tudies}",
+ Journal="Health Serv Res",
+ Year="2015",
+ Volume="50",
+ Number="5",
+ Pages="1432--1451",
+ Month="Oct"
+}
+
+% 25525200
+@Article{pmid25525200,
+ Author="Chui, C. S. and Wong, I. C. and Wong, L. Y. and Chan, E. W. ",
+ Title="{{A}ssociation between oral fluoroquinolone use and the development of retinal detachment: a systematic review and meta-analysis of observational studies}",
+ Journal="J. Antimicrob. Chemother.",
+ Year="2015",
+ Volume="70",
+ Number="4",
+ Pages="971--978",
+ Month="Apr"
+}
+
+% 24833754
+@Article{pmid24833754,
+ Author="Chui, C. S. and Man, K. K. and Cheng, C. L. and Chan, E. W. and Lau, W. C. and Cheng, V. C. and Wong, D. S. and Yang Kao, Y. H. and Wong, I. C. ",
+ Title="{{A}n investigation of the potential association between retinal detachment and oral fluoroquinolones: a self-controlled case series study}",
+ Journal="J. Antimicrob. Chemother.",
+ Year="2014",
+ Volume="69",
+ Number="9",
+ Pages="2563--2567",
+ Month="Sep"
+}
+
+% 24526267
+@Article{pmid24526267,
+ Author="Fife, D. and Zhu, V. and Voss, E. and Levy-Clarke, G. and Ryan, P. ",
+ Title="{{E}xposure to oral fluoroquinolones and the risk of retinal detachment: retrospective analyses of two large healthcare databases}",
+ Journal="Drug Saf",
+ Year="2014",
+ Volume="37",
+ Number="3",
+ Pages="171--182",
+ Month="Mar"
+}
+
+% 24363326
+@Article{pmid24363326,
+ Author="Tchetgen Tchetgen, E. ",
+ Title="{{T}he control outcome calibration approach for causal inference with unobserved confounding}",
+ Journal="Am. J. Epidemiol.",
+ Year="2014",
+ Volume="179",
+ Number="5",
+ Pages="633--640",
+ Month="Mar"
+}
+
+% 24281462
+@Article{pmid24281462,
+ Author="Pasternak, B. and Svanstrom, H. and Melbye, M. and Hviid, A. ",
+ Title="{{A}ssociation between oral fluoroquinolone use and retinal detachment}",
+ Journal="JAMA",
+ Year="2013",
+ Volume="310",
+ Number="20",
+ Pages="2184--2190",
+ Month="Nov"
+}
+
+% 23900808
+@Article{pmid23900808,
+ Author="Schuemie, M. J. and Ryan, P. B. and DuMouchel, W. and Suchard, M. A. and Madigan, D. ",
+ Title="{{I}nterpreting observational studies: why empirical calibration is needed to correct p-values}",
+ Journal="Stat Med",
+ Year="2014",
+ Volume="33",
+ Number="2",
+ Pages="209--218",
+ Month="Jan"
+}
+
+% 23321761
+@Article{pmid23321761,
+ Author="Prasad, V. and Jena, A. B. ",
+ Title="{{P}respecified falsification end points: can they validate true observational associations?}",
+ Journal="JAMA",
+ Year="2013",
+ Volume="309",
+ Number="3",
+ Pages="241--242",
+ Month="Jan"
+}
+
+% 22574756
+@Article{pmid22574756,
+ Author="Wei, L. and MacDonald, T. M. and Mackenzie, I. S. ",
+ Title="{{P}ioglitazone and bladder cancer: a propensity score matched cohort study}",
+ Journal="Br J Clin Pharmacol",
+ Year="2013",
+ Volume="75",
+ Number="1",
+ Pages="254--259",
+ Month="Jan"
+}
+
+% 22474205
+@Article{pmid22474205,
+ Author="Etminan, M. and Forooghian, F. and Brophy, J. M. and Bird, S. T. and Maberley, D. ",
+ Title="{{O}ral fluoroquinolones and the risk of retinal detachment}",
+ Journal="JAMA",
+ Year="2012",
+ Volume="307",
+ Number="13",
+ Pages="1414--1419",
+ Month="Apr"
+}
+
+% 20335814
+@Article{pmid20335814,
+ Author="Lipsitch, M. and Tchetgen Tchetgen, E. and Cohen, T. ",
+ Title="{{N}egative controls: a tool for detecting confounding and bias in observational studies}",
+ Journal="Epidemiology",
+ Year="2010",
+ Volume="21",
+ Number="3",
+ Pages="383--388",
+ Month="May"
+}
+
+% 24166219
+@Article{pmid24166219,
+ Author="Overhage, J. M. and Ryan, P. B. and Schuemie, M. J. and Stang, P. E. ",
+ Title="{{D}esideratum for evidence based epidemiology}",
+ Journal="Drug Saf",
+ Year="2013",
+ Volume="36 Suppl 1",
+ Pages="5--14",
+ Month="Oct"
+}
+
+
diff --git a/LegendMedCentral/blank_template.tex b/LegendMedCentral/blank_template.tex
new file mode 100644
index 00000000..189b4cf4
--- /dev/null
+++ b/LegendMedCentral/blank_template.tex
@@ -0,0 +1,131 @@
+\documentclass[$if(papersize)$$papersize$paper,$else$letter,$endif$$if(fontsize)$$fontsize$,$else$9pt,$endif$$if(one_column)$$if(lineno)$lineno,$endif$$else$twocolumn,$endif$$if(one_sided)$$else$twoside,$endif$printwatermark=$if(watermark)$$watermark$$else$false$endif$]{pnas-markdown}
+
+%% Some pieces required from the pandoc template
+\providecommand{\tightlist}{%
+ \setlength{\itemsep}{0pt}\setlength{\parskip}{0pt}}
+
+% Use the lineno option to display guide line numbers if required.
+% Note that the use of elements such as single-column equations
+% may affect the guide line number alignment.
+
+\usepackage[T1]{fontenc}
+\usepackage[utf8]{inputenc}
+$if(tables)$
+\usepackage{longtable}
+$endif$
+
+% The geometry package layout settings need to be set here...
+\geometry{layoutsize={0.95588\paperwidth,0.98864\paperheight},%
+ layouthoffset=0.02206\paperwidth,%
+ layoutvoffset=0.00568\paperheight}
+
+$if(headercolor)$
+\definecolor{pinpblue}{HTML}{$headercolor$}
+$else$
+\definecolor{pinpblue}{HTML}{EB6622}
+$endif$
+$if(linkcolor)$
+\definecolor{pnasbluetext}{HTML}{$linkcolor$}
+$else$
+\definecolor{pnasbluetext}{RGB}{101,0,0} %
+$endif$
+
+
+$for(header-includes)$
+$header-includes$
+$endfor$
+
+\title{$title$}
+
+$for(author)$
+\author[$author.affiliation$]{$author.name$}
+$endfor$
+
+$for(address)$
+ \affil[$address.code$]{$address.address$}
+$endfor$
+
+$if(numbersections)$
+\setcounter{secnumdepth}{$if(secnumdepth)$$secnumdepth$$else$5$endif$}
+$else$
+\setcounter{secnumdepth}{0}
+$endif$
+
+% Please give the surname of the lead author for the running footer
+\leadauthor{$lead_author_surname$}
+
+% Keywords are not mandatory, but authors are strongly encouraged to provide them. If provided, please include two to five keywords, separated by the pipe symbol, e.g:
+$if(keywords)$ \keywords{ $for(keywords)$ $keywords$ $sep$| $endfor$ } $endif$
+
+\begin{abstract}
+$abstract$
+\end{abstract}
+
+\dates{This report was \textbf{automatically} compiled on \today.}
+$if(doi)$
+\doi{$doi$}
+$endif$
+
+$if(footer_contents)$
+\pinpfootercontents{$footer_contents$}
+$endif$
+
+$if(author_declaration)$
+\authordeclaration{$author_declaration$}
+$endif$
+
+$if(corresponding_author)$
+\correspondingauthor{\textsuperscript{$corresponding_author$}}}
+$endif$
+
+\begin{document}
+
+% Optional adjustment to line up main text (after abstract) of first page with line numbers, when using both lineno and twocolumn options.
+% You should only change this length when you've finalised the article contents.
+%\verticaladjustment{-2pt}
+
+\maketitle
+\thispagestyle{firststyle}
+\ifthenelse{\boolean{shortarticle}}{\ifthenelse{\boolean{singlecolumn}}{\abscontentformatted}{\abscontent}}{}
+
+% If your first paragraph (i.e. with the \dropcap) contains a list environment (quote, quotation, theorem, definition, enumerate, itemize...), the line after the list may have some extra indentation. If this is the case, add \parshape=0 to the end of the list environment.
+
+$if(acknowledgements)$
+\acknow{$acknowledgements$}
+$endif$
+
+$body$
+
+%\showmatmethods
+$if(acknowledgements)$
+\showacknow
+$endif$
+
+$if(skip_final_break)$
+$else$
+\pnasbreak
+$endif$
+
+$if(natbib)$
+$if(bibliography)$
+$if(biblio-title)$
+$if(book-class)$
+\renewcommand\bibname{$biblio-title$}
+$else$
+\renewcommand\refname{$biblio-title$}
+$endif$
+$endif$
+\bibliography{$for(bibliography)$$bibliography$$sep$,$endfor$}
+\bibliographystyle{$if(biblio-style)$$biblio-style$$else$jss$endif$}
+$endif$
+$endif$
+
+$if(biblatex)$
+\printbibliography$if(biblio-title)$[title=$biblio-title$]$endif$
+$endif$
+
+$for(include-after)$
+$include-after$
+$endfor$
+
+\end{document}
diff --git a/LegendMedCentral/dbPaper.rmd b/LegendMedCentral/dbPaper.rmd
new file mode 100644
index 00000000..f6ca841f
--- /dev/null
+++ b/LegendMedCentral/dbPaper.rmd
@@ -0,0 +1,276 @@
+---
+csl: pnas.csl
+
+output:
+ pdf_document:
+ fig_caption: yes
+ html_document: default
+bibliography: bibliography.bib
+params:
+ databaseId: "MDCR"
+ targetId: 739138
+ comparatorId: 715259
+ outcomeId: 18
+ setTitle: "A Comparison of Sertraline to Duloxetine for the Risk of Stroke in the MDCD Database."
+title: "`r params$setTitle`"
+---
+
+
+```{r, echo=FALSE, message=FALSE, comment=FALSE, warning=FALSE, results='hide'}
+library(DatabaseConnector)
+library(knitr)
+library(kableExtra)
+source("DataPulls.R")
+source("PlotsAndTables.R")
+options(knitr.kable.NA = '')
+
+# params <- list(databaseId = "MDCR",
+# targetId = 739138,
+# comparatorId = 715259,
+# outcomeId = 18)
+
+useStoredObject <- FALSE
+
+if (!useStoredObject) {
+ # connectionDetails <- createConnectionDetails(dbms = "postgresql",
+ # server = "localhost/ohdsi",
+ # user = "postgres",
+ # password = Sys.getenv("pwPostgres"),
+ # schema = "legend")
+ connectionDetails <- createConnectionDetails(dbms = "postgresql",
+ server = paste(Sys.getenv("legendServer"), Sys.getenv("legendDatabase"), sep = "/"),
+ port = Sys.getenv("legendPort"),
+ user = Sys.getenv("legendUser"),
+ password = Sys.getenv("legendPw"),
+ schema = Sys.getenv("legendSchema"))
+ connection <- connect(connectionDetails)
+ targetName <- getExposureName(connection = connection, exposureId = params$targetId)
+ comparatorName <- getExposureName(connection = connection, exposureId = params$comparatorId)
+ outcomeName <- getOutcomeName(connection = connection, outcomeId = params$outcomeId)
+ analyses <- getAnalyses(connection = connection)
+ databaseDetails <- getDatabaseDetails(connection = connection,
+ databaseId = params$databaseId)
+ studyPeriod <- getStudyPeriod(connection = connection,
+ targetId = params$targetId,
+ comparatorId = params$comparatorId,
+ databaseId = params$databaseId)
+ mainResults <- getMainResults(connection = connection,
+ targetIds = params$targetId,
+ comparatorIds = params$comparatorId,
+ outcomeIds = params$outcomeId,
+ databaseIds = params$databaseId,
+ analysisIds = c(1, 2, 3, 4))
+
+ subgroupResults <- getSubgroupResults(connection = connection,
+ targetIds = params$targetId,
+ comparatorIds = params$comparatorId,
+ outcomeIds = params$outcomeId,
+ databaseIds = params$databaseId)
+
+ controlResults <- getControlResults(connection = connection,
+ targetId = params$targetId,
+ comparatorId = params$comparatorId,
+ analysisId = 1,
+ databaseId = params$databaseId)
+
+ attrition <- getAttrition(connection = connection,
+ targetId = params$targetId,
+ comparatorId = params$comparatorId,
+ outcomeId = params$outcomeId,
+ analysisId = 1,
+ databaseId = params$databaseId)
+
+ followUpDist <- getCmFollowUpDist(connection = connection,
+ targetId = params$targetId,
+ comparatorId = params$comparatorId,
+ outcomeId = params$outcomeId,
+ databaseId = params$databaseId,
+ analysisId = 1)
+
+ balance <- getCovariateBalance(connection = connection,
+ targetId = params$targetId,
+ comparatorId = params$comparatorId,
+ databaseId = params$databaseId,
+ analysisId = 2)
+
+ popCharacteristics <- getCovariateBalance(connection = connection,
+ targetId = params$targetId,
+ comparatorId = params$comparatorId,
+ databaseId = params$databaseId,
+ analysisId = 1,
+ outcomeId = params$outcomeId)
+
+ ps <- getPs(connection = connection,
+ targetIds = params$targetId,
+ comparatorIds = params$comparatorId,
+ databaseId = params$databaseId)
+
+ kaplanMeier <- getKaplanMeier(connection = connection,
+ targetId = params$targetId,
+ comparatorId = params$comparatorId,
+ outcomeId = params$outcomeId,
+ databaseId = params$databaseId,
+ analysisId = 2)
+} else {
+ load("paperData.rda")
+}
+```
+
+\centerline{Martijn J. Schuemie$^{1,2}$}
+\centerline{Marc A. Suchard$^{1,3,4,5}$}
+\centerline{George M. Hripcsak$^{1,6}$}
+\centerline{Patrick B. Ryan$^{1,2,6}$}
+\centerline{David Madigan$^{1,7}$}
+
+$^{1}$ Observational Health Data Sciences and Informatics, New York, NY
+$^{2}$ Janssen Research & Development, Titusville, NJ
+$^{3}$ Department of Biomathematics, University of Califoria, Los Angeles, CA
+$^{4}$ Department of Biostatistics, University of Califoria, Los Angeles, CA
+$^{5}$ Department of Human Genetics, University of Califoria, Los Angeles, CA
+$^{6}$ Department of Biomedical Informatics, Columbia University, New York, NY
+$^{7}$ Department of Statistics, Columbia University, New York, NY
+
+Corresponding author: Martijn J. Schuemie, Janssen R&D, 1125 Trenton Harbourton Road, Titusville, NJ, 08560, Phone: +31 631793897, schuemie@ohdsi.org
+
+# Abstract
+
+To do
+
+# Introduction
+
+This is a very important study. Here's a really cool paper @pmid23900808.
+
+# Methods
+
+The study spanned the period from `r studyPeriod$minDate` until `r studyPeriod$minDate`.
+
+## Data source
+
+`r databaseDetails$description`
+
+# Results
+
+```{r, echo = FALSE, fig.width=6, fig.height=7.5, out.width = '50%', fig.align='center'}
+drawAttritionDiagram(attrition, targetName, comparatorName)
+```
+**Figure 1**. Attrition diagram.
+
+
+**Table 1**. Select population characteristics
+```{r, echo = FALSE}
+table <- prepareTable1(popCharacteristics)
+# Remove 1st header, with add back later with merged columns:
+header <- as.character(table[1, ])
+header[header == "1"] <- ""
+table <- table[-1, ]
+# Indentation needs to be made explicit (not by leading spaces):
+needIndent <- which(substr(table[, 1], 1, 1) == " ")
+
+kable_styling(add_indent(add_header_above(kable(table, "latex",
+ booktabs = TRUE,
+ longtable = TRUE,
+ row.names = FALSE,
+ col.names = header,
+ linesep = "",
+ align = c("l", "r", "r", "r", "r", "r", "r")),
+ c("", "Before stratification" = 3, "After stratification" = 3)),
+ needIndent),
+ font_size = 7,
+ latex_options = c("HOLD_position", "repeat_header"))
+
+```
+
+**Table 2**. Number of subjects, follow-up time (in days), number of outcome events, and event incidence rate (IR) per 1,000 patient years (PY) in the target and comparator group after stratification or matching, as well as the minimum detectable relative risk (MDRR). Note that the IR does not account for any stratification or matching.
+```{r, echo = FALSE}
+table <- preparePowerTable(mainResults, analyses)
+
+header <- c("Analysis", "Target", "Comp.", "Target", "Comp.", "Target", "Comp.", "Target", "Comp.", "MDRR")
+kable_styling(add_header_above(kable(table, "latex",
+ booktabs = TRUE,
+ row.names = FALSE,
+ col.names = header,
+ align = c("l", "r", "r", "r", "r", "r", "r", "r", "r", "r")),
+ c("", "Subjects" = 2, "PYs" = 2, "Outcomes" = 2, "IR (per 1,000 PY)" = 2, "")),
+ font_size = 7,
+ latex_options = c("HOLD_position"))
+
+```
+
+
+**Table 2**. Time (days) at risk distribution expressed as minimum (Min), 10th Percentile (P10), 25th percentile (P25), median, 75th percentile (P75), 90th percentile (P90) and maximum (Max) in the target and comparator cohort after stratification.
+```{r, echo = FALSE}
+table <- prepareFollowUpDistTable(followUpDist)
+kable_styling(kable(table, "latex",
+ booktabs = TRUE,
+ longtable = FALSE,
+ row.names = FALSE,
+ linesep = "",
+ align = c("l", "r", "r", "r", "r", "r", "r", "r")),
+ font_size = 8,
+ latex_options = c("HOLD_position"))
+
+```
+
+```{r, echo = FALSE, fig.width=5, fig.height=3.5, out.width = '50%', fig.align='center'}
+plotPs(ps, targetName, comparatorName)
+```
+**Figure 2**. Preference score distribution. The preference score is a transformation of the propensity score that adjusts for differences in the sizes of the two treatment groups. A higher overlap indicates subjects in the two groups were more similar in terms of their predicted probability of receiving one treatment over the other.
+
+```{r, echo = FALSE, fig.width=4, fig.height=4, out.width = '50%', fig.align='center', warning=FALSE}
+plotCovariateBalanceScatterPlot(balance, beforeLabel = "Before stratification", afterLabel = "After stratification")
+```
+**Figure 3**. Covariate balance before and after stratification. Each dot represents the standardizes difference of means for a single covariate before and after stratification on the propensity score.
+
+```{r, echo = FALSE, fig.width=12, fig.height=4, out.width = '100%', fig.align='center', warning=FALSE}
+plotScatter(controlResults)
+```
+**Figure 4**. Systematic error
+
+
+**Table 3**. Hazard ratios, 95% confidence intervals, uncalibrated and empirically calibrated, for various analyses.
+```{r, echo = FALSE}
+table <- prepareMainResultsTable(mainResults, analyses)
+kable_styling(kable(table, "latex",
+ booktabs = TRUE,
+ longtable = FALSE,
+ row.names = FALSE,
+ linesep = ""),
+ font_size = 8,
+ latex_options = c("HOLD_position"))
+```
+
+```{r, echo = FALSE, fig.width=7, fig.height=5, out.width = '100%', fig.align='center', results='hide'}
+plotKaplanMeier(kaplanMeier, targetName, comparatorName)
+```
+**Figure 3**. Kaplan Meier plot, showing survival as a function of time. This plot
+is adjusted for the propensity score stratification: The target curve (`r targetName`) shows the actual observed survival. The
+comparator curve (`r comparatorName`) applies reweighting to approximate the counterfactual of what the target survival
+would look like had the target cohort been exposed to the comparator instead. The shaded area denotes
+the 95 percent confidence interval.
+
+
+**Table 4**. Subgroup interactions
+```{r, echo = FALSE}
+table <- prepareSubgroupTable(subgroupResults)
+
+header <- c("Subgroup", "Target", "Comparator", "HRR (95% CI)", "P" ,"Cal. P", "HRR (95% CI)", "P" ,"Cal. P")
+kable_styling(add_header_above(kable(table, "latex",
+ booktabs = TRUE,
+ row.names = FALSE,
+ col.names = header,
+ align = c("l", "r", "r", "r", "r", "r", "r", "r", "r")),
+ c("", "Subjects" = 2, "On-treatment" = 3, "Intent-to-treat" = 3)),
+ font_size = 8,
+ latex_options = c("HOLD_position"))
+
+```
+
+# Conclusions
+
+# References
+
+```{r, echo=FALSE, message=FALSE, comment=FALSE, warning=FALSE, results='hide'}
+if (!useStoredObject) {
+ DatabaseConnector::disconnect(connection)
+}
+```
diff --git a/LegendMedCentral/dbPaperPinp.Rmd b/LegendMedCentral/dbPaperPinp.Rmd
new file mode 100644
index 00000000..48879b43
--- /dev/null
+++ b/LegendMedCentral/dbPaperPinp.Rmd
@@ -0,0 +1,387 @@
+---
+params:
+ databaseId: "MDCR"
+ targetId: 739138
+ comparatorId: 715259
+ outcomeId: 18
+ setTitle: "Stroke risk in new-users of sertaline versus duloxetine for major depressive disorder in the MDCR database."
+title: "`r params$setTitle`"
+# Corresponding author: Martijn J. Schuemie, Janssen R&D, 1125 Trenton Harbourton Road, Titusville, NJ, 08560, Phone: +31 631793897, schuemie@ohdsi.org
+author:
+
+ - name: Martijn J. Schuemie
+ affiliation: a,b,c
+ - name: Patrick B. Ryan
+ affiliation: a,b,d
+ - name: Seng Chan You
+ affiliation: a,e
+ - name: Nicole Pratt
+ affiliation: a,f
+ - name: David Madigan
+ affiliation: a,g
+ - name: George Hripcsak
+ affiliation: a,d
+ - name: Marc A. Suchard
+ affiliation: a,c,h,i
+address:
+ - code: a
+ address: Observational Health Data Sciences and Informatics, New York, NY, USA
+ - code: b
+ address: Janssen Research & Development, Titusville, NJ, USA
+ - code: c
+ address: Department of Biostatistics, University of Califoria, Los Angeles, CA
+ - code: d
+ address: Department of Biomedical Informatics, Columbia University, New York, NY
+ - code: e
+ address: Department of Biomedical Informatics, Ajou University, Suwon, South Korea
+ - code: f
+ address: Sansom Institute, University of South Australia, Adelaide SA, Australia
+ - code: g
+ address: Department of Statistics, Columbia University, New York, NY
+ - code: h
+ address: Department of Biomathematics, University of Califoria, Los Angeles, CA
+ - code: i
+ address: Department of Human Genetics, University of Califoria, Los Angeles, CA
+lead_author_surname: Schuemie et al.
+doi: "https://cran.r-project.org/package=YourPackage"
+abstract: |
+ Your abstract will be typeset here, and used by default a visually distinctive font.
+ An abstract should explain to the general reader the major contributions of the article.
+# Optional: Acknowledgements
+acknowledgements: |
+ This template package builds upon, and extends, the work of the excellent
+ gratefully acknowledged as this work would not have been possible without them. Our extensions
+ are under the same respective licensing term
+ [rticles](https://cran.r-project.org/package=rticles) package, and both packages rely on the
+ [PNAS LaTeX](http://www.pnas.org/site/authors/latex.xhtml) macros. Both these sources are
+ ([GPL-3](https://www.gnu.org/licenses/gpl-3.0.en.html) and
+ [LPPL (>= 1.3)](https://www.latex-project.org/lppl/)).
+# Optional: One or more keywords
+keywords:
+ - one
+ - two
+ - optional
+ - keywords
+ - here
+papersize: letter
+fontsize: 9pt
+# Optional: Force one-column layout, default is two-column
+# one_column: true
+# Optional: Enables lineno mode, but only if one_column mode is also true
+#lineno: true
+# Optional: Enable one-sided layout, default is two-sided
+#one_sided: true
+# Optional: Enable section numbering, default is unnumbered
+#numbersections: true
+# Optional: Specify the depth of section number, default is 5
+#secnumdepth: 5
+# Optional: Skip inserting final break between acknowledgements, default is false
+skip_final_break: true
+# Optional: Bibliography
+bibliography: bibliography.bib
+# Optional: Enable a 'Draft' watermark on the document
+watermark: true
+footer_contents: "LEGEND Project Document"
+output: pinp::pinp
+# Required: Vignette metadata for inclusion in a package.
+vignette: >
+ %\VignetteIndexEntry{YourPackage-vignetteentry}
+ %\VignetteKeywords{YourPackage, r, anotherkeyword}
+ %\VignettePackage{YourPackage}
+ %\VignetteEngine{knitr::rmarkdown}
+editor_options:
+ chunk_output_type: console
+---
+
+## Introduction
+
+This *pinp is not PNAS* template started when the introduction to
+[Rcpp](http://dirk.eddelbuettel.com/code/rcpp.html) by \cite{PeerJ:Rcpp}
+was converted into this updated
+[Rcpp Introduction](https://eddelbuettel.github.io/pinp/Rcpp-introduction.pdf)
+vignette. It is based on the
+[pnas_article](https://github.com/rstudio/rticles/tree/master/inst/rmarkdown/templates/pnas_article)
+template of the wonderful [rticles](https://cran.r-project.org/package=rticles) package by
+\cite{CRAN:rticles}. The conversion from markdown to latex is facilitated by
+[rmarkdown](https://cran.r-project.org/package=rmarkdown)
+\citep{CRAN:rmarkdown} and [knitr](https://cran.r-project.org/package=knitr)
+\citep{CRAN:knitr}. The underlying LaTeX macros are from
+[pnas.org](http://www.pnas.org/site/authors/latex.xhtml).
+
+The remainder of the document carries over from the corresponding
+[pnas_article](https://github.com/rstudio/rticles/tree/master/inst/rmarkdown/templates/pnas_article)
+template document. but has been edited and updated to our use case. A
+few specific tips follow. In general, for fine-tuning some knowledge
+of LaTeX is helpful.
+
+
+
+```{r, echo=FALSE, message=FALSE, comment=FALSE, results='hide'}
+library(DatabaseConnector)
+library(CohortMethod)
+library(Legend)
+library(knitr)
+library(xtable)
+library(ggplot2)
+source("DataPulls.R")
+source("PlotsAndTables.R")
+options(knitr.kable.NA = '')
+
+# params <- list(databaseId = "MDCR",
+# targetId = 739138,
+# comparatorId = 715259,
+# outcomeId = 18)
+
+useStoredObject <- TRUE
+
+if (!useStoredObject) {
+ connectionDetails <- createConnectionDetails(dbms = "postgresql",
+ server = "localhost/ohdsi",
+ user = "postgres",
+ password = Sys.getenv("pwPostgres"),
+ schema = "legend")
+ connection <- connect(connectionDetails)
+ targetName <- getExposureName(connection, params$targetId)
+ comparatorName <- getExposureName(connection, params$comparatorId)
+ outcomeName <- getOutcomeName(connection, params$outcomeId)
+ analyses <- getAnalyses(connection)
+ mainResults <- getMainResults(connection,
+ targetIds = params$targetId,
+ comparatorIds = params$comparatorId,
+ outcomeIds = params$outcomeId,
+ databaseIds = params$databaseId)
+
+ attrition <- getAttrition(connection,
+ targetId = params$targetId,
+ comparatorId = params$comparatorId,
+ outcomeId = params$outcomeId,
+ analysisId = 1,
+ databaseId = params$databaseId)
+
+ balance <- getCovariateBalance(connection,
+ targetId = params$targetId,
+ comparatorId = params$comparatorId,
+ databaseId = params$databaseId)
+
+ ps <- getPs(connection,
+ targetId = params$targetId,
+ comparatorId = params$comparatorId,
+ databaseId = params$databaseId)
+
+ kaplanMeier <- getKaplanMeier(connection,
+ targetId = params$targetId,
+ comparatorId = params$comparatorId,
+ outcomeId = params$outcomeId,
+ databaseId = params$databaseId,
+ analysisId = 2)
+} else {
+ load("paperData.rda")
+}
+```
+
+## Methods
+
+## Results
+
+Table \ref{tab:demographics} \ldots
+
+\clearpage
+
+\begin{figure*}
+\caption{\textbf{Patient demographics.} Target (T) population is sertaline new-users. Comparative (C) population is dulexotine new-users. We report the standardized difference of population means (StdDiff) before and after stratification for selected base-line patient characteristics.}\label{tab:demographics}
+\begin{center}
+\resizebox{0.5\textwidth}{!}{
+\begin{tabular}{lrrrrrr}
+\hline
+& \multicolumn{3}{c}{Before stratification}
+& \multicolumn{3}{c}{After stratification} \\
+\multicolumn{1}{c}{Characteristic}
+ & \multicolumn{1}{c}{T (\%)}
+ & \multicolumn{1}{c}{C (\%)}
+ & \multicolumn{1}{c}{StdDiff}
+ & \multicolumn{1}{c}{T (\%)}
+ & \multicolumn{1}{c}{C (\%)}
+ & \multicolumn{1}{c}{StdDiff} \\
+ \hline
+```{r, echo=FALSE, results="asis", cache=TRUE}
+table <- prepareTable1(balance)
+table <- table[3:nrow(table),]
+
+print(xtable(table, format = "latex", align = c("l","l","r","r","r","r","r","r")),
+ include.rownames = FALSE,
+ include.colnames = FALSE,
+ hline.after = NULL,
+ only.contents = TRUE,
+ sanitize.text.function = identity)
+```
+\end{tabular}
+}
+\end{center}
+\end{figure*}
+
+\clearpage
+
+```{r, echo=FALSE, cache=TRUE}
+plot <- plotPs(ps, targetName, comparatorName)
+suppressMessages(ggsave("ps.pdf", plot,
+ width = 5, height = 5, units = "in"))
+```
+
+\begin{figure}
+ \centerline{
+ \includegraphics[width=0.4\textwidth]{ps}
+ }
+ \caption{\textbf{Preference score distribution for sertaline and dulexotine new-users.}
+ The preference score is a transformation of the propensity score that adjusts for size differences between populations. A higher overlap indicates that subjects in the two populations are more similar in terms of their predicted probability of receiving one treatment over the other.
+ }
+\end{figure}
+
+More text here.
+
+\begin{figure}
+\begin{tabular}{lrrrr}
+```{r, echo=FALSE, results="asis"}
+table <- mainResults
+table$hr <- sprintf("%.2f (%.2f - %.2f)", mainResults$rr, mainResults$ci95lb, mainResults$ci95ub)
+table$p <- sprintf("%.2f", table$p)
+table$calHr <- sprintf("%.2f (%.2f - %.2f)", mainResults$calibratedRr, mainResults$calibratedCi95Lb, mainResults$calibratedCi95Ub)
+table$calibratedP <- sprintf("%.2f", table$calibratedP)
+table <- merge(table, analyses)
+table <- table[, c("description", "hr", "p", "calHr", "calibratedP")]
+
+print(xtable(table),
+ include.rownames = FALSE,
+ include.colnames = FALSE,
+ hline.after = NULL,
+ only.contents = TRUE,
+ sanitize.text.function = identity)
+```
+\end{tabular}
+\end{figure}
+
+
+## Discussion
+
+## Appendix
+
+```{r, echo=FALSE, cache=TRUE}
+plot <- drawAttritionDiagram(attrition, targetName, comparatorName)
+suppressMessages(ggsave("attrition.pdf", plot,
+ width = 6, height = 10, units = "in"))
+```
+
+\begin{figure*}
+ \begin{center}
+ \includegraphics[width=0.66\textwidth]{attrition}
+ \end{center}
+ \caption{Attrition diagram for selecting new-users of }\label{fig:attrition}
+\end{figure*}
+
+## Inline R Code
+
+The PNAS sample included a fixed PNG image here, but this document prefers
+to show the results and embedding of _R_ code.
+
+```{r figex, fig.width=3, fig.height=3, cache=TRUE, echo=TRUE, fig.cap="Narrow ggplot2 figure"}
+library(ggplot2)
+ggplot(mtcars, aes(wt, mpg)) +
+ geom_point(size=3, aes(colour=factor(cyl))) +
+ theme(legend.position="none")
+```
+
+Here we use a standard knitr bloc with explicit options for
+
+- figure width and height (`fig.width`, `fig.height`), both set to three inches;
+- whether the code is shown (`echo=TRUE`); and
+- the caption (`fig.cap`) as shown above.
+
+
+## Digital Figures
+
+Markdown, Pandoc and LaTeX support `.eps` and `.pdf` files.
+
+Figures and Tables should be labelled and referenced in the standard way
+using the `\label{}` and `\ref{}` commands.
+
+The R examples above show how to insert a column-wide
+figure. To insert a figure wider than one column, please use the
+`\begin{figure*}...\end{figure*}` environment.
+
+One (roundabout) way of doing this is to _not_ actually plot a figure, but to
+save it in a file as the following segment shows:
+
+```{r densityPlot, echo=TRUE}
+library(ggplot2)
+p <- ggplot(data = midwest,
+ mapping = aes(x = area,
+ fill = state,
+ color = state)) +
+ geom_density(alpha = 0.3)
+## save to file
+suppressMessages(ggsave("densities.pdf", p))
+```
+
+This file is then included via standard LaTeX commands.
+
+\begin{figure*}
+ \begin{center}
+ \includegraphics[width=0.66\textwidth, height=3.5in]{densities}
+ \end{center}
+ \caption{Wide ggplot2 figure}\label{fig}
+\end{figure*}
+
+
+## Typeset Code (But Do Not Run It)
+
+We can also just show code.
+
+```r
+xx <- faithful[,"eruptions"]
+fit <- density(xx)
+plot(fit)
+```
+
+This simply used a pandoc bloc started and ended by three backticks,
+with `r` as the language choice. Similarly, _many_ other languages
+can be typeset directly simply by relying on pandoc.
+
+
+## Single column equations
+
+Authors may use 1- or 2-column equations in their article, according to
+their preference.
+
+To allow an equation to span both columns, options are to use the
+`\begin{figure*}...\end{figure*}` environment mentioned above for
+figures, or to use the `\begin{widetext}...\end{widetext}` environment
+as shown in equation \ref{eqn:example} below.
+
+Please note that this option may run into problems with floats and
+footnotes, as mentioned in the [cuted package
+documentation](http://texdoc.net/pkg/cuted). In the case of problems
+with footnotes, it may be possible to correct the situation using
+commands `\footnotemark` and `\footnotetext`.
+
+\begin{equation}
+ \begin{aligned}
+(x+y)^3&=(x+y)(x+y)^2\\
+ &=(x+y)(x^2+2xy+y^2) \\
+ &=x^3+3x^2y+3xy^3+x^3.
+ \label{eqn:example}
+ \end{aligned}
+\end{equation}
+
+
+
+
diff --git a/LegendMedCentral/global.R b/LegendMedCentral/global.R
new file mode 100644
index 00000000..20f4b2ce
--- /dev/null
+++ b/LegendMedCentral/global.R
@@ -0,0 +1,25 @@
+library(DatabaseConnector)
+source("DataPulls.R")
+source("PlotsAndTables.R")
+
+# connectionDetails <- createConnectionDetails(dbms = 'postgresql', server = 'localhost/ohdsi', user
+# = 'postgres', password = Sys.getenv('pwPostgres'), schema = 'legend')
+connectionDetails <- createConnectionDetails(dbms = "postgresql",
+ server = paste(Sys.getenv("legendServer"),
+ Sys.getenv("legendDatabase"),
+ sep = "/"),
+ port = Sys.getenv("legendPort"),
+ user = Sys.getenv("legendUser"),
+ password = Sys.getenv("legendPw"),
+ schema = Sys.getenv("legendSchema"))
+connection <- connect(connectionDetails)
+
+exposures <- getExposures(connection)
+exposures$exposureName <- sapply(exposures$exposureName, uncapitalize)
+
+outcomes <- getOutcomes(connection)
+databases <- getDatabases(connection)
+
+writeLines("Closing connection")
+disconnect(connection)
+
diff --git a/LegendMedCentral/ijrexoda_files/figure-latex/attrition_plot-1.pdf b/LegendMedCentral/ijrexoda_files/figure-latex/attrition_plot-1.pdf
new file mode 100644
index 00000000..969989af
Binary files /dev/null and b/LegendMedCentral/ijrexoda_files/figure-latex/attrition_plot-1.pdf differ
diff --git a/LegendMedCentral/ijrexoda_files/figure-latex/error.pdf b/LegendMedCentral/ijrexoda_files/figure-latex/error.pdf
new file mode 100644
index 00000000..8966ee08
Binary files /dev/null and b/LegendMedCentral/ijrexoda_files/figure-latex/error.pdf differ
diff --git a/LegendMedCentral/ijrexoda_files/figure-latex/km-1.pdf b/LegendMedCentral/ijrexoda_files/figure-latex/km-1.pdf
new file mode 100644
index 00000000..6e65282e
Binary files /dev/null and b/LegendMedCentral/ijrexoda_files/figure-latex/km-1.pdf differ
diff --git a/LegendMedCentral/ijrexoda_files/figure-latex/make_balance-1.pdf b/LegendMedCentral/ijrexoda_files/figure-latex/make_balance-1.pdf
new file mode 100644
index 00000000..e67fa470
Binary files /dev/null and b/LegendMedCentral/ijrexoda_files/figure-latex/make_balance-1.pdf differ
diff --git a/LegendMedCentral/ijrexoda_files/figure-latex/make_ps-1.pdf b/LegendMedCentral/ijrexoda_files/figure-latex/make_ps-1.pdf
new file mode 100644
index 00000000..e82a04de
Binary files /dev/null and b/LegendMedCentral/ijrexoda_files/figure-latex/make_ps-1.pdf differ
diff --git a/LegendMedCentral/jss.bst b/LegendMedCentral/jss.bst
new file mode 100644
index 00000000..5d73c072
--- /dev/null
+++ b/LegendMedCentral/jss.bst
@@ -0,0 +1,1654 @@
+%%
+%% This is file `jss.bst',
+%% generated with the docstrip utility.
+%%
+%% The original source files were:
+%%
+%% merlin.mbs (with options: `ay,nat,nm-rvx,keyxyr,dt-beg,yr-par,note-yr,tit-qq,atit-u,trnum-it,vol-bf,volp-com,num-xser,pre-edn,isbn,issn,edpar,pp,ed,xedn,xand,etal-it,revdata,eprint,url,url-blk,doi,nfss')
+%%
+%% ** BibTeX style file for JSS publications (http://www.jstatsoft.org/)
+%%
+%% Copyright 1994-2011 Patrick W Daly
+%% License: GPL-2 | GPL-3
+ % ===============================================================
+ % IMPORTANT NOTICE:
+ % This bibliographic style (bst) file has been generated from one or
+ % more master bibliographic style (mbs) files, listed above, provided
+ % with kind permission of Patrick W Daly.
+ %
+ % This generated file can be redistributed and/or modified under the terms
+ % of the General Public License (Version 2 or 3).
+ % ===============================================================
+ % Name and version information of the main mbs file:
+ % \ProvidesFile{merlin.mbs}[2011/11/18 4.33 (PWD, AO, DPC)]
+ % For use with BibTeX version 0.99a or later
+ %-------------------------------------------------------------------
+ % This bibliography style file is intended for texts in ENGLISH
+ % This is an author-year citation style bibliography. As such, it is
+ % non-standard LaTeX, and requires a special package file to function properly.
+ % Such a package is natbib.sty by Patrick W. Daly
+ % The form of the \bibitem entries is
+ % \bibitem[Jones et al.(1990)]{key}...
+ % \bibitem[Jones et al.(1990)Jones, Baker, and Smith]{key}...
+ % The essential feature is that the label (the part in brackets) consists
+ % of the author names, as they should appear in the citation, with the year
+ % in parentheses following. There must be no space before the opening
+ % parenthesis!
+ % With natbib v5.3, a full list of authors may also follow the year.
+ % In natbib.sty, it is possible to define the type of enclosures that is
+ % really wanted (brackets or parentheses), but in either case, there must
+ % be parentheses in the label.
+ % The \cite command functions as follows:
+ % \citet{key} ==>> Jones et al. (1990)
+ % \citet*{key} ==>> Jones, Baker, and Smith (1990)
+ % \citep{key} ==>> (Jones et al., 1990)
+ % \citep*{key} ==>> (Jones, Baker, and Smith, 1990)
+ % \citep[chap. 2]{key} ==>> (Jones et al., 1990, chap. 2)
+ % \citep[e.g.][]{key} ==>> (e.g. Jones et al., 1990)
+ % \citep[e.g.][p. 32]{key} ==>> (e.g. Jones et al., 1990, p. 32)
+ % \citeauthor{key} ==>> Jones et al.
+ % \citeauthor*{key} ==>> Jones, Baker, and Smith
+ % \citeyear{key} ==>> 1990
+ %---------------------------------------------------------------------
+
+ENTRY
+ { address
+ archive
+ author
+ booktitle
+ chapter
+ collaboration
+ doi
+ edition
+ editor
+ eid
+ eprint
+ howpublished
+ institution
+ isbn
+ issn
+ journal
+ key
+ month
+ note
+ number
+ numpages
+ organization
+ pages
+ publisher
+ school
+ series
+ title
+ type
+ url
+ volume
+ year
+ }
+ {}
+ { label extra.label sort.label short.list }
+INTEGERS { output.state before.all mid.sentence after.sentence after.block }
+FUNCTION {init.state.consts}
+{ #0 'before.all :=
+ #1 'mid.sentence :=
+ #2 'after.sentence :=
+ #3 'after.block :=
+}
+STRINGS { s t}
+FUNCTION {output.nonnull}
+{ 's :=
+ output.state mid.sentence =
+ { ", " * write$ }
+ { output.state after.block =
+ { add.period$ write$
+ newline$
+ "\newblock " write$
+ }
+ { output.state before.all =
+ 'write$
+ { add.period$ " " * write$ }
+ if$
+ }
+ if$
+ mid.sentence 'output.state :=
+ }
+ if$
+ s
+}
+FUNCTION {output}
+{ duplicate$ empty$
+ 'pop$
+ 'output.nonnull
+ if$
+}
+FUNCTION {output.check}
+{ 't :=
+ duplicate$ empty$
+ { pop$ "empty " t * " in " * cite$ * warning$ }
+ 'output.nonnull
+ if$
+}
+FUNCTION {fin.entry}
+{ add.period$
+ write$
+ newline$
+}
+
+FUNCTION {new.block}
+{ output.state before.all =
+ 'skip$
+ { after.block 'output.state := }
+ if$
+}
+FUNCTION {new.sentence}
+{ output.state after.block =
+ 'skip$
+ { output.state before.all =
+ 'skip$
+ { after.sentence 'output.state := }
+ if$
+ }
+ if$
+}
+FUNCTION {add.blank}
+{ " " * before.all 'output.state :=
+}
+
+FUNCTION {date.block}
+{
+ new.block
+}
+
+FUNCTION {not}
+{ { #0 }
+ { #1 }
+ if$
+}
+FUNCTION {and}
+{ 'skip$
+ { pop$ #0 }
+ if$
+}
+FUNCTION {or}
+{ { pop$ #1 }
+ 'skip$
+ if$
+}
+FUNCTION {non.stop}
+{ duplicate$
+ "}" * add.period$
+ #-1 #1 substring$ "." =
+}
+
+STRINGS {z}
+
+FUNCTION {remove.dots}
+{ 'z :=
+ ""
+ { z empty$ not }
+ { z #1 #2 substring$
+ duplicate$ "\." =
+ { z #3 global.max$ substring$ 'z := * }
+ { pop$
+ z #1 #1 substring$
+ z #2 global.max$ substring$ 'z :=
+ duplicate$ "." = 'pop$
+ { * }
+ if$
+ }
+ if$
+ }
+ while$
+}
+FUNCTION {new.block.checkb}
+{ empty$
+ swap$ empty$
+ and
+ 'skip$
+ 'new.block
+ if$
+}
+FUNCTION {field.or.null}
+{ duplicate$ empty$
+ { pop$ "" }
+ 'skip$
+ if$
+}
+FUNCTION {emphasize}
+{ duplicate$ empty$
+ { pop$ "" }
+ { "\emph{" swap$ * "}" * }
+ if$
+}
+FUNCTION {bolden}
+{ duplicate$ empty$
+ { pop$ "" }
+ { "\textbf{" swap$ * "}" * }
+ if$
+}
+FUNCTION {tie.or.space.prefix}
+{ duplicate$ text.length$ #3 <
+ { "~" }
+ { " " }
+ if$
+ swap$
+}
+
+FUNCTION {capitalize}
+{ "u" change.case$ "t" change.case$ }
+
+FUNCTION {space.word}
+{ " " swap$ * " " * }
+ % Here are the language-specific definitions for explicit words.
+ % Each function has a name bbl.xxx where xxx is the English word.
+ % The language selected here is ENGLISH
+FUNCTION {bbl.and}
+{ "and"}
+
+FUNCTION {bbl.etal}
+{ "et~al." }
+
+FUNCTION {bbl.editors}
+{ "eds." }
+
+FUNCTION {bbl.editor}
+{ "ed." }
+
+FUNCTION {bbl.edby}
+{ "edited by" }
+
+FUNCTION {bbl.edition}
+{ "edition" }
+
+FUNCTION {bbl.volume}
+{ "volume" }
+
+FUNCTION {bbl.of}
+{ "of" }
+
+FUNCTION {bbl.number}
+{ "number" }
+
+FUNCTION {bbl.nr}
+{ "no." }
+
+FUNCTION {bbl.in}
+{ "in" }
+
+FUNCTION {bbl.pages}
+{ "pp." }
+
+FUNCTION {bbl.page}
+{ "p." }
+
+FUNCTION {bbl.eidpp}
+{ "pages" }
+
+FUNCTION {bbl.chapter}
+{ "chapter" }
+
+FUNCTION {bbl.techrep}
+{ "Technical Report" }
+
+FUNCTION {bbl.mthesis}
+{ "Master's thesis" }
+
+FUNCTION {bbl.phdthesis}
+{ "Ph.D. thesis" }
+
+MACRO {jan} {"January"}
+
+MACRO {feb} {"February"}
+
+MACRO {mar} {"March"}
+
+MACRO {apr} {"April"}
+
+MACRO {may} {"May"}
+
+MACRO {jun} {"June"}
+
+MACRO {jul} {"July"}
+
+MACRO {aug} {"August"}
+
+MACRO {sep} {"September"}
+
+MACRO {oct} {"October"}
+
+MACRO {nov} {"November"}
+
+MACRO {dec} {"December"}
+
+MACRO {acmcs} {"ACM Computing Surveys"}
+
+MACRO {acta} {"Acta Informatica"}
+
+MACRO {cacm} {"Communications of the ACM"}
+
+MACRO {ibmjrd} {"IBM Journal of Research and Development"}
+
+MACRO {ibmsj} {"IBM Systems Journal"}
+
+MACRO {ieeese} {"IEEE Transactions on Software Engineering"}
+
+MACRO {ieeetc} {"IEEE Transactions on Computers"}
+
+MACRO {ieeetcad}
+ {"IEEE Transactions on Computer-Aided Design of Integrated Circuits"}
+
+MACRO {ipl} {"Information Processing Letters"}
+
+MACRO {jacm} {"Journal of the ACM"}
+
+MACRO {jcss} {"Journal of Computer and System Sciences"}
+
+MACRO {scp} {"Science of Computer Programming"}
+
+MACRO {sicomp} {"SIAM Journal on Computing"}
+
+MACRO {tocs} {"ACM Transactions on Computer Systems"}
+
+MACRO {tods} {"ACM Transactions on Database Systems"}
+
+MACRO {tog} {"ACM Transactions on Graphics"}
+
+MACRO {toms} {"ACM Transactions on Mathematical Software"}
+
+MACRO {toois} {"ACM Transactions on Office Information Systems"}
+
+MACRO {toplas} {"ACM Transactions on Programming Languages and Systems"}
+
+MACRO {tcs} {"Theoretical Computer Science"}
+FUNCTION {bibinfo.check}
+{ swap$
+ duplicate$ missing$
+ {
+ pop$ pop$
+ ""
+ }
+ { duplicate$ empty$
+ {
+ swap$ pop$
+ }
+ { swap$
+ pop$
+ }
+ if$
+ }
+ if$
+}
+FUNCTION {bibinfo.warn}
+{ swap$
+ duplicate$ missing$
+ {
+ swap$ "missing " swap$ * " in " * cite$ * warning$ pop$
+ ""
+ }
+ { duplicate$ empty$
+ {
+ swap$ "empty " swap$ * " in " * cite$ * warning$
+ }
+ { swap$
+ pop$
+ }
+ if$
+ }
+ if$
+}
+FUNCTION {format.eprint}
+{ eprint duplicate$ empty$
+ 'skip$
+ { "\eprint"
+ archive empty$
+ 'skip$
+ { "[" * archive * "]" * }
+ if$
+ "{" * swap$ * "}" *
+ }
+ if$
+}
+FUNCTION {format.url}
+{
+ url
+ duplicate$ empty$
+ { pop$ "" }
+ { "\urlprefix\url{" swap$ * "}" * }
+ if$
+}
+
+INTEGERS { nameptr namesleft numnames }
+
+
+STRINGS { bibinfo}
+
+FUNCTION {format.names}
+{ 'bibinfo :=
+ duplicate$ empty$ 'skip$ {
+ 's :=
+ "" 't :=
+ #1 'nameptr :=
+ s num.names$ 'numnames :=
+ numnames 'namesleft :=
+ { namesleft #0 > }
+ { s nameptr
+ "{vv~}{ll}{ jj}{ f{}}"
+ format.name$
+ remove.dots
+ bibinfo bibinfo.check
+ 't :=
+ nameptr #1 >
+ {
+ namesleft #1 >
+ { ", " * t * }
+ {
+ s nameptr "{ll}" format.name$ duplicate$ "others" =
+ { 't := }
+ { pop$ }
+ if$
+ "," *
+ t "others" =
+ {
+ " " * bbl.etal emphasize *
+ }
+ { " " * t * }
+ if$
+ }
+ if$
+ }
+ 't
+ if$
+ nameptr #1 + 'nameptr :=
+ namesleft #1 - 'namesleft :=
+ }
+ while$
+ } if$
+}
+FUNCTION {format.names.ed}
+{
+ 'bibinfo :=
+ duplicate$ empty$ 'skip$ {
+ 's :=
+ "" 't :=
+ #1 'nameptr :=
+ s num.names$ 'numnames :=
+ numnames 'namesleft :=
+ { namesleft #0 > }
+ { s nameptr
+ "{f{}~}{vv~}{ll}{ jj}"
+ format.name$
+ remove.dots
+ bibinfo bibinfo.check
+ 't :=
+ nameptr #1 >
+ {
+ namesleft #1 >
+ { ", " * t * }
+ {
+ s nameptr "{ll}" format.name$ duplicate$ "others" =
+ { 't := }
+ { pop$ }
+ if$
+ "," *
+ t "others" =
+ {
+
+ " " * bbl.etal emphasize *
+ }
+ { " " * t * }
+ if$
+ }
+ if$
+ }
+ 't
+ if$
+ nameptr #1 + 'nameptr :=
+ namesleft #1 - 'namesleft :=
+ }
+ while$
+ } if$
+}
+FUNCTION {format.key}
+{ empty$
+ { key field.or.null }
+ { "" }
+ if$
+}
+
+FUNCTION {format.authors}
+{ author "author" format.names
+ duplicate$ empty$ 'skip$
+ { collaboration "collaboration" bibinfo.check
+ duplicate$ empty$ 'skip$
+ { " (" swap$ * ")" * }
+ if$
+ *
+ }
+ if$
+}
+FUNCTION {get.bbl.editor}
+{ editor num.names$ #1 > 'bbl.editors 'bbl.editor if$ }
+
+FUNCTION {format.editors}
+{ editor "editor" format.names duplicate$ empty$ 'skip$
+ {
+ " " *
+ get.bbl.editor
+ "(" swap$ * ")" *
+ *
+ }
+ if$
+}
+FUNCTION {format.isbn}
+{ isbn "isbn" bibinfo.check
+ duplicate$ empty$ 'skip$
+ {
+ new.block
+ "ISBN " swap$ *
+ }
+ if$
+}
+
+FUNCTION {format.issn}
+{ issn "issn" bibinfo.check
+ duplicate$ empty$ 'skip$
+ {
+ new.block
+ "ISSN " swap$ *
+ }
+ if$
+}
+
+FUNCTION {format.doi}
+{ doi empty$
+ { "" }
+ {
+ new.block
+ "\doi{" doi * "}" *
+ }
+ if$
+}
+FUNCTION {format.note}
+{
+ note empty$
+ { "" }
+ { note #1 #1 substring$
+ duplicate$ "{" =
+ 'skip$
+ { output.state mid.sentence =
+ { "l" }
+ { "u" }
+ if$
+ change.case$
+ }
+ if$
+ note #2 global.max$ substring$ * "note" bibinfo.check
+ }
+ if$
+}
+
+FUNCTION {format.title}
+{ title
+ "title" bibinfo.check
+ duplicate$ empty$ 'skip$
+ {
+ "\enquote{" swap$ *
+ add.period$ "}" *
+ }
+ if$
+}
+FUNCTION {format.full.names}
+{'s :=
+ "" 't :=
+ #1 'nameptr :=
+ s num.names$ 'numnames :=
+ numnames 'namesleft :=
+ { namesleft #0 > }
+ { s nameptr
+ "{vv~}{ll}" format.name$
+ 't :=
+ nameptr #1 >
+ {
+ namesleft #1 >
+ { ", " * t * }
+ {
+ s nameptr "{ll}" format.name$ duplicate$ "others" =
+ { 't := }
+ { pop$ }
+ if$
+ t "others" =
+ {
+ " " * bbl.etal emphasize *
+ }
+ {
+ numnames #2 >
+ { "," * }
+ 'skip$
+ if$
+ bbl.and
+ space.word * t *
+ }
+ if$
+ }
+ if$
+ }
+ 't
+ if$
+ nameptr #1 + 'nameptr :=
+ namesleft #1 - 'namesleft :=
+ }
+ while$
+}
+
+FUNCTION {author.editor.key.full}
+{ author empty$
+ { editor empty$
+ { key empty$
+ { cite$ #1 #3 substring$ }
+ 'key
+ if$
+ }
+ { editor format.full.names }
+ if$
+ }
+ { author format.full.names }
+ if$
+}
+
+FUNCTION {author.key.full}
+{ author empty$
+ { key empty$
+ { cite$ #1 #3 substring$ }
+ 'key
+ if$
+ }
+ { author format.full.names }
+ if$
+}
+
+FUNCTION {editor.key.full}
+{ editor empty$
+ { key empty$
+ { cite$ #1 #3 substring$ }
+ 'key
+ if$
+ }
+ { editor format.full.names }
+ if$
+}
+
+FUNCTION {make.full.names}
+{ type$ "book" =
+ type$ "inbook" =
+ or
+ 'author.editor.key.full
+ { type$ "proceedings" =
+ 'editor.key.full
+ 'author.key.full
+ if$
+ }
+ if$
+}
+
+FUNCTION {output.bibitem}
+{ newline$
+ "\bibitem[{" write$
+ label write$
+ ")" make.full.names duplicate$ short.list =
+ { pop$ }
+ { * }
+ if$
+ "}]{" * write$
+ cite$ write$
+ "}" write$
+ newline$
+ ""
+ before.all 'output.state :=
+}
+
+FUNCTION {n.dashify}
+{
+ 't :=
+ ""
+ { t empty$ not }
+ { t #1 #1 substring$ "-" =
+ { t #1 #2 substring$ "--" = not
+ { "--" *
+ t #2 global.max$ substring$ 't :=
+ }
+ { { t #1 #1 substring$ "-" = }
+ { "-" *
+ t #2 global.max$ substring$ 't :=
+ }
+ while$
+ }
+ if$
+ }
+ { t #1 #1 substring$ *
+ t #2 global.max$ substring$ 't :=
+ }
+ if$
+ }
+ while$
+}
+
+FUNCTION {word.in}
+{ bbl.in capitalize
+ " " * }
+
+FUNCTION {format.date}
+{ year "year" bibinfo.check duplicate$ empty$
+ {
+ "empty year in " cite$ * "; set to ????" * warning$
+ pop$ "????"
+ }
+ 'skip$
+ if$
+ extra.label *
+ before.all 'output.state :=
+ " (" swap$ * ")" *
+}
+FUNCTION {format.btitle}
+{ title "title" bibinfo.check
+ duplicate$ empty$ 'skip$
+ {
+ emphasize
+ }
+ if$
+}
+FUNCTION {either.or.check}
+{ empty$
+ 'pop$
+ { "can't use both " swap$ * " fields in " * cite$ * warning$ }
+ if$
+}
+FUNCTION {format.bvolume}
+{ volume empty$
+ { "" }
+ { bbl.volume volume tie.or.space.prefix
+ "volume" bibinfo.check * *
+ series "series" bibinfo.check
+ duplicate$ empty$ 'pop$
+ { swap$ bbl.of space.word * swap$
+ emphasize * }
+ if$
+ "volume and number" number either.or.check
+ }
+ if$
+}
+FUNCTION {format.number.series}
+{ volume empty$
+ { number empty$
+ { series field.or.null }
+ { series empty$
+ { number "number" bibinfo.check }
+ { output.state mid.sentence =
+ { bbl.number }
+ { bbl.number capitalize }
+ if$
+ number tie.or.space.prefix "number" bibinfo.check * *
+ bbl.in space.word *
+ series "series" bibinfo.check *
+ }
+ if$
+ }
+ if$
+ }
+ { "" }
+ if$
+}
+
+FUNCTION {format.edition}
+{ edition duplicate$ empty$ 'skip$
+ {
+ output.state mid.sentence =
+ { "l" }
+ { "t" }
+ if$ change.case$
+ "edition" bibinfo.check
+ " " * bbl.edition *
+ }
+ if$
+}
+INTEGERS { multiresult }
+FUNCTION {multi.page.check}
+{ 't :=
+ #0 'multiresult :=
+ { multiresult not
+ t empty$ not
+ and
+ }
+ { t #1 #1 substring$
+ duplicate$ "-" =
+ swap$ duplicate$ "," =
+ swap$ "+" =
+ or or
+ { #1 'multiresult := }
+ { t #2 global.max$ substring$ 't := }
+ if$
+ }
+ while$
+ multiresult
+}
+FUNCTION {format.pages}
+{ pages duplicate$ empty$ 'skip$
+ { duplicate$ multi.page.check
+ {
+ bbl.pages swap$
+ n.dashify
+ }
+ {
+ bbl.page swap$
+ }
+ if$
+ tie.or.space.prefix
+ "pages" bibinfo.check
+ * *
+ }
+ if$
+}
+FUNCTION {format.journal.pages}
+{ pages duplicate$ empty$ 'pop$
+ { swap$ duplicate$ empty$
+ { pop$ pop$ format.pages }
+ {
+ ", " *
+ swap$
+ n.dashify
+ "pages" bibinfo.check
+ *
+ }
+ if$
+ }
+ if$
+}
+FUNCTION {format.journal.eid}
+{ eid "eid" bibinfo.check
+ duplicate$ empty$ 'pop$
+ { swap$ duplicate$ empty$ 'skip$
+ {
+ ", " *
+ }
+ if$
+ swap$ *
+ numpages empty$ 'skip$
+ { bbl.eidpp numpages tie.or.space.prefix
+ "numpages" bibinfo.check * *
+ " (" swap$ * ")" * *
+ }
+ if$
+ }
+ if$
+}
+FUNCTION {format.vol.num.pages}
+{ volume field.or.null
+ duplicate$ empty$ 'skip$
+ {
+ "volume" bibinfo.check
+ }
+ if$
+ bolden
+ number "number" bibinfo.check duplicate$ empty$ 'skip$
+ {
+ swap$ duplicate$ empty$
+ { "there's a number but no volume in " cite$ * warning$ }
+ 'skip$
+ if$
+ swap$
+ "(" swap$ * ")" *
+ }
+ if$ *
+ eid empty$
+ { format.journal.pages }
+ { format.journal.eid }
+ if$
+}
+
+FUNCTION {format.chapter.pages}
+{ chapter empty$
+ 'format.pages
+ { type empty$
+ { bbl.chapter }
+ { type "l" change.case$
+ "type" bibinfo.check
+ }
+ if$
+ chapter tie.or.space.prefix
+ "chapter" bibinfo.check
+ * *
+ pages empty$
+ 'skip$
+ { ", " * format.pages * }
+ if$
+ }
+ if$
+}
+
+FUNCTION {format.booktitle}
+{
+ booktitle "booktitle" bibinfo.check
+ emphasize
+}
+FUNCTION {format.in.ed.booktitle}
+{ format.booktitle duplicate$ empty$ 'skip$
+ {
+ editor "editor" format.names.ed duplicate$ empty$ 'pop$
+ {
+ " " *
+ get.bbl.editor
+ "(" swap$ * "), " *
+ * swap$
+ * }
+ if$
+ word.in swap$ *
+ }
+ if$
+}
+FUNCTION {format.thesis.type}
+{ type duplicate$ empty$
+ 'pop$
+ { swap$ pop$
+ "t" change.case$ "type" bibinfo.check
+ }
+ if$
+}
+FUNCTION {format.tr.number}
+{ number "number" bibinfo.check
+ type duplicate$ empty$
+ { pop$ bbl.techrep }
+ 'skip$
+ if$
+ "type" bibinfo.check
+ swap$ duplicate$ empty$
+ { pop$ "t" change.case$ }
+ { tie.or.space.prefix * * }
+ if$
+}
+FUNCTION {format.article.crossref}
+{
+ word.in
+ " \cite{" * crossref * "}" *
+}
+FUNCTION {format.book.crossref}
+{ volume duplicate$ empty$
+ { "empty volume in " cite$ * "'s crossref of " * crossref * warning$
+ pop$ word.in
+ }
+ { bbl.volume
+ capitalize
+ swap$ tie.or.space.prefix "volume" bibinfo.check * * bbl.of space.word *
+ }
+ if$
+ " \cite{" * crossref * "}" *
+}
+FUNCTION {format.incoll.inproc.crossref}
+{
+ word.in
+ " \cite{" * crossref * "}" *
+}
+FUNCTION {format.org.or.pub}
+{ 't :=
+ ""
+ address empty$ t empty$ and
+ 'skip$
+ {
+ t empty$
+ { address "address" bibinfo.check *
+ }
+ { t *
+ address empty$
+ 'skip$
+ { ", " * address "address" bibinfo.check * }
+ if$
+ }
+ if$
+ }
+ if$
+}
+FUNCTION {format.publisher.address}
+{ publisher "publisher" bibinfo.warn format.org.or.pub
+}
+
+FUNCTION {format.organization.address}
+{ organization "organization" bibinfo.check format.org.or.pub
+}
+
+FUNCTION {article}
+{ output.bibitem
+ format.authors "author" output.check
+ author format.key output
+ format.date "year" output.check
+ date.block
+ format.title "title" output.check
+ new.block
+ crossref missing$
+ {
+ journal
+ "journal" bibinfo.check
+ emphasize
+ "journal" output.check
+ format.vol.num.pages output
+ }
+ { format.article.crossref output.nonnull
+ format.pages output
+ }
+ if$
+ format.issn output
+ format.doi output
+ new.block
+ format.note output
+ format.eprint output
+ format.url output
+ fin.entry
+}
+FUNCTION {book}
+{ output.bibitem
+ author empty$
+ { format.editors "author and editor" output.check
+ editor format.key output
+ }
+ { format.authors output.nonnull
+ crossref missing$
+ { "author and editor" editor either.or.check }
+ 'skip$
+ if$
+ }
+ if$
+ format.date "year" output.check
+ date.block
+ format.btitle "title" output.check
+ crossref missing$
+ { format.bvolume output
+ new.block
+ format.number.series output
+ format.edition output
+ new.sentence
+ format.publisher.address output
+ }
+ {
+ new.block
+ format.book.crossref output.nonnull
+ }
+ if$
+ format.isbn output
+ format.doi output
+ new.block
+ format.note output
+ format.eprint output
+ format.url output
+ fin.entry
+}
+FUNCTION {booklet}
+{ output.bibitem
+ format.authors output
+ author format.key output
+ format.date "year" output.check
+ date.block
+ format.title "title" output.check
+ new.block
+ howpublished "howpublished" bibinfo.check output
+ address "address" bibinfo.check output
+ format.isbn output
+ format.doi output
+ new.block
+ format.note output
+ format.eprint output
+ format.url output
+ fin.entry
+}
+
+FUNCTION {inbook}
+{ output.bibitem
+ author empty$
+ { format.editors "author and editor" output.check
+ editor format.key output
+ }
+ { format.authors output.nonnull
+ crossref missing$
+ { "author and editor" editor either.or.check }
+ 'skip$
+ if$
+ }
+ if$
+ format.date "year" output.check
+ date.block
+ format.btitle "title" output.check
+ crossref missing$
+ {
+ format.bvolume output
+ format.chapter.pages "chapter and pages" output.check
+ new.block
+ format.number.series output
+ format.edition output
+ new.sentence
+ format.publisher.address output
+ }
+ {
+ format.chapter.pages "chapter and pages" output.check
+ new.block
+ format.book.crossref output.nonnull
+ }
+ if$
+ crossref missing$
+ { format.isbn output }
+ 'skip$
+ if$
+ format.doi output
+ new.block
+ format.note output
+ format.eprint output
+ format.url output
+ fin.entry
+}
+
+FUNCTION {incollection}
+{ output.bibitem
+ format.authors "author" output.check
+ author format.key output
+ format.date "year" output.check
+ date.block
+ format.title "title" output.check
+ new.block
+ crossref missing$
+ { format.in.ed.booktitle "booktitle" output.check
+ format.bvolume output
+ format.number.series output
+ format.edition output
+ format.chapter.pages output
+ new.sentence
+ format.publisher.address output
+ format.isbn output
+ }
+ { format.incoll.inproc.crossref output.nonnull
+ format.chapter.pages output
+ }
+ if$
+ format.doi output
+ new.block
+ format.note output
+ format.eprint output
+ format.url output
+ fin.entry
+}
+FUNCTION {inproceedings}
+{ output.bibitem
+ format.authors "author" output.check
+ author format.key output
+ format.date "year" output.check
+ date.block
+ format.title "title" output.check
+ new.block
+ crossref missing$
+ { format.in.ed.booktitle "booktitle" output.check
+ format.bvolume output
+ format.number.series output
+ format.pages output
+ new.sentence
+ publisher empty$
+ { format.organization.address output }
+ { organization "organization" bibinfo.check output
+ format.publisher.address output
+ }
+ if$
+ format.isbn output
+ format.issn output
+ }
+ { format.incoll.inproc.crossref output.nonnull
+ format.pages output
+ }
+ if$
+ format.doi output
+ new.block
+ format.note output
+ format.eprint output
+ format.url output
+ fin.entry
+}
+FUNCTION {conference} { inproceedings }
+FUNCTION {manual}
+{ output.bibitem
+ format.authors output
+ author format.key output
+ format.date "year" output.check
+ date.block
+ format.btitle "title" output.check
+ organization address new.block.checkb
+ organization "organization" bibinfo.check output
+ address "address" bibinfo.check output
+ format.edition output
+ format.doi output
+ new.block
+ format.note output
+ format.eprint output
+ format.url output
+ fin.entry
+}
+
+FUNCTION {mastersthesis}
+{ output.bibitem
+ format.authors "author" output.check
+ author format.key output
+ format.date "year" output.check
+ date.block
+ format.btitle
+ "title" output.check
+ new.block
+ bbl.mthesis format.thesis.type output.nonnull
+ school "school" bibinfo.warn output
+ address "address" bibinfo.check output
+ format.doi output
+ new.block
+ format.note output
+ format.eprint output
+ format.url output
+ fin.entry
+}
+
+FUNCTION {misc}
+{ output.bibitem
+ format.authors output
+ author format.key output
+ format.date "year" output.check
+ date.block
+ format.title output
+ new.block
+ howpublished "howpublished" bibinfo.check output
+ format.doi output
+ new.block
+ format.note output
+ format.eprint output
+ format.url output
+ fin.entry
+}
+FUNCTION {phdthesis}
+{ output.bibitem
+ format.authors "author" output.check
+ author format.key output
+ format.date "year" output.check
+ date.block
+ format.btitle
+ "title" output.check
+ new.block
+ bbl.phdthesis format.thesis.type output.nonnull
+ school "school" bibinfo.warn output
+ address "address" bibinfo.check output
+ format.doi output
+ new.block
+ format.note output
+ format.eprint output
+ format.url output
+ fin.entry
+}
+
+FUNCTION {proceedings}
+{ output.bibitem
+ format.editors output
+ editor format.key output
+ format.date "year" output.check
+ date.block
+ format.btitle "title" output.check
+ format.bvolume output
+ format.number.series output
+ new.sentence
+ publisher empty$
+ { format.organization.address output }
+ { organization "organization" bibinfo.check output
+ format.publisher.address output
+ }
+ if$
+ format.isbn output
+ format.issn output
+ format.doi output
+ new.block
+ format.note output
+ format.eprint output
+ format.url output
+ fin.entry
+}
+
+FUNCTION {techreport}
+{ output.bibitem
+ format.authors "author" output.check
+ author format.key output
+ format.date "year" output.check
+ date.block
+ format.title
+ "title" output.check
+ new.block
+ format.tr.number emphasize output.nonnull
+ institution "institution" bibinfo.warn output
+ address "address" bibinfo.check output
+ format.doi output
+ new.block
+ format.note output
+ format.eprint output
+ format.url output
+ fin.entry
+}
+
+FUNCTION {unpublished}
+{ output.bibitem
+ format.authors "author" output.check
+ author format.key output
+ format.date "year" output.check
+ date.block
+ format.title "title" output.check
+ format.doi output
+ new.block
+ format.note "note" output.check
+ format.eprint output
+ format.url output
+ fin.entry
+}
+
+FUNCTION {default.type} { misc }
+READ
+FUNCTION {sortify}
+{ purify$
+ "l" change.case$
+}
+INTEGERS { len }
+FUNCTION {chop.word}
+{ 's :=
+ 'len :=
+ s #1 len substring$ =
+ { s len #1 + global.max$ substring$ }
+ 's
+ if$
+}
+FUNCTION {format.lab.names}
+{ 's :=
+ "" 't :=
+ s #1 "{vv~}{ll}" format.name$
+ s num.names$ duplicate$
+ #2 >
+ { pop$
+ " " * bbl.etal emphasize *
+ }
+ { #2 <
+ 'skip$
+ { s #2 "{ff }{vv }{ll}{ jj}" format.name$ "others" =
+ {
+ " " * bbl.etal emphasize *
+ }
+ { bbl.and space.word * s #2 "{vv~}{ll}" format.name$
+ * }
+ if$
+ }
+ if$
+ }
+ if$
+}
+
+FUNCTION {author.key.label}
+{ author empty$
+ { key empty$
+ { cite$ #1 #3 substring$ }
+ 'key
+ if$
+ }
+ { author format.lab.names }
+ if$
+}
+
+FUNCTION {author.editor.key.label}
+{ author empty$
+ { editor empty$
+ { key empty$
+ { cite$ #1 #3 substring$ }
+ 'key
+ if$
+ }
+ { editor format.lab.names }
+ if$
+ }
+ { author format.lab.names }
+ if$
+}
+
+FUNCTION {editor.key.label}
+{ editor empty$
+ { key empty$
+ { cite$ #1 #3 substring$ }
+ 'key
+ if$
+ }
+ { editor format.lab.names }
+ if$
+}
+
+FUNCTION {calc.short.authors}
+{ type$ "book" =
+ type$ "inbook" =
+ or
+ 'author.editor.key.label
+ { type$ "proceedings" =
+ 'editor.key.label
+ 'author.key.label
+ if$
+ }
+ if$
+ 'short.list :=
+}
+
+FUNCTION {calc.label}
+{ calc.short.authors
+ short.list
+ "("
+ *
+ year duplicate$ empty$
+ short.list key field.or.null = or
+ { pop$ "" }
+ 'skip$
+ if$
+ *
+ 'label :=
+}
+
+FUNCTION {sort.format.names}
+{ 's :=
+ #1 'nameptr :=
+ ""
+ s num.names$ 'numnames :=
+ numnames 'namesleft :=
+ { namesleft #0 > }
+ { s nameptr
+ "{vv{ } }{ll{ }}{ f{ }}{ jj{ }}"
+ format.name$ 't :=
+ nameptr #1 >
+ {
+ " " *
+ namesleft #1 = t "others" = and
+ { "zzzzz" 't := }
+ 'skip$
+ if$
+ t sortify *
+ }
+ { t sortify * }
+ if$
+ nameptr #1 + 'nameptr :=
+ namesleft #1 - 'namesleft :=
+ }
+ while$
+}
+
+FUNCTION {sort.format.title}
+{ 't :=
+ "A " #2
+ "An " #3
+ "The " #4 t chop.word
+ chop.word
+ chop.word
+ sortify
+ #1 global.max$ substring$
+}
+FUNCTION {author.sort}
+{ author empty$
+ { key empty$
+ { "to sort, need author or key in " cite$ * warning$
+ ""
+ }
+ { key sortify }
+ if$
+ }
+ { author sort.format.names }
+ if$
+}
+FUNCTION {author.editor.sort}
+{ author empty$
+ { editor empty$
+ { key empty$
+ { "to sort, need author, editor, or key in " cite$ * warning$
+ ""
+ }
+ { key sortify }
+ if$
+ }
+ { editor sort.format.names }
+ if$
+ }
+ { author sort.format.names }
+ if$
+}
+FUNCTION {editor.sort}
+{ editor empty$
+ { key empty$
+ { "to sort, need editor or key in " cite$ * warning$
+ ""
+ }
+ { key sortify }
+ if$
+ }
+ { editor sort.format.names }
+ if$
+}
+FUNCTION {presort}
+{ calc.label
+ label sortify
+ " "
+ *
+ type$ "book" =
+ type$ "inbook" =
+ or
+ 'author.editor.sort
+ { type$ "proceedings" =
+ 'editor.sort
+ 'author.sort
+ if$
+ }
+ if$
+ #1 entry.max$ substring$
+ 'sort.label :=
+ sort.label
+ *
+ " "
+ *
+ title field.or.null
+ sort.format.title
+ *
+ #1 entry.max$ substring$
+ 'sort.key$ :=
+}
+
+ITERATE {presort}
+SORT
+STRINGS { last.label next.extra }
+INTEGERS { last.extra.num last.extra.num.extended last.extra.num.blank number.label }
+FUNCTION {initialize.extra.label.stuff}
+{ #0 int.to.chr$ 'last.label :=
+ "" 'next.extra :=
+ #0 'last.extra.num :=
+ "a" chr.to.int$ #1 - 'last.extra.num.blank :=
+ last.extra.num.blank 'last.extra.num.extended :=
+ #0 'number.label :=
+}
+FUNCTION {forward.pass}
+{ last.label label =
+ { last.extra.num #1 + 'last.extra.num :=
+ last.extra.num "z" chr.to.int$ >
+ { "a" chr.to.int$ 'last.extra.num :=
+ last.extra.num.extended #1 + 'last.extra.num.extended :=
+ }
+ 'skip$
+ if$
+ last.extra.num.extended last.extra.num.blank >
+ { last.extra.num.extended int.to.chr$
+ last.extra.num int.to.chr$
+ * 'extra.label := }
+ { last.extra.num int.to.chr$ 'extra.label := }
+ if$
+ }
+ { "a" chr.to.int$ 'last.extra.num :=
+ "" 'extra.label :=
+ label 'last.label :=
+ }
+ if$
+ number.label #1 + 'number.label :=
+}
+FUNCTION {reverse.pass}
+{ next.extra "b" =
+ { "a" 'extra.label := }
+ 'skip$
+ if$
+ extra.label 'next.extra :=
+ extra.label
+ duplicate$ empty$
+ 'skip$
+ { "{\natexlab{" swap$ * "}}" * }
+ if$
+ 'extra.label :=
+ label extra.label * 'label :=
+}
+EXECUTE {initialize.extra.label.stuff}
+ITERATE {forward.pass}
+REVERSE {reverse.pass}
+FUNCTION {bib.sort.order}
+{ sort.label
+ " "
+ *
+ year field.or.null sortify
+ *
+ " "
+ *
+ title field.or.null
+ sort.format.title
+ *
+ #1 entry.max$ substring$
+ 'sort.key$ :=
+}
+ITERATE {bib.sort.order}
+SORT
+FUNCTION {begin.bib}
+{ preamble$ empty$
+ 'skip$
+ { preamble$ write$ newline$ }
+ if$
+ "\begin{thebibliography}{" number.label int.to.str$ * "}" *
+ write$ newline$
+ "\newcommand{\enquote}[1]{``#1''}"
+ write$ newline$
+ "\providecommand{\natexlab}[1]{#1}"
+ write$ newline$
+ "\providecommand{\url}[1]{\texttt{#1}}"
+ write$ newline$
+ "\providecommand{\urlprefix}{URL }"
+ write$ newline$
+ "\expandafter\ifx\csname urlstyle\endcsname\relax"
+ write$ newline$
+ " \providecommand{\doi}[1]{doi:\discretionary{}{}{}#1}\else"
+ write$ newline$
+ " \providecommand{\doi}{doi:\discretionary{}{}{}\begingroup \urlstyle{rm}\Url}\fi"
+ write$ newline$
+ "\providecommand{\eprint}[2][]{\url{#2}}"
+ write$ newline$
+}
+EXECUTE {begin.bib}
+EXECUTE {init.state.consts}
+ITERATE {call.type$}
+FUNCTION {end.bib}
+{ newline$
+ "\end{thebibliography}" write$ newline$
+}
+EXECUTE {end.bib}
+%% End of customized bst file
+%%
+%% End of file `jss.bst'.
diff --git a/LegendMedCentral/missing.pdf b/LegendMedCentral/missing.pdf
new file mode 100644
index 00000000..d0aa6117
Binary files /dev/null and b/LegendMedCentral/missing.pdf differ
diff --git a/LegendMedCentral/ohdsi.bib b/LegendMedCentral/ohdsi.bib
new file mode 100644
index 00000000..0fb31fdc
--- /dev/null
+++ b/LegendMedCentral/ohdsi.bib
@@ -0,0 +1,167 @@
+@article{schuemie2018improving,
+ title={Improving reproducibility by using high-throughput observational studies with empirical calibration},
+ journal={Philosophical Transactions of the Royal Society A},
+ author={Schuemie, MJ and Ryan, PB and Hripcsak, G and Madigan, D and Suchard, MA},
+ volume={376},
+ pages={20170356},
+ year={2018},
+}
+
+@article{schuemie2018empirical,
+ title={Empirical confidence interval calibration for population-level effect estimation studies in observational healthcare data},
+ author={Schuemie, Martijn J and Hripcsak, George and Ryan, Patrick B and Madigan, David and Suchard, Marc A},
+ journal={Proceedings of the National Academy of Sciences},
+ pages={201708282},
+ year={2018},
+ publisher={National Acad Sciences}
+}
+
+@article{hripcsak2015observational,
+ title={Observational Health Data Sciences and Informatics (OHDSI): Opportunities for Observational Researchers.},
+ author={Hripcsak, G and Duke, JD and Shah, NH and Reich, CG and Huser, V and Schuemie, MJ and Suchard, MA and Park, RW and Wong, IC and Rijnbeek, PR and others},
+ journal={Studies in health technology and informatics},
+ volume={216},
+ pages={574--578},
+ year={2015}
+}
+
+@article{voss2017accuracy,
+ title={Accuracy of an automated knowledge base for identifying drug adverse reactions},
+ author={Voss, Erica A and Boyce, Richard D and Ryan, Patrick B and van der Lei, Johan and Rijnbeek, Peter R and Schuemie, Martijn J},
+ journal={J Biomed Inform},
+ volume={66},
+ pages={72--81},
+ year={2017},
+ publisher={Elsevier}
+}
+
+@article{schuemie2016robust,
+ title={Robust empirical calibration of p-values using observational data},
+ author={Schuemie, Martijn J and Hripcsak, George and Ryan, Patrick B and Madigan, David and Suchard, Marc A},
+ journal={Statistics in Medicine},
+ volume={35},
+ number={22},
+ pages={3883--3888},
+ year={2016},
+ publisher={Wiley Online Library}
+}
+
+@article{schuemie2014interpreting,
+ title={Interpreting observational studies: why empirical calibration is needed to correct p-values},
+ author={Schuemie, Martijn J and Ryan, Patrick B and DuMouchel, William and Suchard, Marc A and Madigan, David},
+ journal={Statistics in medicine},
+ volume={33},
+ number={2},
+ pages={209--218},
+ year={2014},
+ publisher={Wiley Online Library}
+}
+
+@article{overhage2012validation,
+author = {J.M. Overhage and P.B. Ryan and C.G. Reich and A.G. Hartzema and P.E. Stang},
+title = {Validation of a common data model for active safety surveillance research},
+journal = {Journal of the American Medical Informatics Association},
+year = {2012},
+volume = {19},
+pages={54--60},
+}
+
+@article{rosenbaum1983central,
+title={The central role of the propensity score in observational studies for causal effects},
+author={Rosenbaum, Paul R and Rubin, Donald B},
+journal={Biometrika},
+volume={70},
+number={1},
+pages={41--55},
+year={1983},
+publisher={Biometrika Trust}
+}
+
+ @Manual{schuemie2018featureextration,
+ title = {FeatureExtraction: Generating Features for a Cohort},
+ author = {Martijn J. Schuemie and Marc A. Suchard and Patrick B. Ryan and Jenna Reps},
+ year = {2018},
+ note = {R package version 2.1.5},
+ }
+
+
+ @Manual{schuemie2018cohortmethod,
+ title = {CohortMethod: New-user cohort method with large scale propensity and outcome
+models},
+ author = {Martijn J. Schuemie and Marc A. Suchard and Patrick B. Ryan},
+ year = {2018},
+ note = {R package version 2.5.1},
+ }
+
+@article{ryan2013empirical,
+ title={Empirical performance of a new user cohort method: lessons for developing a risk identification and analysis system},
+ author={Ryan, Patrick B and Schuemie, Martijn J and Gruber, Susan and Zorych, Ivan and Madigan, David},
+ journal={Drug Safety},
+ volume={36},
+ number={1},
+ pages={59--72},
+ year={2013},
+ publisher={Springer}
+}
+
+@article{suchard2013massive,
+ author={Suchard, MA and Simpson, SE and Zorych, I and Ryan, P and Madigan, D},
+ title={Massive parallelization of serial inference algorithms for a complex generalized linear model},
+ journal={Transactions on Modeling and Computer Simulation},
+ year={2013},
+ volume={23},
+ pages={10},
+ }
+
+@article{austin2009balance,
+ title={Balance diagnostics for comparing the distribution of baseline covariates between treatment groups in propensity-score matched samples},
+ author={Austin, Peter C},
+ journal={Statistics in medicine},
+ volume={28},
+ number={25},
+ pages={3083--3107},
+ year={2009},
+ publisher={Wiley Online Library}
+}
+
+@article{winnenburg2015leveraging,
+ title={Leveraging {MEDLINE} indexing for pharmacovigilance--Inherent limitations and mitigation strategies},
+ author={Winnenburg, Rainer and Sorbello, Alfred and Ripple, Anna and Harpaz, Rave and Tonning, Joseph and Szarfman, Ana and Francis, Henry and Bodenreider, Olivier},
+ journal={Journal of Biomedical Informatics},
+ volume={57},
+ pages={425--435},
+ year={2015},
+ publisher={Elsevier}
+}
+
+@article{duke2013consistency,
+ title={Consistency in the safety labeling of bioequivalent medications},
+ author={Duke, Jon and Friedlin, Jeff and Li, Xiaochun},
+ journal={Pharmacoepidemiology and Drug Safety},
+ volume={22},
+ number={3},
+ pages={294--301},
+ year={2013},
+ publisher={Wiley Online Library}
+}
+
+@article{evans2001use,
+ title={Use of proportional reporting ratios ({PRR}s) for signal generation from spontaneous adverse drug reaction reports},
+ author={Evans, SJW and Waller, Patrick C and Davis, S},
+ journal={Pharmacoepidemiology and Drug Safety},
+ volume={10},
+ number={6},
+ pages={483--486},
+ year={2001},
+ publisher={Wiley Online Library}
+}
+
+@article{banda2016curated,
+ title={A curated and standardized adverse drug event resource to accelerate drug safety research},
+ author={Banda, Juan M and Evans, Lee and Vanguri, Rami S and Tatonetti, Nicholas P and Ryan, Patrick B and Shah, Nigam H},
+ journal={Scientific data},
+ volume={3},
+ pages={160026},
+ year={2016},
+ publisher={Nature Publishing Group}
+}
diff --git a/LegendMedCentral/pnas-markdown.cls b/LegendMedCentral/pnas-markdown.cls
new file mode 100644
index 00000000..6ece0473
--- /dev/null
+++ b/LegendMedCentral/pnas-markdown.cls
@@ -0,0 +1,662 @@
+%%%
+%% ping.cls
+%% based on pnas-new.cls and supporting material from
+%% http://www.pnas.org/site/authors/latex.xhtml
+%% as well as local changes
+%%
+%% Dirk Eddelbuettel and James Balamuta
+%% August - September 2017
+%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% pnas-new.cls, v1.2, 2016/02/28
+%
+% This class file enables authors to prepare research
+% articles for submission to PNAS.
+%
+% Please note that whilst this template provides a
+% preview of the typeset manuscript for submission, it
+% will not necessarily be the final publication layout.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% This work may be distributed and/or modified under the
+% conditions of the LaTeX Project Public License, either
+% version 1.3 of this license or any later version.
+% The latest version of this license is in
+% http://www.latex-project.org/lppl.txt and
+% version 1.3 or later is part of all distributions
+% of LaTeX version 2005/12/01 or later.
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% For use with latex+dvipdfm, pdflatex, xelatex & lualatex
+% For compiling with plain latex, please use latex+dvipdfm
+% to produce the PDF, not dvis -> ps -> pdf nor dvipdf
+%
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesClass{pnas-new}[28/02/2015, v1.2]
+\AtEndOfClass{\RequirePackage{microtype}}
+% Option for line numbers
+\newif\if@pnaslineno
+\DeclareOption{lineno}{\@pnaslinenotrue}
+\DeclareOption*{\PassOptionsToClass{\CurrentOption}{extarticle}}
+\ProcessOptions*
+\LoadClass{extarticle}
+
+%% Fonts and language
+\RequirePackage[utf8]{inputenc}
+\RequirePackage[english]{babel}
+\RequirePackage{amsmath,amsfonts,amssymb}
+\RequirePackage{lmodern}
+\RequirePackage[scaled]{helvet}
+\RequirePackage[T1]{fontenc}
+\RequirePackage{lettrine} % For dropped capitals
+
+%% For the Significance Statement & footnote on the first page
+\RequirePackage{afterpage}
+\RequirePackage{ifpdf,ifxetex}
+\ifpdf\else
+ \ifxetex\else
+ \def\pgfsysdriver{pgfsys-dvipdfm.def}
+ \pdfpagewidth=\paperwidth
+ \pdfpageheight=\paperheight
+\fi\fi
+\RequirePackage[table]{xcolor}
+\RequirePackage{tikz}
+\RequirePackage[framemethod=tikz]{mdframed}
+
+%% For single column equations and balancing the columns on final page
+%\RequirePackage{widetext}
+%% BEGIN
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{widetext}
+
+%% Mimics the widetext environment of revtex4 for any other class package
+%% Eg: article.cls
+%%
+%% Compiled by: Anjishnu Sarkar
+%%
+%% Advantages:
+%% *) Supports float (eg: figure) in two column format (Advantage over
+%% multicol package)
+%% *) One and twocolumn exist on the same page
+%% *) Flow of text shown via rule
+%% *) Equal height of text when in two column format
+%%
+%% Acknowledgment(s):
+%% 1. Instead of re-inventing the wheel, two packages (flushend, cuted) of
+%% the sttools bundle are used. The sttools bundle is available from CTAN.
+%% Lisence of these packages rests with their corresponding author.
+%% Any bug/problem with flushend and cuted should be forwarded to their
+%% corresponding package authors.
+%% 2. The idea of the rule came from the following latex community website
+%% http://www.latex-community.org/forum/viewtopic.php?f=5&t=2770
+%%
+%% This package just defines the widetext environment and the rules.
+%%
+%% Usage:
+%% \documentclass[a4paper,12pt,twocolumn]{article}
+%% \usepackage{widetext}
+%%
+%% \begin{document}
+%%
+%% Some text in twocolumn
+%%
+%% \begin{widetext}
+%% Text in onecolumn format.
+%% \end{widetext}
+%%
+%% Some more text in twocolumn
+%%
+%% \end{document}
+%%%%%%%%%%%%%%%%%%%%
+
+%% Package required for equal height while in 2 columns format
+\IfFileExists{flushend.sty}
+ {\RequirePackage{flushend}}
+ {\typeout{}
+ \typeout{Package widetext error: Install the flushend package which is
+ a part of sttools bundle. Available from CTAN.}
+ \typeout{}
+ \stop
+ }
+
+%% Package required for onecolumn and twocolumn to exist on the same page.
+%% and also required for widetext environment.
+\IfFileExists{cuted.sty}
+ {\RequirePackage{cuted}}
+ {\typeout{}
+ \typeout{Package widetext error: Install the cuted package which is
+ a part of sttools bundle. Available from CTAN.}
+ \typeout{}
+ \stop
+ }
+
+
+\newlength\@parindent
+\setlength\@parindent{\parindent}
+
+\if@twocolumn
+ \newenvironment{widetext}
+ {%
+ \begin{strip}
+ \rule{\dimexpr(0.5\textwidth-0.5\columnsep-0.4pt)}{0.4pt}%
+ \rule{0.4pt}{6pt}
+ \par %\vspace{6pt}
+ \parindent \@parindent
+ }%
+ {%
+ \par
+ \hfill\rule[-6pt]{0.4pt}{6.4pt}%
+ \rule{\dimexpr(0.5\textwidth-0.5\columnsep-1pt)}{0.4pt}
+ \end{strip}
+ }
+\else
+ \newenvironment{widetext}{}{}
+\fi
+%% END
+
+%% Hyperlinking
+% from below
+%\definecolor{pnasbluetext}{RGB}{0,101,165} %
+%\definecolor{pnasblueback}{RGB}{205,217,235} %
+\RequirePackage[colorlinks=true, allcolors=pnasbluetext]{hyperref}
+
+%% Set up main title page fonts
+\newcommand{\headerfont}{\normalfont\sffamily\fontsize{7}{9} \selectfont}
+\newcommand{\footerfont}{\normalfont\sffamily\fontsize{7}{9} \selectfont}
+\newcommand{\titlefont}{\fontfamily{lmss}\bfseries\fontsize{22pt}{24pt}\selectfont}
+\newcommand{\dropcapfont}{\fontfamily{lmss}\bfseries\fontsize{26pt}{28pt}\selectfont}
+\newcommand{\datesfont}{\normalfont\sffamily\fontsize{7}{8}\selectfont}
+\newcommand{\absfont}{\normalfont\sffamily\bfseries\fontsize{8}{11}\selectfont}
+\newcommand{\keywordsfont}{\normalfont\rmfamily\fontsize{7}{10}\selectfont}
+\newcommand{\copyrightfont}{\normalfont\rmfamily\fontsize{6}{8}\selectfont}
+
+%% Set URL link color & font
+\renewcommand\UrlFont{\color{pnasbluetext}\sffamily}
+
+%% Author and affiliation
+\RequirePackage{authblk}
+\setlength{\affilsep}{8.5pt} % 16.5pts between base of author line and base of affil line
+\renewcommand\Authfont{\color{color0}\normalfont\sffamily\bfseries\fontsize{9}{11}\selectfont}
+\renewcommand\Affilfont{\color{color0}\normalfont\sffamily\fontsize{7}{8}\selectfont}
+\makeatletter
+\renewcommand\AB@affilsepx{; \protect\Affilfont}
+\makeatother
+\renewcommand\Authands{, and }
+
+%% Options for element switching
+\RequirePackage{xifthen}
+\newboolean{shortarticle}
+\newboolean{singlecolumn}
+
+%% For numbering just one line of an equation
+\newcommand\numberthis{\addtocounter{equation}{1}\tag{\theequation}}
+
+%% Watermark
+% See: http://mirrors.ctan.org/macros/latex/contrib/xwatermark/doc/xwatermark-guide.pdf#page=3
+\RequirePackage[printwatermark]{xwatermark}
+\newwatermark[allpages,color=gray!20,angle=45,scale=3,xpos=0,ypos=0]{DRAFT}
+
+\RequirePackage{textcomp} % For copyright symbol styling
+
+%% Graphics, tables and other formatting
+\RequirePackage{graphicx}
+\RequirePackage{colortbl}
+\RequirePackage{booktabs}
+\RequirePackage{algorithm}
+\RequirePackage[noend]{algpseudocode}
+\RequirePackage{changepage}
+\RequirePackage[twoside,%
+ includeheadfoot,
+ left=38.5pt,%
+ right=43pt,%
+ top=43pt,% 10pt provided by headsep
+ bottom=32pt,%
+ headheight=0pt,% No Header
+ headsep=10pt,%
+ footskip=25pt]{geometry}
+\RequirePackage[labelfont={bf,sf},%
+ labelsep=period,%
+ figurename=Fig.]{caption}
+\setlength{\columnsep}{13.5pt} % Distance between the two columns of text
+\setlength{\parindent}{12pt} % Paragraph indent
+
+%% Set document color scheme
+\definecolor{black50}{gray}{0.5} % 50% black for hrules
+\definecolor{color0}{RGB}{0,0,0} % Base
+\definecolor{color1}{RGB}{59,90,198} % author email, doi
+%\definecolor{color2}{RGB}{16,131,16} %
+% For sig statement box
+% already define above
+%\definecolor{pnasbluetext}{RGB}{0,101,165} %
+%\definecolor{pnasblueback}{RGB}{205,217,235} %
+
+%% Bibliography
+\RequirePackage{natbib}
+\setlength{\bibsep}{0.0pt}
+%\bibliographystyle{pnas2011}
+%\renewcommand{\bibsection}{} % Remove header
+\renewcommand\bibfont{\normalfont\sffamily\fontsize{8}{10}\selectfont} % set font to be sans serif
+
+%% Figure caption style
+\DeclareCaptionFormat{pnasformat}{\normalfont\sffamily\fontsize{7}{9}\selectfont#1#2#3}
+\captionsetup{format=pnasformat}
+
+%% Table style
+\RequirePackage{etoolbox}
+\captionsetup[table]{labelfont+={small},textfont+={small,sf,bf},skip=10pt,position=above}
+% booktabs provide nice spacing, but rule widths and distances need fixing
+\setlength{\heavyrulewidth}{0.5pt}
+\setlength{\lightrulewidth}{0.5pt}
+\setlength{\aboverulesep}{1.5pt}
+\setlength{\belowrulesep}{1.5pt}
+\setlength{\belowbottomsep}{10pt}
+\AtBeginEnvironment{tabular}{
+\sffamily\fontsize{7.5}{10}\selectfont
+}
+\newcommand{\addtabletext}[1]{{\setlength{\leftskip}{9pt}\fontsize{7}{9}\selectfont#1}}
+
+%% Headers and footers
+\RequirePackage{fancyhdr} % custom headers/footers
+\RequirePackage{lastpage} % Number of pages in the document
+\pagestyle{fancy} % Enables the custom headers/footers
+
+% Add name footer option
+\def\pinpfootercontents#1{\def\@pinpfootercontents{#1}}
+\pinpfootercontents{Package Vignette}
+\newcommand{\printpinpfootercontents}{\@pinpfootercontents}
+
+%% For the line numbers overlay
+\def\leftlinenos{%
+ \pgfmathtruncatemacro{\leftstartlineno}{2*(\thepage - 1)*62 + 1}%
+ \pgfmathtruncatemacro{\leftendlineno}{(2*(\thepage - 1) + 1)*62}%
+ \foreach \x in {\leftstartlineno,...,\leftendlineno}{\noindent\x\\}%
+}
+\def\rightlinenos{%
+ \pgfmathtruncatemacro{\rightstartlineno}{(2*(\thepage - 1) + 1)*62 + 1}%
+ \pgfmathtruncatemacro{\rightendlineno}{(2*\thepage)*62}%
+ \foreach \x in {\rightstartlineno,...,\rightendlineno}{\noindent\x\\}%
+}
+
+
+\makeatletter
+\fancypagestyle{firststyle}{
+ \fancyfoot[R]{\footerfont \printpinpfootercontents\hspace{7pt}|\hspace{7pt}\textbf{\today}\hspace{7pt}|\hspace{7pt}\textbf{\thepage\textendash\pageref{LastPage}}}
+ \fancyfoot[L]{\footerfont\@ifundefined{@doi}{}{\@doi}}
+}
+\makeatother
+
+% Headers
+\fancyhead[LE,RO]{}
+\fancyhead[LO,RE]{}
+% Footers
+\lfoot{}%
+\cfoot{}%
+\rfoot{}%
+\makeatletter
+\fancyfoot[LE]{\footerfont\textbf{\thepage}\hspace{7pt}|\hspace{7pt}\@ifundefined{@doi}{}{\@doi}}
+\fancyfoot[RO]{\footerfont \printpinpfootercontents\hspace{7pt}|\hspace{7pt}\textbf{\today}\hspace{7pt}|\hspace{7pt}\textbf{\thepage}}
+\fancyfoot[RE,LO]{\footerfont\@ifundefined{@leadauthor}{}{\@leadauthor}}
+
+% Use footer routine for line numbers
+\AtBeginDocument{
+ \if@pnaslineno
+ \ifthenelse{\boolean{singlecolumn}}{
+ % use lineno package if singlecolumn
+ \RequirePackage{lineno}
+ \linenumbers
+ }{% use tikz if twocolumn
+ \fancyfoot[C]{\begin{tikzpicture}[remember picture,overlay]
+ \node at([xshift=1.5em,yshift=\dimexpr -0.0625in-53pt] current page.north west)[anchor=north west,text width=3em,font=\rmfamily,align=right] {\leftlinenos};%
+ \node at([xshift=-1.5em,yshift=\dimexpr -0.0625in-53pt] current page.north east)[anchor=north east,text width=3em,font=\rmfamily,align=left] {\rightlinenos};%
+ \end{tikzpicture}}
+ }
+ \fi
+}
+\makeatother
+
+\renewcommand{\headrulewidth}{0pt}% % No header rule
+\renewcommand{\footrulewidth}{0pt}% % No footer rule
+
+%% Section/subsection/paragraph set-up
+\RequirePackage[explicit]{titlesec}
+%% \renewcommand{\thesubsection}{\Alph{subsection}}
+
+\titleformat{\section}
+ {\large\sffamily\bfseries}
+ {\thesection.}
+ {0.5em}
+ {#1}
+ []
+\titleformat{name=\section,numberless}
+ {\large\sffamily\bfseries}
+ {}
+ {0em}
+ {#1}
+ []
+\titleformat{\subsection}[runin]
+ {\sffamily\bfseries}
+ {\thesubsection.}
+ {0.5em}
+ {#1. }
+ []
+\titleformat{\subsubsection}[runin]
+ {\sffamily\small\bfseries\itshape}
+ {\thesubsubsection.}
+ {0.5em}
+ {#1. }
+ []
+\titleformat{\paragraph}[runin]
+ {\sffamily\small\bfseries}
+ {}
+ {0em}
+ {#1}
+\titlespacing*{\section}{0pc}{3ex \@plus4pt \@minus3pt}{5pt}
+\titlespacing*{\subsection}{0pc}{2.5ex \@plus3pt \@minus2pt}{2pt}
+\titlespacing*{\subsubsection}{0pc}{2ex \@plus2.5pt \@minus1.5pt}{2pt}
+\titlespacing*{\paragraph}{0pc}{1.5ex \@plus2pt \@minus1pt}{12pt}
+
+%% Article meta data additional fields
+\newcommand{\additionalelement}[1]{\def\@additionalelement{#1}}
+\newcommand{\dates}[1]{\def\@dates{#1}}
+\newcommand{\doi}[1]{\def\@doi{#1}}
+\newcommand{\leadauthor}[1]{\def\@leadauthor{#1}}
+\newcommand{\etal}[1]{\def\@etal{#1}}
+\newcommand{\keywords}[1]{\def\@keywords{#1}}
+\newcommand{\authorcontributions}[1]{\def\@authorcontributions{#1}}
+\newcommand{\authordeclaration}[1]{\def\@authordeclaration{#1}}
+\newcommand{\equalauthors}[1]{\def\@equalauthors{#1}}
+\newcommand{\correspondingauthor}[1]{\def\@correspondingauthor{#1}}
+\newcommand{\significancestatement}[1]{\def\@significancestatement{#1}}
+\newcommand{\matmethods}[1]{\def\@matmethods{#1}}
+\newcommand{\acknow}[1]{\def\@acknow{#1}}
+
+%% Dropped capital for first letter of main text
+\newcommand{\dropcap}[1]{\lettrine[lines=2,lraise=0.05,findent=0.1em, nindent=0em]{{\dropcapfont{#1}}}{}}
+
+%% Abstract formatting
+\def\xabstract{abstract}
+\long\def\abstract#1\end#2{\def\two{#2}\ifx\two\xabstract
+\long\gdef\theabstract{\ignorespaces#1}
+\def\go{\end{abstract}}\else
+\typeout{^^J^^J PLEASE DO NOT USE ANY \string\begin\space \string\end^^J
+COMMANDS WITHIN ABSTRACT^^J^^J}#1\end{#2}
+\gdef\theabstract{\vskip12pt BADLY FORMED ABSTRACT: PLEASE DO
+NOT USE {\tt\string\begin...\string\end} COMMANDS WITHIN
+THE ABSTRACT\vskip12pt}\let\go\relax\fi
+\go}
+
+% Define an environment with abstract content and styling
+\newcommand{\abscontent}{
+\noindent
+{%
+\parbox{\dimexpr\linewidth}{%
+ \vskip3pt%
+ \absfont \theabstract
+}%
+}%
+\vskip10pt%
+\noindent
+{\parbox{\dimexpr\linewidth}{%
+{
+ \keywordsfont \@ifundefined{@keywords}{}{\@keywords}}%
+}}%
+\vskip12pt%
+}
+
+% Option to format abstract differently for certain layouts (not used)
+\newcommand{\abscontentformatted}{
+\abscontent
+}
+
+%% Manual adjustment to line up main content with line numbers
+\newlength\pnas@vertadjust
+\newcommand\verticaladjustment[1]{\setlength{\pnas@vertadjust}{#1}}
+
+%% Custom title page
+\renewcommand{\@maketitle}{%
+{%
+\ifthenelse{\boolean{shortarticle}}
+{\ifthenelse{\boolean{singlecolumn}}{}{
+{\raggedright\baselineskip= 24pt\titlefont \@title\par}%
+\vskip10pt% 21pts between base of title and base of author line
+{\raggedright \@author\par}
+\vskip8pt% 16pts between base of affiliations and base of dates line
+{\raggedright \datesfont \@ifundefined{@dates}{}{\@dates}\par}
+\vskip12pt%
+}}
+{% else
+%
+\vskip10pt%
+{\raggedright\baselineskip= 24pt\titlefont \@title\par}%
+\vskip10pt% 21pts between base of title and base of author line
+{\raggedright \@author\par}
+\vskip8pt% 16pts between base of affiliations and base of dates line
+{\raggedright \datesfont \@ifundefined{@dates}{}{\@dates}\par}
+\vskip12pt
+{%
+\abscontent
+}%
+\vskip25pt%
+}%
+%%%
+%\@additionalelement
+}%
+\vskip\pnas@vertadjust
+}%
+
+%% Footnotes set up
+\RequirePackage[flushmargin,ragged]{footmisc}
+\renewcommand*{\footnotelayout}{\normalfont\sffamily\fontsize{6}{8}\selectfont} % set the footnote font
+\renewcommand{\footnoterule}{% Set the footnote hrule style
+ \kern -3pt
+ {\color{black50} \hrule width 72pt height 0.25pt}
+ \kern 2.5pt
+}
+
+\definecolor{pinpblue}{HTML}{EB6622} % imagecolorpicker on blue for new R logo -- 185FAF
+
+%% Set up the acknowledgments field
+\titleclass{\acknow@section}{straight}[\part]
+\newcounter{acknow@section}
+\providecommand*{\toclevel@acknow@section}{0}
+% Format is set for research articles by default
+\titleformat{\acknow@section}[runin]
+ {\sffamily\normalsize\bfseries\color{pinpblue}}
+ {}
+ {0em}
+ {#1.}
+ []
+\titlespacing{\acknow@section}
+ {0pt}
+ {3.25ex plus 1ex minus .2ex}
+ {1.5ex plus .2ex}
+\newcommand{\showacknow}{% Display acknowledgments section
+\@ifundefined{@acknow}{}{\acknow@section{Acknowledgments}\@acknow}
+}
+
+%% Set up the materials&methods field
+\titleclass{\matmethods@section}{straight}[\part]
+\newcounter{matmethods@section}
+\providecommand*{\toclevel@matmethods@section}{0}
+% Format is set for research articles by default
+\titleformat{\matmethods@section}
+ {\sffamily\normalsize\bfseries}
+ {}
+ {0em}
+ {#1}
+ []
+\titlespacing{\matmethods@section}
+ {0pt}
+ {3.25ex plus 1ex minus .2ex}
+ {1.5ex plus .2ex}
+\newcommand{\showmatmethods}{% Display materials&methods section
+\@ifundefined{@matmethods}{}{\matmethods@section{Materials and Methods}{\small\noindent\@matmethods}}
+}
+
+%% Other packages
+\RequirePackage{enumitem} % For reducing bullet list item separation
+
+% Taken from RJournal styling
+\makeatletter
+\DeclareRobustCommand\code{\bgroup\@noligs\@codex}
+\def\@codex#1{\texorpdfstring%
+{{\normalfont\ttfamily\hyphenchar\font=-1 #1}}%
+{#1}\egroup}
+\makeatother
+
+\usepackage{fancyvrb}
+\newcommand{\VerbBar}{|}
+\newcommand{\VERB}{\Verb[commandchars=\\\{\}]}
+\DefineVerbatimEnvironment{Highlighting}{Verbatim}{commandchars=\\\{\}}
+
+%% using mdframed (loaded above) for shaded box around code
+\global\mdfdefinestyle{codebox}{%
+ linecolor=gray!70,
+ linewidth=0.5pt,
+ backgroundcolor=gray!05,
+ innerleftmargin=2pt,
+ innerrightmargin=2pt}
+\newenvironment{Shaded}{\begin{mdframed}[style=codebox]}{\end{mdframed}}
+\global\mdfdefinestyle{resultbox}{%
+ linecolor=gray!50,
+ linewidth=0.5pt,
+ backgroundcolor=gray!02,
+ innerleftmargin=2pt,
+ innerrightmargin=2pt}
+\newenvironment{ShadedResult}{\begin{mdframed}[style=resultbox]}{\end{mdframed}}
+\newcommand{\KeywordTok}[1]{\textcolor[rgb]{0.13,0.29,0.53}{\textbf{#1}}}
+\newcommand{\DataTypeTok}[1]{\textcolor[rgb]{0.13,0.29,0.53}{#1}}
+\newcommand{\DecValTok}[1]{\textcolor[rgb]{0.00,0.00,0.81}{#1}}
+\newcommand{\BaseNTok}[1]{\textcolor[rgb]{0.00,0.00,0.81}{#1}}
+\newcommand{\FloatTok}[1]{\textcolor[rgb]{0.00,0.00,0.81}{#1}}
+\newcommand{\ConstantTok}[1]{\textcolor[rgb]{0.00,0.00,0.00}{#1}}
+\newcommand{\CharTok}[1]{\textcolor[rgb]{0.31,0.60,0.02}{#1}}
+\newcommand{\SpecialCharTok}[1]{\textcolor[rgb]{0.00,0.00,0.00}{#1}}
+\newcommand{\StringTok}[1]{\textcolor[rgb]{0.31,0.60,0.02}{#1}}
+\newcommand{\VerbatimStringTok}[1]{\textcolor[rgb]{0.31,0.60,0.02}{#1}}
+\newcommand{\SpecialStringTok}[1]{\textcolor[rgb]{0.31,0.60,0.02}{#1}}
+\newcommand{\ImportTok}[1]{#1}
+\newcommand{\CommentTok}[1]{\textcolor[rgb]{0.56,0.35,0.01}{\textit{#1}}}
+\newcommand{\DocumentationTok}[1]{\textcolor[rgb]{0.56,0.35,0.01}{\textbf{\textit{#1}}}}
+\newcommand{\AnnotationTok}[1]{\textcolor[rgb]{0.56,0.35,0.01}{\textbf{\textit{#1}}}}
+\newcommand{\CommentVarTok}[1]{\textcolor[rgb]{0.56,0.35,0.01}{\textbf{\textit{#1}}}}
+\newcommand{\OtherTok}[1]{\textcolor[rgb]{0.56,0.35,0.01}{#1}}
+\newcommand{\FunctionTok}[1]{\textcolor[rgb]{0.00,0.00,0.00}{#1}}
+\newcommand{\VariableTok}[1]{\textcolor[rgb]{0.00,0.00,0.00}{#1}}
+\newcommand{\ControlFlowTok}[1]{\textcolor[rgb]{0.13,0.29,0.53}{\textbf{#1}}}
+\newcommand{\OperatorTok}[1]{\textcolor[rgb]{0.81,0.36,0.00}{\textbf{#1}}}
+\newcommand{\BuiltInTok}[1]{#1}
+\newcommand{\ExtensionTok}[1]{#1}
+\newcommand{\PreprocessorTok}[1]{\textcolor[rgb]{0.56,0.35,0.01}{\textit{#1}}}
+\newcommand{\AttributeTok}[1]{\textcolor[rgb]{0.77,0.63,0.00}{#1}}
+\newcommand{\RegionMarkerTok}[1]{#1}
+\newcommand{\InformationTok}[1]{\textcolor[rgb]{0.56,0.35,0.01}{\textbf{\textit{#1}}}}
+\newcommand{\WarningTok}[1]{\textcolor[rgb]{0.56,0.35,0.01}{\textbf{\textit{#1}}}}
+\newcommand{\AlertTok}[1]{\textcolor[rgb]{0.94,0.16,0.16}{#1}}
+\newcommand{\ErrorTok}[1]{\textcolor[rgb]{0.64,0.00,0.00}{\textbf{#1}}}
+\newcommand{\NormalTok}[1]{#1}
+
+\providecommand{\tightlist}{%
+ \setlength{\itemsep}{0pt}\setlength{\parskip}{0pt}}
+
+
+%\RequirePackage{pnasresearcharticle}
+%%% BEGIN pnasresearcharticle
+%%% PNAS two column research article style file
+%%% For use with pnas-new.cls
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{pnasresearcharticle}[2016/02/28 v1.2 PNAS two column research article style]
+
+%% Set whether the abstract is set into the first column
+\setboolean{shortarticle}{true}
+% true = set into first column
+% false = spans page width
+
+%% Set up the first page footnote/fact box here
+\RequirePackage{float}
+\floatstyle{plain}
+\newfloat{sigstatement}{b!}{sst}
+
+\additionalelement{%
+\afterpage{\begin{sigstatement}
+\sffamily
+\mdfdefinestyle{pnassigstyle}{linewidth=0.7pt,backgroundcolor=pnasblueback,linecolor=pnasbluetext,fontcolor=pnasbluetext,innertopmargin=6pt,innerrightmargin=6pt,innerbottommargin=6pt,innerleftmargin=6pt}
+\@ifundefined{@significancestatement}{}{%
+ \begin{mdframed}[style=pnassigstyle]%
+ \section*{Significance Statement}%
+ \@significancestatement
+ \end{mdframed}}
+% \medskip
+\scriptsize
+\@ifundefined{@authorcontributions}{}{\@authorcontributions}
+\vskip5pt%
+\@ifundefined{@authordeclaration}{}{\@authordeclaration}
+\vskip5pt%
+\@ifundefined{@equalauthors}{}{\@equalauthors}
+\vskip5pt%
+\@ifundefined{@correspondingauthor}{}{\@correspondingauthor}
+\end{sigstatement}}
+}
+
+
+%% Break at end of article (before references)
+% The blank line before the strip command ensures there is nothing placed
+% directly before the break (which can cause formatting issues).
+\newcommand{\pnasbreak}{
+\begin{strip}
+\vskip-11pt
+\end{strip}
+}
+
+\DefineVerbatimEnvironment{Sinput}{Verbatim}{fontshape=sl}
+\DefineVerbatimEnvironment{Soutput}{Verbatim}{}
+\DefineVerbatimEnvironment{Scode}{Verbatim}{fontshape=sl}
+\newenvironment{Schunk}{}{}
+\DefineVerbatimEnvironment{Code}{Verbatim}{}
+\DefineVerbatimEnvironment{CodeInput}{Verbatim}{fontshape=sl}
+\DefineVerbatimEnvironment{CodeOutput}{Verbatim}{}
+\newenvironment{CodeChunk}{}{}
+
+%% Set colors -- now via test and fallback default in template
+%\definecolor{pinpblue}{HTML}{185FAF} % imagecolorpicker on blue for new R logo
+
+\definecolor{pinpblue}{HTML}{EB6622}
+
+% Add colour to the title
+\appto{\titlefont}{\color{pinpblue}}
+
+% ...and section headings
+\titleformat{\section}
+ {\large\sffamily\bfseries\color{pinpblue}}
+ {\thesection.}
+ {0.5em}
+ {#1}
+ []
+\titleformat{name=\section,numberless}
+ {\large\sffamily\bfseries\color{pinpblue}}
+ {}
+ {0em}
+ {#1}
+ []
+\titleformat{\subsection}[runin]
+ {\sffamily\bfseries\color{pinpblue}} %\itshape}%
+ {\thesubsection.}
+ {0.5em}
+ {#1. }
+ []
+% Other section headings left unchanged.
+
+%% Other packages
+\RequirePackage{enumitem} % For reducing bullet list item separation
+
+%% microtype with mathdesign, microtype already loaded
+%\usepackage[bitstream-charter]{mathdesign} %% cf http://www.khirevich.com/latex/font/
+
+\endinput
+
+%%% END pnasresearcharticle
+
+
+
+
+
diff --git a/LegendMedCentral/pnas-new.cls b/LegendMedCentral/pnas-new.cls
new file mode 100644
index 00000000..3e9c7ec5
--- /dev/null
+++ b/LegendMedCentral/pnas-new.cls
@@ -0,0 +1,445 @@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% pnas-new.cls, v1.2, 2016/02/28
+%
+% This class file enables authors to prepare research
+% articles for submission to PNAS.
+%
+% Please note that whilst this template provides a
+% preview of the typeset manuscript for submission, it
+% will not necessarily be the final publication layout.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% This work may be distributed and/or modified under the
+% conditions of the LaTeX Project Public License, either
+% version 1.3 of this license or any later version.
+% The latest version of this license is in
+% http://www.latex-project.org/lppl.txt and
+% version 1.3 or later is part of all distributions
+% of LaTeX version 2005/12/01 or later.
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% For use with latex+dvipdfm, pdflatex, xelatex & lualatex
+% For compiling with plain latex, please use latex+dvipdfm
+% to produce the PDF, not dvis -> ps -> pdf nor dvipdf
+%
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesClass{pnas-new}[28/02/2015, v1.2]
+\AtEndOfClass{\RequirePackage{microtype}}
+% Option for line numbers
+\newif\if@pnaslineno
+\DeclareOption{lineno}{\@pnaslinenotrue}
+\DeclareOption*{\PassOptionsToClass{\CurrentOption}{extarticle}}
+\ProcessOptions*
+\LoadClass{extarticle}
+
+%% Fonts and language
+\RequirePackage[utf8]{inputenc}
+\RequirePackage[english]{babel}
+\RequirePackage{amsmath,amsfonts,amssymb}
+\RequirePackage{lmodern}
+\RequirePackage[scaled]{helvet}
+\RequirePackage[T1]{fontenc}
+\RequirePackage{lettrine} % For dropped capitals
+
+%% For the Significance Statement & footnote on the first page
+\RequirePackage{afterpage}
+\RequirePackage{ifpdf,ifxetex}
+\ifpdf\else
+ \ifxetex\else
+ \def\pgfsysdriver{pgfsys-dvipdfm.def}
+ \pdfpagewidth=\paperwidth
+ \pdfpageheight=\paperheight
+\fi\fi
+\RequirePackage{xcolor}
+\RequirePackage{tikz}
+\RequirePackage[framemethod=tikz]{mdframed}
+
+%% For single column equations and balancing the columns on final page
+\RequirePackage{widetext}
+
+%% Hyperlinking
+\RequirePackage[colorlinks=true, allcolors=blue]{hyperref}
+
+%% Set up main title page fonts
+\newcommand{\headerfont}{\normalfont\sffamily\fontsize{7}{9} \selectfont}
+\newcommand{\footerfont}{\normalfont\sffamily\fontsize{7}{9} \selectfont}
+\newcommand{\titlefont}{\fontfamily{lmss}\bfseries\fontsize{22pt}{24pt}\selectfont}
+\newcommand{\dropcapfont}{\fontfamily{lmss}\bfseries\fontsize{26pt}{28pt}\selectfont}
+\newcommand{\datesfont}{\normalfont\sffamily\fontsize{7}{8}\selectfont}
+\newcommand{\absfont}{\normalfont\sffamily\bfseries\fontsize{8}{11}\selectfont}
+\newcommand{\keywordsfont}{\normalfont\rmfamily\fontsize{7}{10}\selectfont}
+\newcommand{\copyrightfont}{\normalfont\rmfamily\fontsize{6}{8}\selectfont}
+
+%% Set URL link color & font
+\renewcommand\UrlFont{\color{black}\sffamily}
+
+%% Author and affiliation
+\RequirePackage{authblk}
+\setlength{\affilsep}{8.5pt} % 16.5pts between base of author line and base of affil line
+\renewcommand\Authfont{\color{color0}\normalfont\sffamily\bfseries\fontsize{9}{11}\selectfont}
+\renewcommand\Affilfont{\color{color0}\normalfont\sffamily\fontsize{7}{8}\selectfont}
+\makeatletter
+\renewcommand\AB@affilsepx{; \protect\Affilfont}
+\makeatother
+\renewcommand\Authands{, and }
+
+%% Choose template type
+\newcommand*{\templatetype}[1]{%
+ \RequirePackage{#1}}
+
+%% Options for element switching
+\RequirePackage{xifthen}
+\newboolean{shortarticle}
+\newboolean{singlecolumn}
+
+%% For numbering just one line of an equation
+\newcommand\numberthis{\addtocounter{equation}{1}\tag{\theequation}}
+
+%% Watermark
+\usepackage[printwatermark]{xwatermark}
+\newboolean{displaywatermark}
+\setboolean{displaywatermark}{true} % Set to false to remove the watermark
+\ifthenelse{\boolean{displaywatermark}}{%
+\newwatermark[allpages,color=gray!20,angle=45,scale=3,xpos=0,ypos=0]{DRAFT}}{}
+
+%% Copyright statement (not used)
+\newboolean{displaycopyright}
+\setboolean{displaycopyright}{false} % Confirmed as not required
+\RequirePackage{textcomp} % For copyright symbol styling
+\newcommand{\copyrightstatement}{\, \textcopyright\, 2015 by The National Academy of Sciences of the USA}
+
+%% Graphics, tables and other formatting
+\RequirePackage{graphicx,xcolor}
+\RequirePackage{colortbl}
+\RequirePackage{booktabs}
+\RequirePackage{algorithm}
+\RequirePackage[noend]{algpseudocode}
+\RequirePackage{changepage}
+\RequirePackage[twoside,%
+ letterpaper,includeheadfoot,%
+ layoutsize={8.125in,10.875in},%
+ layouthoffset=0.1875in,%
+ layoutvoffset=0.0625in,%
+ left=38.5pt,%
+ right=43pt,%
+ top=43pt,% 10pt provided by headsep
+ bottom=32pt,%
+ headheight=0pt,% No Header
+ headsep=10pt,%
+ footskip=25pt]{geometry}
+\RequirePackage[labelfont={bf,sf},%
+ labelsep=period,%
+ figurename=Fig.]{caption}
+\setlength{\columnsep}{13.5pt} % Distance between the two columns of text
+\setlength{\parindent}{12pt} % Paragraph indent
+
+%% Set document color scheme
+\definecolor{black50}{gray}{0.5} % 50% black for hrules
+\definecolor{color0}{RGB}{0,0,0} % Base
+\definecolor{color1}{RGB}{59,90,198} % author email, doi
+\definecolor{color2}{RGB}{16,131,16} %
+% For sig statement box
+\definecolor{pnasbluetext}{RGB}{0,101,165} %
+\definecolor{pnasblueback}{RGB}{205,217,235} %
+%\definecolor{pnasbluetext}{RGB}{0,115,209} % Not used
+%\definecolor{pnasblueback}{RGB}{210,230,247} % Not used
+
+%% Bibliography
+\RequirePackage[numbers,sort&compress]{natbib}
+\setlength{\bibsep}{0.0pt}
+\bibliographystyle{pnas2011}
+\renewcommand{\bibsection}{} % Remove header
+\renewcommand\bibfont{\normalfont\sffamily\fontsize{6}{8}\selectfont} % set font to be sans serif
+
+\makeatletter
+\renewcommand\@biblabel[1]{ #1.} % Remove brackets from label
+\def\tagform@#1{\maketag@@@{\bfseries(\ignorespaces#1\unskip\@@italiccorr)}}
+\renewcommand{\eqref}[1]{\textup{{\normalfont Eq.~(\ref{#1}}\normalfont)}}
+\makeatother
+
+%% Figure caption style
+\DeclareCaptionFormat{pnasformat}{\normalfont\sffamily\fontsize{7}{9}\selectfont#1#2#3}
+\captionsetup{format=pnasformat}
+
+%% Table style
+\RequirePackage{etoolbox}
+\captionsetup[table]{labelfont+={small},textfont+={small,sf,bf},skip=10pt,position=above}
+% booktabs provide nice spacing, but rule widths and distances need fixing
+\setlength{\heavyrulewidth}{0.5pt}
+\setlength{\lightrulewidth}{0.5pt}
+\setlength{\aboverulesep}{1.5pt}
+\setlength{\belowrulesep}{1.5pt}
+\setlength{\belowbottomsep}{10pt}
+\AtBeginEnvironment{tabular}{
+\sffamily\fontsize{7.5}{10}\selectfont
+}
+\newcommand{\addtabletext}[1]{{\setlength{\leftskip}{9pt}\fontsize{7}{9}\selectfont#1}}
+
+%% Equation numbering - use square brackets
+\makeatletter
+\renewcommand\tagform@[1]{\maketag@@@ {[\ignorespaces #1\unskip \@@italiccorr ]}}
+\makeatother
+
+%% Headers and footers
+\RequirePackage{fancyhdr} % custom headers/footers
+\RequirePackage{lastpage} % Number of pages in the document
+\pagestyle{fancy} % Enables the custom headers/footers
+
+%% For the line numbers overlay
+\def\leftlinenos{%
+ \pgfmathtruncatemacro{\leftstartlineno}{2*(\thepage - 1)*62 + 1}%
+ \pgfmathtruncatemacro{\leftendlineno}{(2*(\thepage - 1) + 1)*62}%
+ \foreach \x in {\leftstartlineno,...,\leftendlineno}{\noindent\x\\}%
+}
+\def\rightlinenos{%
+ \pgfmathtruncatemacro{\rightstartlineno}{(2*(\thepage - 1) + 1)*62 + 1}%
+ \pgfmathtruncatemacro{\rightendlineno}{(2*\thepage)*62}%
+ \foreach \x in {\rightstartlineno,...,\rightendlineno}{\noindent\x\\}%
+}
+
+\makeatletter
+\fancypagestyle{firststyle}{
+ \fancyfoot[R]{\footerfont OHDSI\hspace{7pt}|\hspace{7pt}\textbf{\today}\hspace{7pt}|\hspace{7pt}LEGEND version XXX\hspace{7pt}|\hspace{7pt}\textbf{\thepage\textendash\pageref{LastPage}}}
+% \fancyfoot[L]{\footerfont\@ifundefined{@doi}{}{\@doi}}
+}
+\makeatother
+
+% Headers
+\fancyhead[LE,RO]{}
+\fancyhead[LO,RE]{}
+% Footers
+\lfoot{}%
+\cfoot{}%
+\rfoot{}%
+\makeatletter
+%\fancyfoot[LE]{\footerfont\textbf{\thepage}\hspace{7pt}|\hspace{7pt}\@ifundefined{@doi}{}{\@doi}}
+\fancyfoot[RO]{\footerfont OHDSI\hspace{7pt}|\hspace{7pt}\textbf{\today}\hspace{7pt}|\hspace{7pt}LEGEND version XXX\hspace{7pt}|\hspace{7pt}\textbf{\thepage}}
+\fancyfoot[RE,LO]{\footerfont\@ifundefined{@leadauthor}{}{\@leadauthor}\ifnum \value{authors} > 1\hspace{5pt}\textit{et al.}\fi}
+
+% Use footer routine for line numbers
+\AtBeginDocument{
+ \if@pnaslineno
+ \ifthenelse{\boolean{singlecolumn}}{
+ % use lineno package if singlecolumn
+ \RequirePackage{lineno}
+ \linenumbers
+ }{% use tikz if twocolumn
+ \fancyfoot[C]{\begin{tikzpicture}[remember picture,overlay]
+ \node at([xshift=1.5em,yshift=\dimexpr -0.0625in-53pt] current page.north west)[anchor=north west,text width=3em,font=\rmfamily,align=right] {\leftlinenos};%
+ \node at([xshift=-1.5em,yshift=\dimexpr -0.0625in-53pt] current page.north east)[anchor=north east,text width=3em,font=\rmfamily,align=left] {\rightlinenos};%
+ \end{tikzpicture}}
+ }
+ \fi
+}
+\makeatother
+
+\renewcommand{\headrulewidth}{0pt}% % No header rule
+\renewcommand{\footrulewidth}{0pt}% % No footer rule
+
+%% Section/subsection/paragraph set-up
+\RequirePackage[explicit]{titlesec}
+\renewcommand{\thesubsection}{\Alph{subsection}}
+
+\titleformat{\section}
+ {\large\sffamily\bfseries}
+ {\thesection.}
+ {0.5em}
+ {#1}
+ []
+\titleformat{name=\section,numberless}
+ {\large\sffamily\bfseries}
+ {}
+ {0em}
+ {#1}
+ []
+\titleformat{\subsection}[runin]
+ {\sffamily\bfseries}
+ {\thesubsection.}
+ {0.5em}
+ {#1. }
+ []
+\titleformat{\subsubsection}[runin]
+ {\sffamily\small\bfseries\itshape}
+ {\thesubsubsection.}
+ {0.5em}
+ {#1. }
+ []
+\titleformat{\paragraph}[runin]
+ {\sffamily\small\bfseries}
+ {}
+ {0em}
+ {#1}
+\titlespacing*{\section}{0pc}{3ex \@plus4pt \@minus3pt}{5pt}
+\titlespacing*{\subsection}{0pc}{2.5ex \@plus3pt \@minus2pt}{2pt}
+\titlespacing*{\subsubsection}{0pc}{2ex \@plus2.5pt \@minus1.5pt}{2pt}
+\titlespacing*{\paragraph}{0pc}{1.5ex \@plus2pt \@minus1pt}{12pt}
+
+%% Article meta data additional fields
+\newcommand{\additionalelement}[1]{\def\@additionalelement{#1}}
+\newcommand{\dates}[1]{\def\@dates{#1}}
+\newcommand{\doi}[1]{\def\@doi{#1}}
+\newcommand{\leadauthor}[1]{\def\@leadauthor{#1}}
+\newcommand{\etal}[1]{\def\@etal{#1}}
+\newcommand{\keywords}[1]{\def\@keywords{#1}}
+\newcommand{\authorcontributions}[1]{\def\@authorcontributions{#1}}
+\newcommand{\authordeclaration}[1]{\def\@authordeclaration{#1}}
+\newcommand{\equalauthors}[1]{\def\@equalauthors{#1}}
+\newcommand{\correspondingauthor}[1]{\def\@correspondingauthor{#1}}
+\newcommand{\significancestatement}[1]{\def\@significancestatement{#1}}
+\newcommand{\matmethods}[1]{\def\@matmethods{#1}}
+\newcommand{\acknow}[1]{\def\@acknow{#1}}
+
+%% Dropped capital for first letter of main text
+\newcommand{\dropcap}[1]{\lettrine[lines=2,lraise=0.05,findent=0.1em, nindent=0em]{{\dropcapfont{#1}}}{}}
+
+%% Abstract formatting
+\def\xabstract{abstract}
+\long\def\abstract#1\end#2{\def\two{#2}\ifx\two\xabstract
+\long\gdef\theabstract{\ignorespaces#1}
+\def\go{\end{abstract}}\else
+\typeout{^^J^^J PLEASE DO NOT USE ANY \string\begin\space \string\end^^J
+COMMANDS WITHIN ABSTRACT^^J^^J}#1\end{#2}
+\gdef\theabstract{\vskip12pt BADLY FORMED ABSTRACT: PLEASE DO
+NOT USE {\tt\string\begin...\string\end} COMMANDS WITHIN
+THE ABSTRACT\vskip12pt}\let\go\relax\fi
+\go}
+
+% Define an environment with abstract content and styling
+\newcommand{\abscontent}{
+\noindent
+{%
+\parbox{\dimexpr\linewidth}{%
+ \vskip3pt%
+ \absfont \theabstract
+}%
+}%
+\vskip10pt%
+\noindent
+{\parbox{\dimexpr\linewidth}{%
+{
+ \keywordsfont \@ifundefined{@keywords}{}{\@keywords}}%
+}}%
+\vskip12pt%
+}
+
+% Option to format abstract differently for certain layouts (not used)
+\newcommand{\abscontentformatted}{
+\abscontent
+}
+
+%% Manual adjustment to line up main content with line numbers
+\newlength\pnas@vertadjust
+\newcommand\verticaladjustment[1]{\setlength{\pnas@vertadjust}{#1}}
+
+%% Custom title page
+\renewcommand{\@maketitle}{%
+{%
+\ifthenelse{\boolean{shortarticle}}
+{\ifthenelse{\boolean{singlecolumn}}{}{
+{\raggedright\baselineskip= 24pt\titlefont \@title\par}%
+\vskip10pt% 21pts between base of title and base of author line
+{\raggedright \@author\par}
+\vskip8pt% 16pts between base of affiliations and base of dates line
+{\raggedright \datesfont \@ifundefined{@dates}{}{\@dates}\par}
+\vskip12pt%
+}}
+{% else
+%
+\vskip10pt%
+{\raggedright\baselineskip= 24pt\titlefont \@title\par}%
+\vskip10pt% 21pts between base of title and base of author line
+{\raggedright \@author\par}
+\vskip8pt% 16pts between base of affiliations and base of dates line
+{\raggedright \datesfont \@ifundefined{@dates}{}{\@dates}\par}
+\vskip12pt
+{%
+\abscontent
+}%
+\vskip25pt%
+}%
+%%%
+\@additionalelement
+}%
+\vskip\pnas@vertadjust
+}%
+
+%% Footnotes set up
+\RequirePackage[flushmargin,ragged]{footmisc}
+\renewcommand*{\footnotelayout}{\normalfont\sffamily\fontsize{6}{8}\selectfont} % set the footnote font
+\renewcommand{\footnoterule}{% Set the footnote hrule style
+ \kern -3pt
+ {\color{black50} \hrule width 72pt height 0.25pt}
+ \kern 2.5pt
+}
+
+\definecolor{pinpblue}{HTML}{EB6622} % imagecolorpicker on blue for new R logo -- 185FAF
+
+%% Set up the acknowledgments field
+\titleclass{\acknow@section}{straight}[\part]
+\newcounter{acknow@section}
+\providecommand*{\toclevel@acknow@section}{0}
+% Format is set for research articles by default
+\titleformat{\acknow@section}[runin]
+ %{\sffamily\normalsize\bfseries}
+ {\sffamily\normalsize\bfseries\color{pinpblue}}
+ {}
+ {0em}
+ {#1.}
+ []
+\titlespacing{\acknow@section}
+ {0pt}
+ {3.25ex plus 1ex minus .2ex}
+ {1.5ex plus .2ex}
+\newcommand{\showacknow}{% Display acknowledgments section
+\@ifundefined{@acknow}{}{\acknow@section{ACKNOWLEDGMENTS}\small\@acknow}
+}
+
+%% Set up the materials&methods field
+\titleclass{\matmethods@section}{straight}[\part]
+\newcounter{matmethods@section}
+\providecommand*{\toclevel@matmethods@section}{0}
+% Format is set for research articles by default
+\titleformat{\matmethods@section}
+ {\sffamily\normalsize\bfseries}
+ {}
+ {0em}
+ {#1}
+ []
+\titlespacing{\matmethods@section}
+ {0pt}
+ {3.25ex plus 1ex minus .2ex}
+ {1.5ex plus .2ex}
+\newcommand{\showmatmethods}{% Display materials&methods section
+\@ifundefined{@matmethods}{}{\matmethods@section{Materials and Methods}{\small\noindent\@matmethods}}
+}
+
+\providecommand{\tightlist}{%
+ \setlength{\itemsep}{0pt}\setlength{\parskip}{0pt}}
+
+
+% Add colour to the title
+\appto{\titlefont}{\color{pinpblue}}
+
+% ...and section headings
+\titleformat{\section}
+ {\large\sffamily\bfseries\color{pinpblue}}
+ {\thesection.}
+ {0.5em}
+ {#1}
+ []
+\titleformat{name=\section,numberless}
+ {\large\sffamily\bfseries\color{pinpblue}}
+ {}
+ {0em}
+ {#1}
+ []
+\titleformat{\subsection}[runin]
+ {\sffamily\bfseries\color{pinpblue}} %\itshape}%
+ {\thesubsection.}
+ {0.5em}
+ {#1. }
+ []
+% Other section headings left unchanged.
+
+%% Other packages
+\RequirePackage{enumitem} % For reducing bullet list item separation
diff --git a/LegendMedCentral/pnas-ohdsi.cls b/LegendMedCentral/pnas-ohdsi.cls
new file mode 100644
index 00000000..3e9c7ec5
--- /dev/null
+++ b/LegendMedCentral/pnas-ohdsi.cls
@@ -0,0 +1,445 @@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% pnas-new.cls, v1.2, 2016/02/28
+%
+% This class file enables authors to prepare research
+% articles for submission to PNAS.
+%
+% Please note that whilst this template provides a
+% preview of the typeset manuscript for submission, it
+% will not necessarily be the final publication layout.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% This work may be distributed and/or modified under the
+% conditions of the LaTeX Project Public License, either
+% version 1.3 of this license or any later version.
+% The latest version of this license is in
+% http://www.latex-project.org/lppl.txt and
+% version 1.3 or later is part of all distributions
+% of LaTeX version 2005/12/01 or later.
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% For use with latex+dvipdfm, pdflatex, xelatex & lualatex
+% For compiling with plain latex, please use latex+dvipdfm
+% to produce the PDF, not dvis -> ps -> pdf nor dvipdf
+%
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesClass{pnas-new}[28/02/2015, v1.2]
+\AtEndOfClass{\RequirePackage{microtype}}
+% Option for line numbers
+\newif\if@pnaslineno
+\DeclareOption{lineno}{\@pnaslinenotrue}
+\DeclareOption*{\PassOptionsToClass{\CurrentOption}{extarticle}}
+\ProcessOptions*
+\LoadClass{extarticle}
+
+%% Fonts and language
+\RequirePackage[utf8]{inputenc}
+\RequirePackage[english]{babel}
+\RequirePackage{amsmath,amsfonts,amssymb}
+\RequirePackage{lmodern}
+\RequirePackage[scaled]{helvet}
+\RequirePackage[T1]{fontenc}
+\RequirePackage{lettrine} % For dropped capitals
+
+%% For the Significance Statement & footnote on the first page
+\RequirePackage{afterpage}
+\RequirePackage{ifpdf,ifxetex}
+\ifpdf\else
+ \ifxetex\else
+ \def\pgfsysdriver{pgfsys-dvipdfm.def}
+ \pdfpagewidth=\paperwidth
+ \pdfpageheight=\paperheight
+\fi\fi
+\RequirePackage{xcolor}
+\RequirePackage{tikz}
+\RequirePackage[framemethod=tikz]{mdframed}
+
+%% For single column equations and balancing the columns on final page
+\RequirePackage{widetext}
+
+%% Hyperlinking
+\RequirePackage[colorlinks=true, allcolors=blue]{hyperref}
+
+%% Set up main title page fonts
+\newcommand{\headerfont}{\normalfont\sffamily\fontsize{7}{9} \selectfont}
+\newcommand{\footerfont}{\normalfont\sffamily\fontsize{7}{9} \selectfont}
+\newcommand{\titlefont}{\fontfamily{lmss}\bfseries\fontsize{22pt}{24pt}\selectfont}
+\newcommand{\dropcapfont}{\fontfamily{lmss}\bfseries\fontsize{26pt}{28pt}\selectfont}
+\newcommand{\datesfont}{\normalfont\sffamily\fontsize{7}{8}\selectfont}
+\newcommand{\absfont}{\normalfont\sffamily\bfseries\fontsize{8}{11}\selectfont}
+\newcommand{\keywordsfont}{\normalfont\rmfamily\fontsize{7}{10}\selectfont}
+\newcommand{\copyrightfont}{\normalfont\rmfamily\fontsize{6}{8}\selectfont}
+
+%% Set URL link color & font
+\renewcommand\UrlFont{\color{black}\sffamily}
+
+%% Author and affiliation
+\RequirePackage{authblk}
+\setlength{\affilsep}{8.5pt} % 16.5pts between base of author line and base of affil line
+\renewcommand\Authfont{\color{color0}\normalfont\sffamily\bfseries\fontsize{9}{11}\selectfont}
+\renewcommand\Affilfont{\color{color0}\normalfont\sffamily\fontsize{7}{8}\selectfont}
+\makeatletter
+\renewcommand\AB@affilsepx{; \protect\Affilfont}
+\makeatother
+\renewcommand\Authands{, and }
+
+%% Choose template type
+\newcommand*{\templatetype}[1]{%
+ \RequirePackage{#1}}
+
+%% Options for element switching
+\RequirePackage{xifthen}
+\newboolean{shortarticle}
+\newboolean{singlecolumn}
+
+%% For numbering just one line of an equation
+\newcommand\numberthis{\addtocounter{equation}{1}\tag{\theequation}}
+
+%% Watermark
+\usepackage[printwatermark]{xwatermark}
+\newboolean{displaywatermark}
+\setboolean{displaywatermark}{true} % Set to false to remove the watermark
+\ifthenelse{\boolean{displaywatermark}}{%
+\newwatermark[allpages,color=gray!20,angle=45,scale=3,xpos=0,ypos=0]{DRAFT}}{}
+
+%% Copyright statement (not used)
+\newboolean{displaycopyright}
+\setboolean{displaycopyright}{false} % Confirmed as not required
+\RequirePackage{textcomp} % For copyright symbol styling
+\newcommand{\copyrightstatement}{\, \textcopyright\, 2015 by The National Academy of Sciences of the USA}
+
+%% Graphics, tables and other formatting
+\RequirePackage{graphicx,xcolor}
+\RequirePackage{colortbl}
+\RequirePackage{booktabs}
+\RequirePackage{algorithm}
+\RequirePackage[noend]{algpseudocode}
+\RequirePackage{changepage}
+\RequirePackage[twoside,%
+ letterpaper,includeheadfoot,%
+ layoutsize={8.125in,10.875in},%
+ layouthoffset=0.1875in,%
+ layoutvoffset=0.0625in,%
+ left=38.5pt,%
+ right=43pt,%
+ top=43pt,% 10pt provided by headsep
+ bottom=32pt,%
+ headheight=0pt,% No Header
+ headsep=10pt,%
+ footskip=25pt]{geometry}
+\RequirePackage[labelfont={bf,sf},%
+ labelsep=period,%
+ figurename=Fig.]{caption}
+\setlength{\columnsep}{13.5pt} % Distance between the two columns of text
+\setlength{\parindent}{12pt} % Paragraph indent
+
+%% Set document color scheme
+\definecolor{black50}{gray}{0.5} % 50% black for hrules
+\definecolor{color0}{RGB}{0,0,0} % Base
+\definecolor{color1}{RGB}{59,90,198} % author email, doi
+\definecolor{color2}{RGB}{16,131,16} %
+% For sig statement box
+\definecolor{pnasbluetext}{RGB}{0,101,165} %
+\definecolor{pnasblueback}{RGB}{205,217,235} %
+%\definecolor{pnasbluetext}{RGB}{0,115,209} % Not used
+%\definecolor{pnasblueback}{RGB}{210,230,247} % Not used
+
+%% Bibliography
+\RequirePackage[numbers,sort&compress]{natbib}
+\setlength{\bibsep}{0.0pt}
+\bibliographystyle{pnas2011}
+\renewcommand{\bibsection}{} % Remove header
+\renewcommand\bibfont{\normalfont\sffamily\fontsize{6}{8}\selectfont} % set font to be sans serif
+
+\makeatletter
+\renewcommand\@biblabel[1]{ #1.} % Remove brackets from label
+\def\tagform@#1{\maketag@@@{\bfseries(\ignorespaces#1\unskip\@@italiccorr)}}
+\renewcommand{\eqref}[1]{\textup{{\normalfont Eq.~(\ref{#1}}\normalfont)}}
+\makeatother
+
+%% Figure caption style
+\DeclareCaptionFormat{pnasformat}{\normalfont\sffamily\fontsize{7}{9}\selectfont#1#2#3}
+\captionsetup{format=pnasformat}
+
+%% Table style
+\RequirePackage{etoolbox}
+\captionsetup[table]{labelfont+={small},textfont+={small,sf,bf},skip=10pt,position=above}
+% booktabs provide nice spacing, but rule widths and distances need fixing
+\setlength{\heavyrulewidth}{0.5pt}
+\setlength{\lightrulewidth}{0.5pt}
+\setlength{\aboverulesep}{1.5pt}
+\setlength{\belowrulesep}{1.5pt}
+\setlength{\belowbottomsep}{10pt}
+\AtBeginEnvironment{tabular}{
+\sffamily\fontsize{7.5}{10}\selectfont
+}
+\newcommand{\addtabletext}[1]{{\setlength{\leftskip}{9pt}\fontsize{7}{9}\selectfont#1}}
+
+%% Equation numbering - use square brackets
+\makeatletter
+\renewcommand\tagform@[1]{\maketag@@@ {[\ignorespaces #1\unskip \@@italiccorr ]}}
+\makeatother
+
+%% Headers and footers
+\RequirePackage{fancyhdr} % custom headers/footers
+\RequirePackage{lastpage} % Number of pages in the document
+\pagestyle{fancy} % Enables the custom headers/footers
+
+%% For the line numbers overlay
+\def\leftlinenos{%
+ \pgfmathtruncatemacro{\leftstartlineno}{2*(\thepage - 1)*62 + 1}%
+ \pgfmathtruncatemacro{\leftendlineno}{(2*(\thepage - 1) + 1)*62}%
+ \foreach \x in {\leftstartlineno,...,\leftendlineno}{\noindent\x\\}%
+}
+\def\rightlinenos{%
+ \pgfmathtruncatemacro{\rightstartlineno}{(2*(\thepage - 1) + 1)*62 + 1}%
+ \pgfmathtruncatemacro{\rightendlineno}{(2*\thepage)*62}%
+ \foreach \x in {\rightstartlineno,...,\rightendlineno}{\noindent\x\\}%
+}
+
+\makeatletter
+\fancypagestyle{firststyle}{
+ \fancyfoot[R]{\footerfont OHDSI\hspace{7pt}|\hspace{7pt}\textbf{\today}\hspace{7pt}|\hspace{7pt}LEGEND version XXX\hspace{7pt}|\hspace{7pt}\textbf{\thepage\textendash\pageref{LastPage}}}
+% \fancyfoot[L]{\footerfont\@ifundefined{@doi}{}{\@doi}}
+}
+\makeatother
+
+% Headers
+\fancyhead[LE,RO]{}
+\fancyhead[LO,RE]{}
+% Footers
+\lfoot{}%
+\cfoot{}%
+\rfoot{}%
+\makeatletter
+%\fancyfoot[LE]{\footerfont\textbf{\thepage}\hspace{7pt}|\hspace{7pt}\@ifundefined{@doi}{}{\@doi}}
+\fancyfoot[RO]{\footerfont OHDSI\hspace{7pt}|\hspace{7pt}\textbf{\today}\hspace{7pt}|\hspace{7pt}LEGEND version XXX\hspace{7pt}|\hspace{7pt}\textbf{\thepage}}
+\fancyfoot[RE,LO]{\footerfont\@ifundefined{@leadauthor}{}{\@leadauthor}\ifnum \value{authors} > 1\hspace{5pt}\textit{et al.}\fi}
+
+% Use footer routine for line numbers
+\AtBeginDocument{
+ \if@pnaslineno
+ \ifthenelse{\boolean{singlecolumn}}{
+ % use lineno package if singlecolumn
+ \RequirePackage{lineno}
+ \linenumbers
+ }{% use tikz if twocolumn
+ \fancyfoot[C]{\begin{tikzpicture}[remember picture,overlay]
+ \node at([xshift=1.5em,yshift=\dimexpr -0.0625in-53pt] current page.north west)[anchor=north west,text width=3em,font=\rmfamily,align=right] {\leftlinenos};%
+ \node at([xshift=-1.5em,yshift=\dimexpr -0.0625in-53pt] current page.north east)[anchor=north east,text width=3em,font=\rmfamily,align=left] {\rightlinenos};%
+ \end{tikzpicture}}
+ }
+ \fi
+}
+\makeatother
+
+\renewcommand{\headrulewidth}{0pt}% % No header rule
+\renewcommand{\footrulewidth}{0pt}% % No footer rule
+
+%% Section/subsection/paragraph set-up
+\RequirePackage[explicit]{titlesec}
+\renewcommand{\thesubsection}{\Alph{subsection}}
+
+\titleformat{\section}
+ {\large\sffamily\bfseries}
+ {\thesection.}
+ {0.5em}
+ {#1}
+ []
+\titleformat{name=\section,numberless}
+ {\large\sffamily\bfseries}
+ {}
+ {0em}
+ {#1}
+ []
+\titleformat{\subsection}[runin]
+ {\sffamily\bfseries}
+ {\thesubsection.}
+ {0.5em}
+ {#1. }
+ []
+\titleformat{\subsubsection}[runin]
+ {\sffamily\small\bfseries\itshape}
+ {\thesubsubsection.}
+ {0.5em}
+ {#1. }
+ []
+\titleformat{\paragraph}[runin]
+ {\sffamily\small\bfseries}
+ {}
+ {0em}
+ {#1}
+\titlespacing*{\section}{0pc}{3ex \@plus4pt \@minus3pt}{5pt}
+\titlespacing*{\subsection}{0pc}{2.5ex \@plus3pt \@minus2pt}{2pt}
+\titlespacing*{\subsubsection}{0pc}{2ex \@plus2.5pt \@minus1.5pt}{2pt}
+\titlespacing*{\paragraph}{0pc}{1.5ex \@plus2pt \@minus1pt}{12pt}
+
+%% Article meta data additional fields
+\newcommand{\additionalelement}[1]{\def\@additionalelement{#1}}
+\newcommand{\dates}[1]{\def\@dates{#1}}
+\newcommand{\doi}[1]{\def\@doi{#1}}
+\newcommand{\leadauthor}[1]{\def\@leadauthor{#1}}
+\newcommand{\etal}[1]{\def\@etal{#1}}
+\newcommand{\keywords}[1]{\def\@keywords{#1}}
+\newcommand{\authorcontributions}[1]{\def\@authorcontributions{#1}}
+\newcommand{\authordeclaration}[1]{\def\@authordeclaration{#1}}
+\newcommand{\equalauthors}[1]{\def\@equalauthors{#1}}
+\newcommand{\correspondingauthor}[1]{\def\@correspondingauthor{#1}}
+\newcommand{\significancestatement}[1]{\def\@significancestatement{#1}}
+\newcommand{\matmethods}[1]{\def\@matmethods{#1}}
+\newcommand{\acknow}[1]{\def\@acknow{#1}}
+
+%% Dropped capital for first letter of main text
+\newcommand{\dropcap}[1]{\lettrine[lines=2,lraise=0.05,findent=0.1em, nindent=0em]{{\dropcapfont{#1}}}{}}
+
+%% Abstract formatting
+\def\xabstract{abstract}
+\long\def\abstract#1\end#2{\def\two{#2}\ifx\two\xabstract
+\long\gdef\theabstract{\ignorespaces#1}
+\def\go{\end{abstract}}\else
+\typeout{^^J^^J PLEASE DO NOT USE ANY \string\begin\space \string\end^^J
+COMMANDS WITHIN ABSTRACT^^J^^J}#1\end{#2}
+\gdef\theabstract{\vskip12pt BADLY FORMED ABSTRACT: PLEASE DO
+NOT USE {\tt\string\begin...\string\end} COMMANDS WITHIN
+THE ABSTRACT\vskip12pt}\let\go\relax\fi
+\go}
+
+% Define an environment with abstract content and styling
+\newcommand{\abscontent}{
+\noindent
+{%
+\parbox{\dimexpr\linewidth}{%
+ \vskip3pt%
+ \absfont \theabstract
+}%
+}%
+\vskip10pt%
+\noindent
+{\parbox{\dimexpr\linewidth}{%
+{
+ \keywordsfont \@ifundefined{@keywords}{}{\@keywords}}%
+}}%
+\vskip12pt%
+}
+
+% Option to format abstract differently for certain layouts (not used)
+\newcommand{\abscontentformatted}{
+\abscontent
+}
+
+%% Manual adjustment to line up main content with line numbers
+\newlength\pnas@vertadjust
+\newcommand\verticaladjustment[1]{\setlength{\pnas@vertadjust}{#1}}
+
+%% Custom title page
+\renewcommand{\@maketitle}{%
+{%
+\ifthenelse{\boolean{shortarticle}}
+{\ifthenelse{\boolean{singlecolumn}}{}{
+{\raggedright\baselineskip= 24pt\titlefont \@title\par}%
+\vskip10pt% 21pts between base of title and base of author line
+{\raggedright \@author\par}
+\vskip8pt% 16pts between base of affiliations and base of dates line
+{\raggedright \datesfont \@ifundefined{@dates}{}{\@dates}\par}
+\vskip12pt%
+}}
+{% else
+%
+\vskip10pt%
+{\raggedright\baselineskip= 24pt\titlefont \@title\par}%
+\vskip10pt% 21pts between base of title and base of author line
+{\raggedright \@author\par}
+\vskip8pt% 16pts between base of affiliations and base of dates line
+{\raggedright \datesfont \@ifundefined{@dates}{}{\@dates}\par}
+\vskip12pt
+{%
+\abscontent
+}%
+\vskip25pt%
+}%
+%%%
+\@additionalelement
+}%
+\vskip\pnas@vertadjust
+}%
+
+%% Footnotes set up
+\RequirePackage[flushmargin,ragged]{footmisc}
+\renewcommand*{\footnotelayout}{\normalfont\sffamily\fontsize{6}{8}\selectfont} % set the footnote font
+\renewcommand{\footnoterule}{% Set the footnote hrule style
+ \kern -3pt
+ {\color{black50} \hrule width 72pt height 0.25pt}
+ \kern 2.5pt
+}
+
+\definecolor{pinpblue}{HTML}{EB6622} % imagecolorpicker on blue for new R logo -- 185FAF
+
+%% Set up the acknowledgments field
+\titleclass{\acknow@section}{straight}[\part]
+\newcounter{acknow@section}
+\providecommand*{\toclevel@acknow@section}{0}
+% Format is set for research articles by default
+\titleformat{\acknow@section}[runin]
+ %{\sffamily\normalsize\bfseries}
+ {\sffamily\normalsize\bfseries\color{pinpblue}}
+ {}
+ {0em}
+ {#1.}
+ []
+\titlespacing{\acknow@section}
+ {0pt}
+ {3.25ex plus 1ex minus .2ex}
+ {1.5ex plus .2ex}
+\newcommand{\showacknow}{% Display acknowledgments section
+\@ifundefined{@acknow}{}{\acknow@section{ACKNOWLEDGMENTS}\small\@acknow}
+}
+
+%% Set up the materials&methods field
+\titleclass{\matmethods@section}{straight}[\part]
+\newcounter{matmethods@section}
+\providecommand*{\toclevel@matmethods@section}{0}
+% Format is set for research articles by default
+\titleformat{\matmethods@section}
+ {\sffamily\normalsize\bfseries}
+ {}
+ {0em}
+ {#1}
+ []
+\titlespacing{\matmethods@section}
+ {0pt}
+ {3.25ex plus 1ex minus .2ex}
+ {1.5ex plus .2ex}
+\newcommand{\showmatmethods}{% Display materials&methods section
+\@ifundefined{@matmethods}{}{\matmethods@section{Materials and Methods}{\small\noindent\@matmethods}}
+}
+
+\providecommand{\tightlist}{%
+ \setlength{\itemsep}{0pt}\setlength{\parskip}{0pt}}
+
+
+% Add colour to the title
+\appto{\titlefont}{\color{pinpblue}}
+
+% ...and section headings
+\titleformat{\section}
+ {\large\sffamily\bfseries\color{pinpblue}}
+ {\thesection.}
+ {0.5em}
+ {#1}
+ []
+\titleformat{name=\section,numberless}
+ {\large\sffamily\bfseries\color{pinpblue}}
+ {}
+ {0em}
+ {#1}
+ []
+\titleformat{\subsection}[runin]
+ {\sffamily\bfseries\color{pinpblue}} %\itshape}%
+ {\thesubsection.}
+ {0.5em}
+ {#1. }
+ []
+% Other section headings left unchanged.
+
+%% Other packages
+\RequirePackage{enumitem} % For reducing bullet list item separation
diff --git a/LegendMedCentral/pnas.csl b/LegendMedCentral/pnas.csl
new file mode 100644
index 00000000..fa7289d8
--- /dev/null
+++ b/LegendMedCentral/pnas.csl
@@ -0,0 +1,165 @@
+
+
\ No newline at end of file
diff --git a/LegendMedCentral/pnasresearcharticle.sty b/LegendMedCentral/pnasresearcharticle.sty
new file mode 100644
index 00000000..a86d288c
--- /dev/null
+++ b/LegendMedCentral/pnasresearcharticle.sty
@@ -0,0 +1,50 @@
+%%% PNAS two column research article style file
+%%% For use with pnas-new.cls
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{pnasresearcharticle}[2016/02/28 v1.2 PNAS two column research article style]
+
+%% Set whether the abstract is set into the first column
+\setboolean{shortarticle}{true}
+% true = set into first column
+% false = spans page width
+
+%% Set colors
+\definecolor{color2}{RGB}{130,0,0} % color
+
+%% Set up the first page footnote/fact box here
+\RequirePackage{float}
+\floatstyle{plain}
+\newfloat{sigstatement}{b!}{sst}
+
+\additionalelement{%
+\afterpage{\begin{sigstatement}
+\sffamily
+\mdfdefinestyle{pnassigstyle}{linewidth=0.7pt,backgroundcolor=pnasblueback,linecolor=pnasbluetext,fontcolor=pnasbluetext,innertopmargin=6pt,innerrightmargin=6pt,innerbottommargin=6pt,innerleftmargin=6pt}
+\@ifundefined{@significancestatement}{}{%
+ \begin{mdframed}[style=pnassigstyle]%
+ \section*{Significance Statement}%
+ \@significancestatement
+ \end{mdframed}}
+% \medskip
+\scriptsize
+\@ifundefined{@authorcontributions}{}{\@authorcontributions}
+\vskip5pt%
+\@ifundefined{@authordeclaration}{}{\@authordeclaration}
+\vskip5pt%
+\@ifundefined{@equalauthors}{}{\@equalauthors}
+\vskip5pt%
+\@ifundefined{@correspondingauthor}{}{\@correspondingauthor}
+\end{sigstatement}}
+}
+
+%% Break at end of article (before references)
+% The blank line before the strip command ensures there is nothing placed
+% directly before the break (which can cause formatting issues).
+\newcommand{\pnasbreak}{
+
+\begin{strip}
+\vskip-11pt
+\end{strip}
+}
+
+\endinput
\ No newline at end of file
diff --git a/LegendMedCentral/server.R b/LegendMedCentral/server.R
new file mode 100644
index 00000000..4f7dbaea
--- /dev/null
+++ b/LegendMedCentral/server.R
@@ -0,0 +1,200 @@
+library(shiny)
+library(ggplot2)
+library(DT)
+
+shinyServer(function(input, output, session) {
+
+ connection <- DatabaseConnector::connect(connectionDetails)
+
+ session$onSessionEnded(function() {
+ writeLines("Closing connection")
+ DatabaseConnector::disconnect(connection)
+ })
+
+ searchResults <- reactive({
+ query <- parseQueryString(session$clientData$url_search)
+ if (is.null(query$term)) {
+ return(NULL)
+ } else {
+ parts <- strsplit(query$term, " ")[[1]]
+ outcomeIds <- c()
+ exposureIds <- c()
+ databaseIds <- c()
+ for (part in parts) {
+ outcomeDist <- adist(part, outcomes$outcomeName)
+ exposureDist <- adist(part, exposures$exposureName)
+ databaseDist <- adist(part, databases$databaseId)
+ if (min(outcomeDist) < min(exposureDist)) {
+ if (min(databaseDist) < min(outcomeDist)) {
+ match <- databases$databaseId[databaseDist == min(databaseDist)]
+ writeLines(paste("Matched", part, "to database ID", match))
+ databaseIds <- c(databaseIds, match)
+ } else {
+ match <- outcomes$outcomeId[outcomeDist == min(outcomeDist)]
+ writeLines(paste("Matched", part, "to outcome ID", match))
+ outcomeIds <- c(outcomeIds, match)
+ }
+ } else {
+ if (min(databaseDist) < min(exposureDist)) {
+ match <- databases$databaseId[databaseDist == min(databaseDist)]
+ writeLines(paste("Matched", part, "to database ID", match))
+ databaseIds <- c(databaseIds, match)
+ } else {
+ match <- exposures$exposureId[exposureDist == min(exposureDist)]
+ writeLines(paste("Matched", part, "to exposure ID", match))
+ exposureIds <- c(exposureIds, match)
+ }
+ }
+ }
+ tcoDbs <- getTcoDbsStrict(connection, exposureIds = exposureIds, outcomeIds = outcomeIds, databaseIds = databaseIds)
+ return(tcoDbs)
+ }
+ })
+
+ selectedTcoDb <- reactive({
+ query <- parseQueryString(session$clientData$url_search)
+ if (is.null(query$targetId)) {
+ return(NULL)
+ } else {
+ tcoDb <- getTcoDbs(connection,
+ targetIds = query$targetId,
+ comparatorIds = query$comparatorId,
+ outcomeIds = query$outcomeId,
+ databaseIds = query$databaseId)
+ return(tcoDb)
+ }
+ })
+
+ # Maintain contents of search box:
+ observe({
+ query <- parseQueryString(session$clientData$url_search)
+ if (!is.null(query$term))
+ updateTextInput(session, "query", value = query$term)
+ })
+
+ output$isSearchPage <- reactive({
+ query <- parseQueryString(session$clientData$url_search)
+ return(is.null(query$targetId) && is.null(query$term))
+ })
+ outputOptions(output, "isSearchPage", suspendWhenHidden = FALSE)
+
+ output$isSearchResultPage <- reactive({
+ query <- parseQueryString(session$clientData$url_search)
+ return(is.null(query$targetId) && !is.null(query$term))
+ })
+ outputOptions(output, "isSearchResultPage", suspendWhenHidden = FALSE)
+
+ output$isAbstractPage <- reactive({
+ query <- parseQueryString(session$clientData$url_search)
+ return(!is.null(query$targetId))
+ })
+ outputOptions(output, "isAbstractPage", suspendWhenHidden = FALSE)
+
+
+ output$searchResults <- renderDataTable({
+ tcoDbs <- searchResults()
+ if (is.null(tcoDbs)) {
+ return(NULL)
+ } else {
+ titles <- createTitle(tcoDbs)
+ titles <- paste0("",
+ titles,
+ "LEGEND version 1.0, October 2018")
+ options <- list(pageLength = 15,
+ searching = FALSE,
+ lengthChange = TRUE,
+ paging = TRUE,
+ dom = "<\"top\"ip>rt<\"bottom\"flp><\"clear\">")
+ data <- data.frame(title = titles)
+ colnames(data) <- "Search results"
+ table <- datatable(data,
+ options = options,
+ rownames = TRUE,
+ escape = FALSE,
+ class = "compact")
+ return(table)
+ }
+ })
+
+ output$abstract <- renderUI({
+ tcoDb <- selectedTcoDb()
+ if (is.null(tcoDb)) {
+ return(NULL)
+ } else {
+
+ # targetName <- uncapitalize(exposures$exposureName[match(tcoDb$targetId, exposures$exposureId)])
+ # comparatorName <- uncapitalize(exposures$exposureName[match(tcoDb$comparatorId, exposures$exposureId)])
+ # outcomeName <- uncapitalize(outcomes$outcomeName[match(tcoDb$outcomeId, outcomes$outcomeId)])
+ # indicationId <- uncapitalize(exposures$indicationId[match(tcoDb$targetId, exposures$exposureId)])
+ #
+ # results <- getMainResults(connection,
+ # targetIds = tcoDb$targetId,
+ # comparatorIds = tcoDb$comparatorId,
+ # outcomeIds = tcoDb$outcomeId,
+ # databaseIds = tcoDb$databaseId)
+ #
+ # studyPeriod <- getStudyPeriod(connection = connection,
+ # targetId = tcoDb$targetId,
+ # comparatorId = tcoDb$comparatorId,
+ # databaseId = tcoDb$databaseId)
+
+ authors <- createAuthors()
+
+ # abstract <- createAbstract(outcomeName, targetName, comparatorName, tcoDb$databaseId, studyPeriod, results)
+ abstract <- createAbstract(connection, tcoDb)
+
+ title <- createTitle(tcoDb)
+
+ abstract <- div(em("LEGEND version 1.0"),
+ h2(title),
+ h3("Authors"),
+ p(authors),
+ h3("Abstract"),
+ p(abstract),
+ p("NB: This is an", strong("automatically"), "generated abstract.")
+ )
+ return(abstract)
+ }
+ })
+
+ output$pdf <- downloadHandler(filename = function() {
+ return("Paper.pdf")
+ }, content = function(con) {
+ tcoDb <- selectedTcoDb()
+ tcoDb$indicationId <- exposures$indicationId[match(tcoDb$targetId, exposures$exposureId)]
+ title <- createTitle(tcoDb)
+ abstract <- createAbstract(connection, tcoDb)
+ tempFileName <- paste0(paste(sample(letters, 8), collapse = ""), ".pdf")
+ withProgress(message = "Generating PDF", value = 0, {
+ rmarkdown::render("MyArticle.Rmd",
+ output_file = tempFileName,
+ params = list(targetId = tcoDb$targetId,
+ comparatorId = tcoDb$comparatorId,
+ outcomeId = tcoDb$outcomeId,
+ databaseId = tcoDb$databaseId,
+ indicationId = tcoDb$indicationId,
+ title = title,
+ abstract = abstract,
+ save = NULL,
+ load = NULL))
+ # createDocument(targetId = tcoDb$targetId,
+ # comparatorId = tcoDb$comparatorId,
+ # outcomeId = tcoDb$outcomeId,
+ # databaseId = tcoDb$databaseId,
+ # indicationId = tcoDb$indicationId,
+ # outputFile = tempFileName,
+ # workingDirectory = paste(sample(letters, 8), collapse = ""))
+ })
+ file.rename(tempFileName, con)
+ })
+})
diff --git a/LegendMedCentral/template.Rnw b/LegendMedCentral/template.Rnw
new file mode 100644
index 00000000..c7b266c9
--- /dev/null
+++ b/LegendMedCentral/template.Rnw
@@ -0,0 +1,787 @@
+\documentclass[9pt,twocolumn,twoside,]{pnas-new}
+
+%% Some pieces required from the pandoc template
+\providecommand{\tightlist}{%
+ \setlength{\itemsep}{0pt}\setlength{\parskip}{0pt}}
+
+% Use the lineno option to display guide line numbers if required.
+% Note that the use of elements such as single-column equations
+% may affect the guide line number alignment.
+
+
+\usepackage[T1]{fontenc}
+\usepackage[utf8]{inputenc}
+
+\usepackage{longtable}
+
+<>=
+params <- list(databaseId = DATABASE_ID_TAG,
+ targetId = TARGET_ID_TAG,
+ comparatorId = COMPARATOR_ID_TAG,
+ outcomeId = OUTCOME_ID_TAG,
+ indication = uncapitalize("INDICATION_ID_TAG"),
+ primary = 1,
+ ot = 1,
+ itt = 2,
+ matchOt = 3,
+ matchItt = 4
+ )
+@
+
+<>=
+library(DatabaseConnector)
+library(CohortMethod)
+library(Legend)
+library(knitr)
+library(xtable)
+library(ggplot2)
+source("CURRENT_DIRECTORY/DataPulls.R")
+source("CURRENT_DIRECTORY/PlotsAndTables.R")
+options(knitr.kable.NA = '')
+
+extraCriteria <- list(
+ depression = "Further, we exclude patients with diagnoses of bipolar disorder or schizophrenia on or prior to their index date."
+)
+
+extraCovariates <- list(
+ depression = "Prior number of depression treatments (1, 2, 3, 4, 5 or higher)"
+)
+@
+
+<>=
+useStoredObject <- FALSE
+
+if (!useStoredObject) {
+ connectionDetails <- createConnectionDetails(dbms = "postgresql",
+ server = paste(Sys.getenv("legendServer"),
+ Sys.getenv("legendDatabase"), sep = "/"),
+ port = Sys.getenv("legendPort"),
+ user = Sys.getenv("legendUser"),
+ password = Sys.getenv("legendPw"),
+ schema = Sys.getenv("legendSchema"))
+ connection <- connect(connectionDetails)
+ targetName <- getExposureName(connection = connection, exposureId = params$targetId)
+ comparatorName <- getExposureName(connection = connection, exposureId = params$comparatorId)
+ outcomeName <- getOutcomeName(connection = connection, outcomeId = params$outcomeId)
+ analyses <- getAnalyses(connection = connection)
+ databaseDetails <- getDatabaseDetails(connection = connection,
+ databaseId = params$databaseId)
+ studyPeriod <- getStudyPeriod(connection = connection,
+ targetId = params$targetId,
+ comparatorId = params$comparatorId,
+ databaseId = params$databaseId)
+ mainResults <- getMainResults(connection = connection,
+ targetIds = params$targetId,
+ comparatorIds = params$comparatorId,
+ outcomeIds = params$outcomeId,
+ databaseIds = params$databaseId,
+ analysisIds = c(1, 2, 3, 4))
+
+ subgroupResults <- getSubgroupResults(connection = connection,
+ targetIds = params$targetId,
+ comparatorIds = params$comparatorId,
+ outcomeIds = params$outcomeId,
+ databaseIds = params$databaseId)
+
+ controlResults <- getControlResults(connection = connection,
+ targetId = params$targetId,
+ comparatorId = params$comparatorId,
+ analysisId = 1,
+ databaseId = params$databaseId)
+
+ attrition <- getAttrition(connection = connection,
+ targetId = params$targetId,
+ comparatorId = params$comparatorId,
+ outcomeId = params$outcomeId,
+ analysisId = 1,
+ databaseId = params$databaseId)
+
+ followUpDist <- getCmFollowUpDist(connection = connection,
+ targetId = params$targetId,
+ comparatorId = params$comparatorId,
+ outcomeId = params$outcomeId,
+ databaseId = params$databaseId,
+ analysisId = 1)
+
+ balance <- getCovariateBalance(connection = connection,
+ targetId = params$targetId,
+ comparatorId = params$comparatorId,
+ databaseId = params$databaseId,
+ analysisId = 2)
+
+ popCharacteristics <- getCovariateBalance(connection = connection,
+ targetId = params$targetId,
+ comparatorId = params$comparatorId,
+ databaseId = params$databaseId,
+ analysisId = 1,
+ outcomeId = params$outcomeId)
+
+ ps <- getPs(connection = connection,
+ targetIds = params$targetId,
+ comparatorIds = params$comparatorId,
+ databaseId = params$databaseId)
+
+ kaplanMeier <- getKaplanMeier(connection = connection,
+ targetId = params$targetId,
+ comparatorId = params$comparatorId,
+ outcomeId = params$outcomeId,
+ databaseId = params$databaseId,
+ analysisId = 2)
+} else {
+ load("paperData.rda")
+ targetName <- uncapitalize(targetName)
+ comparatorName <- uncapitalize(comparatorName)
+ outcomeName <- uncapitalize(outcomeName)
+}
+
+
+targetName <- uncapitalize(targetName)
+comparatorName <- uncapitalize(comparatorName)
+outcomeName <- uncapitalize(outcomeName)
+
+databaseName <- databaseDetails$databaseName
+
+minYear <- substr(studyPeriod$minDate, 1, 4)
+maxYear <- substr(studyPeriod$maxDate, 1, 4)
+
+coverage <- getCoverage(controlResults)
+
+@
+
+\templatetype{pnasresearcharticle} % Choose template
+
+\title{ \Sexpr{capitalize(outcomeName)} risk in new-users of \Sexpr{targetName} versus \Sexpr{comparatorName}
+for \Sexpr{params$indication} in the \Sexpr{params$databaseId} database}
+
+\author[a,b,c,1]{Martijn J. Schuemie}
+\author[a,b,d]{Patrick B. Ryan}
+\author[a,e]{Seng Chan You}
+\author[a,f]{Nicole Pratt}
+\author[a,g]{David Madigan}
+\author[a,d]{George Hripcsak}
+\author[a,c,h,i]{Marc A. Suchard}
+
+ \affil[a]{Observational Health Data Sciences and Informatics, New York, NY, USA}
+ \affil[b]{Janssen Research \& Development, Titusville, NJ, USA}
+ \affil[c]{Department of Biostatistics, University of Califoria, Los Angeles, CA}
+ \affil[d]{Department of Biomedical Informatics, Columbia University, New York, NY}
+ \affil[e]{Department of Biomedical Informatics, Ajou University, Suwon, South
+Korea}
+ \affil[f]{Sansom Institute, University of South Australia, Adelaide SA, Australia}
+ \affil[g]{Department of Statistics, Columbia University, New York, NY}
+ \affil[h]{Department of Biomathematics, University of Califoria, Los Angeles, CA}
+ \affil[i]{Department of Human Genetics, University of Califoria, Los Angeles, CA}
+
+
+% Please give the surname of the lead author for the running footer
+\leadauthor{Schuemie}
+
+% Please add here a significance statement to explain the relevance of your work
+% \significancestatement{Authors must submit a 120-word maximum statement about the significance
+% of their research paper written at a level understandable to an
+% undergraduate educated scientist outside their field of speciality. The
+% primary goal of the Significance Statement is to explain the relevance
+% of the work in broad context to a broad readership. The Significance
+% Statement appears in the paper itself and is required for all research
+% papers.}
+
+% \authorcontributions{Please provide details of author contributions here.}
+
+\authordeclaration{
+MJS and PBR are employees and share-holders of Janssen Research.
+MAS receives contract support from Janssen Research.
+}
+
+\equalauthors{\textsuperscript{} }
+
+\correspondingauthor{\textsuperscript{Corresponding author contact: \url{mschuemie@ohdsi.org}} }
+
+% Keywords are not mandatory, but authors are strongly encouraged to provide them. If provided, please include two to five keywords, separated by the pipe symbol, e.g:
+ % \keywords{ one | two | optional | optional | optional }
+
+\begin{abstract}
+We conduct a large-scale study on the incidence of \Sexpr{outcomeName} among new users of \Sexpr{targetName} and \Sexpr{comparatorName} from \Sexpr{minYear} to \Sexpr{maxYear} in the \Sexpr{params$databaseId} database.
+Outcomes of interest are estimates of the hazard ratio (HR) for incident events between comparable new users under on-treatment and intent-to-treat risk window assumptions. Secondary analyses entertain possible clinically relevant subgroup interaction with the HR.
+We identify \Sexpr{mainResults[params$primary,"targetSubjects"]} \Sexpr{targetName} and \Sexpr{mainResults[params$primary,"comparatorSubjects"]} \Sexpr{comparatorName} patients for the on-treatment design, totaling \Sexpr{round(mainResults[params$primary,"targetDays"]/365.24)} and \Sexpr{round(mainResults[params$primary,"comparatorDays"]/365.24)} patient-years of observation, and \Sexpr{mainResults[params$primary,"targetOutcomes"]} and \Sexpr{mainResults[params$primary,"comparatorOutcomes"]} events respectively.
+We control for measured confounding using propensity score trimming and stratification or matching based on an expansive propensity score model that includes all measured patient features before treatment initiation.
+We account for unmeasured confounding using negative and positive controls to estimate and adjust for residual systematic bias in the study design and data source, providing calibrated confidence intervals and $p$-values.
+In terms of \Sexpr{outcomeName}, \Sexpr{targetName} has a
+\Sexpr{judgeHazardRatio(mainResults[params$primary,"calibratedCi95Lb"], mainResults[params$primary,"calibratedCi95Ub"])}
+risk as \Sexpr{comparatorName} [HR: \Sexpr{prettyHr(mainResults[params$primary,"calibratedRr"])},
+95\% confidence interval (CI) \Sexpr{prettyHr(mainResults[params$primary, "calibratedCi95Lb"])} - \Sexpr{prettyHr(mainResults[params$primary, "calibratedCi95Ub"])}].
+%We demonstrate (TODO) \Sexpr{judgePropensityScore(1.1,1.1)}.
+%In conclusion, we find that \Sexpr{targetName} is \Sexpr{judgeEffectiveness(mainResults[params$primary,"calibratedCi95Lb"], mainResults[params$primary,"calibratedCi95Ub"])} effective as \Sexpr{comparatorName} in preventing \Sexpr{outcomeName}.
+\end{abstract}
+
+\dates{This manuscript was \textbf{automatically} compiled on \today.}
+% \doi{\url{ADD}}
+
+\begin{document}
+\SweaveOpts{concordance=TRUE}
+
+% Optional adjustment to line up main text (after abstract) of first page with line numbers, when using both lineno and twocolumn options.
+% You should only change this length when you've finalised the article contents.
+\verticaladjustment{-2pt}
+
+\maketitle
+\thispagestyle{firststyle}
+\ifthenelse{\boolean{shortarticle}}{\ifthenelse{\boolean{singlecolumn}}{\abscontentformatted}{\abscontent}}{}
+
+% If your first paragraph (i.e. with the \dropcap) contains a list environment (quote, quotation, theorem, definition, enumerate, itemize...), the line after the list may have some extra indentation. If this is the case, add \parshape=0 to the end of the list environment.
+
+\acknow{We are grateful for \ldots.}
+
+The Large-scale Evidence Generation and Evaluation in a Network of Databases (LEGEND) project aims to generate reliable evidence on the effects of medical interventions using observational healthcare data to support clinical decision making.
+LEGEND follows ten guiding principles (see Supplementary Material); chief among these stand that we generate evidence at large-scale to achieve completeness and faciliate analysis of the overall distribution of effect size estimates across treatments and outcomes.
+We also generate evidence consistently by applying a systematic approach across all research questions and disseminate evidence regardless on the estimates effects to avoid publication bias. These aims help overcome the questionable reliable of observational research [schuemie2018].
+This LEGEND document reports the risk of \Sexpr{outcomeName} between new users of \Sexpr{targetName} and \Sexpr{comparatorName} treated for \Sexpr{params$indication}.
+
+\begin{itemize}
+ \item Add short introduction to indication.
+\end{itemize}
+
+\hypertarget{methods}{%
+\section*{Methods}\label{methods}}
+\addcontentsline{toc}{section}{Methods}
+
+\subsection*{Data source}
+We conduct a new-user cohort study comparing new users of \Sexpr{targetName} with new users of \Sexpr{comparatorName} in the \Sexpr{params$databaseName} (\Sexpr{params$databaseId}) database encoded in the Observational Medical Outcomes Partnership (OMOP) common data model (CDM) version 5 %\citep{hripcsak2015observational,overhage2012validation,ryan2013empirical}
+.
+\Sexpr{sub(paste0(".*\\(",databaseDetails$databaseId,"\\)"), databaseDetails$databaseId, databaseDetails$description)}
+The study period spans from \Sexpr{studyPeriod$minDate} to \Sexpr{studyPeriod$maxDate}.
+
+\subsection*{Study design}
+This study follows a retrospective, observational, comparative cohort design %\citep{ryan2013empirical}
+.
+We include patients who are first time users of \Sexpr{targetName} or \Sexpr{comparatorName}, and who have a diagnosis of \Sexpr{params$indication} on or prior to treatment initation.
+We require that patients have continuous observation in the database for at least 365 days prior to treatment initiation.
+We exclude patients with prior \Sexpr{outcomeName} events and less than 1 day at risk.
+\Sexpr{extraCriteria["depression"]}
+Full cohort details, include concept codes, are provided in the Supplementary Inforamtion (add link).
+The outcome of interest is \Sexpr{outcomeName}.
+We begin the outcome risk window 1 day after treatment initation and consider two design choices to define the window end.
+%As our primary analysis, we have pre-specified \ldots
+%We consider two design choices to define
+First, we end the outcome time-at-risk window at first cessation of continuous drug exposure, analogous to an on-treatment design and, second, we end the outcome time-at-risk window when the patient is no longer observable in the database, analogous to an intent-to-treat design.
+%
+Continuous drug exposures are constructed from the available longitudinal data by considering sequential prescriptions that have fewer than 30 days gap between prescriptions.
+
+\subsection*{Statistical analysis}
+We conduct our cohort study using the open-source OHDSI CohortMethod R package %\citep{schuemie2017cohort}
+, with large-scale analytics achieved through the Cyclops R package %\citep{suchard2013high?}
+.
+We use propensity scores (PSs) -- estimates of treatment exposure probability conditional on pre-treatment baseline features in the one year prior to treatment initiation -- to control for potential measured confoudning and improve balance between the target (\Sexpr{targetName}) and comparator (\Sexpr{comparatorName}) cohorts %\citep{rosenbaum1983central}
+.
+We use an expansive PS model that includes all available patient demographics, drug, condition and procedure covariates generated through the FeatureExtraction R package %\citep{schuemie2018feature}
+ instead of a prespecified set of investigator-selected confounders.
+ We perform PS stratification or variable-ratio matching and then estimate comparative \Sexpr{targetName}-vs-\Sexpr{comparatorName} hazard ratios (HRs) using a Cox proportional hazards model.
+ Detailed covariate and methods informations are provided in the Supplementary Information (add link).
+ We present PS and covariate balance metrics to assess successful confounding control, and provide HR estimates and Kaplan-Meier survival plots for the outcome of \Sexpr{outcomeName}.
+ We additionally estimate HRs for pre-specified subgroups to evaluate interactions with the treatment effect.
+For efficiency reasons, we fit subgroup Cox models using PS stratification only.
+
+Residual study bias from unmeasured and systematic sources can exist in observational studies after controlling for measured confounding %\citep{schuemie2018reliable}
+.
+To estimate such residual bias, we conduct negative control outcome experiments with \Sexpr{length(unique(controlResults$outcomeName))} negative control outcomes %\citep{negative-controls}
+identified through a data-rich algorithm %\citep{voss2017accuracy}
+.
+We fit the negative control estimates to an empirical null distribution that characterizes the study residual bias and is an important artifact from which to assess the study design %\citep{schuemie2014interpreting,schuemie2018empirical}
+.
+Using the empirical null distribution and synthetic positive controls %\citep{positive-controls}
+, we additionally calibrate all HR estimates, their 95\% confidence intervals (CIs) and the $p$-value to reject the null hypothesis of no differential effect (HR = 1).
+Empirical calibration serves as an important diagnostic tool to evaluate if residual systematic error is sufficient to cast doubt on the accuracy of the unknown effect estimate.
+
+\hypertarget{results}{%
+\section*{Results}\label{results}}
+\addcontentsline{toc}{section}{Results}
+
+\subsection*{Population characteristics}
+
+Figure \ref{fig:attrition} diagrams the inclusion of study subjects from the \Sexpr{params$databaseId} database under the on-treatment with stratification design.
+%
+%For the intent-to-treatment analysis, we identify \Sexpr{mainResults[params$itt,"targetSubjects"]} \Sexpr{targetName} and \Sexpr{mainResults[params$itt,"comparatorSubjects"]} \Sexpr{comparatorName} patients, totaling \Sexpr{round(mainResults[params$itt,"targetDays"]/365.24)} and \Sexpr{round(mainResults[params$itt,"comparatorDays"]/365.24)} patient-years of observation, and \Sexpr{mainResults[params$itt,"targetOutcomes"]} and \Sexpr{mainResults[params$itt,"comparatorOutcomes"]} events respectively.
+%Similarly, for the on-treatment analylsis, we identify \Sexpr{mainResults[params$ot,"targetSubjects"]} \Sexpr{targetName} and \Sexpr{mainResults[params$ot,"comparatorSubjects"]} \Sexpr{comparatorName} patients, totaling \Sexpr{round(mainResults[params$ot,"targetDays"]/365.24)} and \Sexpr{round(mainResults[params$ot,"comparatorDays"]/365.24)} patient-years of observation, and \Sexpr{mainResults[params$ot,"targetOutcomes"]} and \Sexpr{mainResults[params$ot,"comparatorOutcomes"]} events respectively.
+<>==
+plot <- drawAttritionDiagram(attrition, targetName, comparatorName)
+suppressMessages(ggsave("attrition.pdf", plot,
+ width = 6, height = 10, units = "in"))
+@
+%
+\begin{figure}
+ \vspace*{-1em}
+ \centerline{\includegraphics[width=0.45\textwidth]{attrition}}
+ \vspace*{-2em}
+ \caption{\textbf{Attrition diagram for selecting new-users of \Sexpr{targetName} and \Sexpr{comparatorName} from the \Sexpr{params$databaseId} database.}}
+ \label{fig:attrition}
+\end{figure}
+%
+We augment these counts with cohort sizes we identify for the remaining designs in Table \ref{tab:power}.
+This table also reports total patient follow-up time, numbers of \Sexpr{outcomeName} events these patients experience and unadjusted incidence rates.
+%
+\begin{table*}
+\caption{\textbf{Patient cohorts.}
+Target (T) cohort is \Sexpr{targetName} new-users. Comparative (C) cohort is \Sexpr{comparatorName} new-users.
+%
+We report total number of patients, follow-up time (in years), number of \Sexpr{outcomeName} events, and event incidence rate (IR) per 1,000 patient years (PY) in patient cohorts, as well as the their minimum detectable relative risk (MDRR).
+%
+Note that the IR does not account for any stratification or matching.
+}\label{tab:power}
+\vspace*{-0.5em}
+\centering{
+\begin{tabular}{lrrrrrrrrr}
+\hline
+ &
+\multicolumn{2}{c}{Patients} &
+\multicolumn{2}{c}{PYs} &
+\multicolumn{2}{c}{Events} &
+\multicolumn{2}{c}{IR} &
+%\multicolumn{1}{c}{MDRR}
+\\
+\multicolumn{1}{c}{Design} &
+\multicolumn{1}{c}{T} & \multicolumn{1}{c}{C} &
+\multicolumn{1}{c}{T} & \multicolumn{1}{c}{C} &
+\multicolumn{1}{c}{T} & \multicolumn{1}{c}{C} &
+\multicolumn{1}{c}{T} & \multicolumn{1}{c}{C} &
+\multicolumn{1}{c}{MDRR} \\
+\hline
+<>==
+table <- preparePowerTable(mainResults, analyses)
+
+print(xtable(table, format = "latex"),
+ include.rownames = FALSE,
+ include.colnames = FALSE,
+ hline.after = NULL,
+ only.contents = TRUE,
+ sanitize.text.function = identity)
+@
+\hline
+\end{tabular}
+}
+\end{table*}
+%
+Table \ref{tab:demographics} compares base-line characteristics between patient cohorts.
+%
+\begin{table}
+\caption{\textbf{Patient demographics.} We report the standardized difference of population means (StdDiff) before and after stratification for selected base-line patient characteristics.}\label{tab:demographics}
+\vspace*{-0.5em}
+\centerline{
+\resizebox{0.5\textwidth}{!}{
+\begin{tabular}{lrrrrrr}
+\hline
+& \multicolumn{3}{c}{Before stratification}
+& \multicolumn{3}{c}{After stratification} \\
+\multicolumn{1}{c}{Characteristic}
+ & \multicolumn{1}{c}{T (\%)}
+ & \multicolumn{1}{c}{C (\%)}
+ & \multicolumn{1}{c}{StdDiff}
+ & \multicolumn{1}{c}{T (\%)}
+ & \multicolumn{1}{c}{C (\%)}
+ & \multicolumn{1}{c}{StdDiff} \\
+ \hline
+<>==
+table <- prepareTable1(balance, pathToCsv = "CURRENT_DIRECTORY/Table1Specs.csv")
+table <- table[3:nrow(table),]
+
+print(xtable(table, format = "latex", align = c("l","l","r","r","r","r","r","r")),
+ include.rownames = FALSE,
+ include.colnames = FALSE,
+ hline.after = NULL,
+ only.contents = TRUE,
+ sanitize.text.function = identity)
+@
+\hline
+\end{tabular}
+}
+}
+\end{table}
+
+\subsection*{Patient characteristics balance}
+Figure \ref{fig:ps} plots the preference score distributions, re-scalings of PS estimates to adjust for differential treatment prevalences, for patients treated with \Sexpr{targetName} and \Sexpr{comparatorName}.
+We assess characteristics balance achieved through PS adjustment by comparing all characteristics' standardized difference (StdDiff) between treatment group means before and after PS trimming and stratification (Table \ref{tab:demographics}).
+Figure \ref{fig:balance} plots StdDiff for all \Sexpr{nrow(balance)} base-line patient features that serve as input for the PS model.
+Before stratification, \Sexpr{sum(na.omit(balance$beforeMatchingStdDiff) > 0.1)} features have a StdDiff $> 0.1$. After stratification, the count is \Sexpr{sum(na.omit(balance$afterMatchingStdDiff) > 0.1)}.
+%
+<>==
+plot <- plotPs(ps, targetName, comparatorName)
+suppressMessages(ggsave("ps.pdf", plot,
+ width = 5, height = 5, units = "in"))
+@
+%
+\begin{figure}
+ \centerline{
+ \includegraphics[width=0.35\textwidth]{ps}
+ }
+ \caption{\textbf{Preference score distribution for sertaline and dulexotine new-users.}
+ The preference score is a transformation of the propensity score that adjusts for prevalence differences between populations. A higher overlap indicates that subjects in the two populations are more similar in terms of their predicted probability of receiving one treatment over the other.
+ }
+ \label{fig:ps}
+\end{figure}
+%
+<>==
+plot <- CohortMethod::plotCovariateBalanceScatterPlot(balance,
+ beforeLabel = "Before stratification",
+ afterLabel = "After stratification")
+suppressMessages(ggsave("balance.pdf", plot,
+ width = 5, height = 5, units = "in"))
+@
+%
+\begin{figure}
+ \centerline{
+ \includegraphics[width=0.35\textwidth]{balance}
+ }
+ \caption{\textbf{Patient characteristics balance before and after stratification.} As a rule-of-thumb, all values $< 0.1$ is generally considered well-balanced (add citation).}
+ \label{fig:balance}
+\end{figure}
+%
+(TODO) Add judgement statement about measured confounding control using something like: \Sexpr{judgePropensityScore(1.1,1.1)}
+%
+%Finally, Figure \ref{fig:topTen} presents the top ten most imbalanced characteristics before and after stratification.
+% %
+% make_features, echo=FALSE, cache=TRUE>>==
+% plot <- CohortMethod::plotCovariateBalanceOfTopVariables(balance, n = 10,
+% beforeLabel = "before",
+% afterLabel = "after",
+% maxNameWidth = 50)
+% plot$theme$legend.direction <- "horizontal"
+% suppressMessages(ggsave("top_10.pdf", plot,
+% width = 5, height = 3.5, units = "in"))
+% @
+% %
+% \begin{figure}
+% \centerline{
+% \includegraphics[width=0.5\textwidth]{top_10}
+% }
+% \caption{\textbf{Top ten most imbalanced patient characteristics before and after stratification.}}
+% \label{fig:topTen}
+% \end{figure}
+% @
+
+\subsection*{Outcome assessment}
+
+Table \ref{tab:fu} details the time to first \Sexpr{outcomeName} or censoring distributions for patients in the \Sexpr{targetName} and \Sexpr{comparatorName} cohorts.
+%
+\begin{table}
+\caption{Time-at-risk distributions as percentiles in the target and comparator cohorts after stratification.}
+\label{tab:fu}
+\begin{tabular}{crrrrrrr}
+\hline
+&
+\multicolumn{1}{c}{min} &
+\multicolumn{1}{c}{10\%} &
+\multicolumn{1}{c}{25\%} &
+\multicolumn{1}{c}{50\%} &
+\multicolumn{1}{c}{75\%} &
+\multicolumn{1}{c}{90\%} &
+\multicolumn{1}{c}{max} \\
+\hline
+<>==
+table <- prepareFollowUpDistTable(followUpDist)
+table$Cohort <- c(targetName, comparatorName)
+
+print(xtable(table, format = "latex"),
+ include.rownames = FALSE,
+ include.colnames = FALSE,
+ hline.after = NULL,
+ only.contents = TRUE,
+ sanitize.text.function = identity)
+@
+\hline
+\end{tabular}
+\end{table}
+%
+% **Table 2**. Time (days) at risk distribution expressed as minimum (Min), 10th Percentile (P10), 25th percentile (P25), median, 75th percentile (P75), 90th percentile (P90) and maximum (Max) in the target and comparator cohort after stratification.
+% ```{r, echo = FALSE}
+% table <- prepareFollowUpDistTable(followUpDist)
+% kable_styling(kable(table, "latex",
+% booktabs = TRUE,
+% longtable = FALSE,
+% row.names = FALSE,
+% linesep = "",
+% align = c("l", "r", "r", "r", "r", "r", "r", "r")),
+% font_size = 8,
+% latex_options = c("HOLD_position"))
+%
+% ```
+%
+We report in Table \ref{tab:hr} estimated HRs comparing \Sexpr{targetName} to \Sexpr{comparatorName} for the on-treatment and intent-to-treat designs with stratification or matching.
+%
+%The table also presents HRs after adjusting for possible subgroup differences (how we know which subgroups?).
+%
+\begin{table*}
+\caption{Hazard ratio (HR) estimates and their confidence intervals (CIs) and $p$-value to reject the null hypothesis of no difference (HR = 1) under various designs.}
+\label{tab:hr}
+\vspace*{-0.5em}
+\centerline{
+\begin{tabular}{lrrrr}
+\hline
+& \multicolumn{2}{c}{Uncalibrated} & \multicolumn{2}{c}{Calibrated} \\
+\multicolumn{1}{c}{Design}
+& \multicolumn{1}{c}{HR (95\% CI)} & \multicolumn{1}{c}{$p$}
+& \multicolumn{1}{c}{HR (95\% CI)} & \multicolumn{1}{c}{$p$} \\
+\hline
+<>==
+table <- mainResults
+table$hr <- sprintf("%.2f (%.2f - %.2f)", mainResults$rr, mainResults$ci95lb, mainResults$ci95ub)
+table$p <- sprintf("%.2f", table$p)
+table$calHr <- sprintf("%.2f (%.2f - %.2f)", mainResults$calibratedRr, mainResults$calibratedCi95Lb, mainResults$calibratedCi95Ub)
+table$calibratedP <- sprintf("%.2f", table$calibratedP)
+table <- merge(table, analyses)
+table <- table[, c("description", "hr", "p", "calHr", "calibratedP")]
+
+print(xtable(table),
+ include.rownames = FALSE,
+ include.colnames = FALSE,
+ hline.after = NULL,
+ only.contents = TRUE,
+ sanitize.text.function = identity)
+@
+\hline
+\end{tabular}
+}
+\end{table*}
+%
+Figure \ref{fig:km} plots Kaplan-Meier survival curves for patients under the intent-to-treat design.
+%
+<>==
+if (nrow(kaplanMeier) > 0) {
+ plot <- plotKaplanMeier(kaplanMeier, targetName, comparatorName)
+ # + ggplot2::theme(plot.margin=grid::unit(c(0,0,0,0), "mm"))
+ suppressMessages(ggsave("km.pdf", plot,
+ width = 6, height = 6, units = "in"))
+} else {
+ system("cp missing.pdf km.pdf")
+}
+@
+%
+\begin{figure}
+ %\centerline{
+ \hspace*{-1em}
+ \includegraphics[width=0.5\textwidth]{km}
+ %}
+ \vspace*{-1em}
+ \caption{\textbf{Kaplan Meier plot of \Sexpr{outcomeName}-free survival.}
+ This plot is adjusted for the propensity score stratification; the \Sexpr{targetName} curveshows the actual observed survival. The \Sexpr{comparatorName} curve applies reweighting to approximate the counterfactual of what \Sexpr{targetName} survival
+ would look like had the \Sexpr{targetName} cohort been exposed to the \Sexpr{comparatorName} instead. The shaded area denotes the 95\% CI.
+ }
+ \label{fig:topTen}
+\end{figure}
+%
+To examine possible subgroup differences in treatment-effect, we include Table{tab:subgroups} that reports HR estimates separately for children (age $<$ 18), the elderly (age $\ge$ 65), female patients, pregnant women, patients with hepatic impairment and patients with renal impairment, using PS stratification.
+%
+\begin{table*}
+\caption{
+Subgroup analyses. We report HR estimates, their 95\% CIs and uncalibrated and calibrated (cal) $p$-values to reject the null hypothesis of no difference in five pre-specified patient subgroups.
+}
+\label{tab:subgroups}
+\centering{
+\begin{tabular}{lrrrrrrrr}
+\hline
+&
+\multicolumn{2}{c}{Subjects} &
+\multicolumn{3}{c}{On-treatment} &
+\multicolumn{3}{c}{Intent-to-treat} \\
+\multicolumn{1}{c}{Subgroup} &
+\multicolumn{1}{c}{T} &
+\multicolumn{1}{c}{C} &
+\multicolumn{1}{c}{HR (95\% CI)} &
+\multicolumn{1}{c}{$p$} &
+\multicolumn{1}{c}{cal-$p$} &
+\multicolumn{1}{c}{HR (95\% CI)} &
+\multicolumn{1}{c}{$p$} &
+\multicolumn{1}{c}{cal-$p$} \\
+\hline
+<>==
+table <- prepareSubgroupTable(subgroupResults)
+print(xtable(table),
+ include.rownames = FALSE,
+ include.colnames = FALSE,
+ hline.after = NULL,
+ only.contents = TRUE,
+ sanitize.text.function = identity)
+@
+\hline
+\end{tabular}
+}
+\end{table*}
+%
+
+\subsection*{Residual systematic error}
+In the absense of bias, we expect 95\% of negative and positive control estimate 95\% confidence intervals to include their presumed HR. In the case of negative controls, the presumed HR = 1. Figure \ref{fig:negatives} describes the negative and positive control estimates under the on-treatment with PS stratification design.
+<>==
+plot <- plotScatter(controlResults)
+suppressMessages(ggsave("error.pdf", plot,
+ width = 14, height = 4, units = "in"))
+@
+\begin{figure*}
+\centerline{
+\includegraphics[width=1.0\textwidth]{error}
+}
+\caption{
+\textbf{Evaluation of effect estimation between \Sexpr{targetName} and \Sexpr{comparatorName} new-users}. The top plots HRs and their corresponding standard errors before calibration for each negative and synthetic positive control. The bottom plots the same estimates after calibration.
+}
+\label{fig:negatives}
+\end{figure*}
+%
+Before calibration, negative and positive controls demonstrate \Sexpr{judgeCoverage(coverage[coverage$group == "Uncalibrated", "coverage"])} coverage. After calibration, controls demonstrate \Sexpr{judgeCoverage(coverage[coverage$group == "Calibrated", "coverage"])} coverage.
+% (TODO) Add judgement statement about residual bias control, using something like: \Sexpr{judgePropensityScore(1.1,1.1)}.
+% \begin{itemize}
+% \item Insert negative control plots
+% \end{itemize}
+
+\hypertarget{conclusions}{%
+\section*{Conclusions}\label{conclusions}}
+\addcontentsline{toc}{section}{Conclusions}
+
+We find that \Sexpr{targetName} has a
+\Sexpr{judgeHazardRatio(mainResults[params$primary,"calibratedCi95Lb"], mainResults[params$primary,"calibratedCi95Ub"])}
+risk of \Sexpr{outcomeName} as \Sexpr{comparatorName} within the population that the \Sexpr{params$databaseId} represents.
+%(What else?)
+
+\hypertarget{supporting-information-si}{%
+\subsection*{Supporting Information
+(SI)}\label{supporting-information-si}}
+\addcontentsline{toc}{subsection}{Supporting Information (SI)}
+
+Here we provide extended details on study cohorts and design and the guiding principles of LEGEND.
+
+\hypertarget{si-principles}{%
+\subsubsection*{SI LEGEND Principles}\label{si-text}}
+\addcontentsline{toc}{subsubsection}{SI Principles} (Need to re-order these)
+
+\begin{enumerate}[noitemsep]
+ \item Evidence will be generated at large-scale.
+ \item Dissemination of the evidence will not depend on the estimated effects.
+ \item Evidence will be generated by consistently applying a systematic approach across all research questions.
+ \item Evidence will be generated using a pre-specified analysis design.
+ \item Evidence will be generated using open source software that is freely available to all.
+ \item Evidence generation process will be empirically evaluated by including control research questions where the true effect size is known.
+ \item Evidence will be generated using best-practices.
+ \item LEGEND will not be used to evaluate methods.
+ \item Evidence will be updated on a regular basis.
+ \item No patient-level data will be shared between sites in the network, only aggregated data.
+\end{enumerate}
+
+\subsubsection*{SI \Sexpr{capitalize(targetName)} cohort definition}
+(TODO)
+
+\subsubsection*{SI \Sexpr{capitalize(comparatorName)} cohort definition}
+(TODO)
+
+\subsubsection*{SI \Sexpr{capitalize(outcomeName)} cohort definition}
+(TODO)
+
+\subsubsection*{SI Covariate sets}
+\begin{itemize}[noitemsep]
+\item Demographics (age in 5-year bands, gender, index year, index month)
+\item Conditions (condition occurrence in lookback window)
+ \begin{itemize}[noitemsep]
+ \item in 365 days prior to index date\
+ \item in 30 days prior to index date
+ \end{itemize}
+\item Condition aggregation
+ \begin{itemize}[noitemsep]
+ \item SMOMED
+ \end{itemize}
+\item Drugs (drug occurrence in lookback window)
+ \begin{itemize}[noitemsep]
+ \item in 365 days prior to index date
+ \item in 30 days prior to index date
+ \end{itemize}
+\item Drug aggregation
+ \begin{itemize}[noitemsep]
+ \item Ingredient
+ \item ATC class
+ \end{itemize}
+\item Risk Scores (Charlson comorbidity index)
+\item \Sexpr{extraCovariates["depression"]}
+\end{itemize}
+
+We exclude all covariates that occur in fewer than 0.1\% of patients within the target and comparator cohorts prior to model fitting for computational efficiency.
+
+\subsubsection*{SI Anticoagulants Study Negative Controls}
+Negative controls were selected using the following criteria:
+\begin{itemize}[noitemsep]
+ \item No evidence found in literature on clinical trials using the method proposed by Avillach %\citep{avillach2012design}
+ \item No evidence found in literature using the method used in SemMedDB %\citep{kilicoglu2011constructing}
+ \item No evidence found in the structured product label (US and EU).
+ \item FAERS Proportional Reporting Ratio (PRR) needed to be less than 2.
+\end{itemize}
+
+Negative controls were rank-ordered by prevalence in study cohort, and manually reviewed until 50 controls were selected. Negative controls with fewer than $0.02\%$ prevalence were discarded. See Table \ref{tab:negatives}
+%
+%\vspace*{-2em}
+\begin{table}
+\caption{Negative controls employed with \Sexpr{params$indication} patients.}
+\label{tab:negatives}
+\vspace*{-1em}
+\begin{tabular}{ll}
+\hline
+% \begin{table}[t]{ |p{8.1cm} | p{8.1cm} |} \hline
+Acute bronchitis & Allergic rhinitis \\
+Anxiety disorder & Arthritis of spine \\
+Arthropathy of knee joint & Atelectasis \\
+Barrett's esophagus & Blepharitis \\
+Bronchiectasis & Bundle branch block \\
+Cellulitis & Chronic sinusitis \\
+Chronic ulcer of skin & Communication disorder \\
+Crohn's disease & Curvature of spine \\
+Cutis laxa & Diabetic renal disease \\
+Diabetic retinopathy & Dislocation of joint \\
+Dyssomnia & Dysuria \\
+Effusion of joint & Fracture of upper limb \\
+Gallstone & Gammopathy \\
+Human papilloma virus infection & Hyperplasia of prostate \\
+Inflammation of sacroiliac joint & Ingrowing nail \\
+Malignant tumor of breast & Multiple sclerosis \\
+Neck pain & Neurologic disorder associated \\
+& $\quad$ with diabetes mellitus \\
+Obesity & Osteomyelitis \\
+Otitis media & Peripheral vertigo \\
+Plantar fasciitis & Presbyopia \\
+Prolapse of female genital organs & Psychotic disorder \\
+Seborrheic keratosis & Simple goiter \\
+Sleep apnea & Superficial mycosis \\
+Urge incontinence of urine & Urinary tract infectious disease \\
+Verruca vulgaris & \\
+\hline
+% \end{table}
+\end{tabular}
+\end{table}
+
+% \hypertarget{appendices}{%
+% \subsubsection*{Appendices}\label{appendices}}
+% \addcontentsline{toc}{subsubsection}{Appendices}
+%
+% PNAS prefers that authors submit individual source files to ensure
+% readability. If this is not possible, supply a single PDF file that
+% contains all of the SI associated with the paper. This file type will be
+% published in raw format and will not be edited or composed.
+
+\showmatmethods
+\showacknow
+\pnasbreak
+
+\hypertarget{refs}{}
+\leavevmode\hypertarget{ref-belkin2002using}{}%
+1. Belkin M, Niyogi P (2002) Using manifold stucture for partially
+labeled classification. \emph{Advances in Neural Information Processing
+Systems}, pp 929--936.
+
+\leavevmode\hypertarget{ref-berard1994embedding}{}%
+2. BĂ©rard P, Besson G, Gallot S (1994) Embedding riemannian manifolds by
+their heat kernel. \emph{Geometric \& Functional Analysis GAFA}
+4(4):373--398.
+
+\leavevmode\hypertarget{ref-coifman2005geometric}{}%
+3. Coifman RR, et al. (2005) Geometric diffusions as a tool for harmonic
+analysis and structure definition of data: Diffusion maps.
+\emph{Proceedings of the National Academy of Sciences of the United
+States of America} 102(21):7426--7431.
+
+
+
+% Bibliography
+% \bibliography{pnas-sample}
+
+\end{document}
+
diff --git a/LegendMedCentral/ui.R b/LegendMedCentral/ui.R
new file mode 100644
index 00000000..5e92a4f9
--- /dev/null
+++ b/LegendMedCentral/ui.R
@@ -0,0 +1,19 @@
+library(shiny)
+library(DT)
+source("widgets.R")
+
+shinyUI(fluidPage(style = "width:1000px;",
+ titlePanel(title=div(img(src="logo.png", height = 50, width = 50),
+ "LegendMed Central"),
+ windowTitle = "PubLegend Central"),
+ verticalLayout(div(style = "background-color: #AAAAAA;", tags$table(border = 0, width = "100%", tags$tr(tags$td(HTML(" ")), tags$td(textInput("query", label = "", placeholder = "Enter your search here", width = "100%")), tags$td(HTML(" ")), tags$td(align = "left", searchButton("searchButton", "Search", "query"))))),
+ conditionalPanel("output.isSearchResultPage == true", dataTableOutput("searchResults")),
+ conditionalPanel("output.isAbstractPage == true",
+ uiOutput("abstract"),
+ downloadLink("pdf",
+ label = paste("Generate and download report PDF")
+ )
+ )
+ )
+ )
+ )
diff --git a/LegendMedCentral/widetext.sty b/LegendMedCentral/widetext.sty
new file mode 100644
index 00000000..a8f805e9
--- /dev/null
+++ b/LegendMedCentral/widetext.sty
@@ -0,0 +1,86 @@
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{widetext}
+
+%% Mimics the widetext environment of revtex4 for any other class package
+%% Eg: article.cls
+%%
+%% Compiled by: Anjishnu Sarkar
+%%
+%% Advantages:
+%% *) Supports float (eg: figure) in two column format (Advantage over
+%% multicol package)
+%% *) One and twocolumn exist on the same page
+%% *) Flow of text shown via rule
+%% *) Equal height of text when in two column format
+%%
+%% Acknowledgment(s):
+%% 1. Instead of re-inventing the wheel, two packages (flushend, cuted) of
+%% the sttools bundle are used. The sttools bundle is available from CTAN.
+%% Lisence of these packages rests with their corresponding author.
+%% Any bug/problem with flushend and cuted should be forwarded to their
+%% corresponding package authors.
+%% 2. The idea of the rule came from the following latex community website
+%% http://www.latex-community.org/forum/viewtopic.php?f=5&t=2770
+%%
+%% This package just defines the widetext environment and the rules.
+%%
+%% Usage:
+%% \documentclass[a4paper,12pt,twocolumn]{article}
+%% \usepackage{widetext}
+%%
+%% \begin{document}
+%%
+%% Some text in twocolumn
+%%
+%% \begin{widetext}
+%% Text in onecolumn format.
+%% \end{widetext}
+%%
+%% Some more text in twocolumn
+%%
+%% \end{document}
+%%%%%%%%%%%%%%%%%%%%
+
+%% Package required for equal height while in 2 columns format
+\IfFileExists{flushend.sty}
+ {\RequirePackage{flushend}}
+ {\typeout{}
+ \typeout{Package widetext error: Install the flushend package which is
+ a part of sttools bundle. Available from CTAN.}
+ \typeout{}
+ \stop
+ }
+
+%% Package required for onecolumn and twocolumn to exist on the same page.
+%% and also required for widetext environment.
+\IfFileExists{cuted.sty}
+ {\RequirePackage{cuted}}
+ {\typeout{}
+ \typeout{Package widetext error: Install the cuted package which is
+ a part of sttools bundle. Available from CTAN.}
+ \typeout{}
+ \stop
+ }
+
+
+\newlength\@parindent
+\setlength\@parindent{\parindent}
+
+\if@twocolumn
+ \newenvironment{widetext}
+ {%
+ \begin{strip}
+ \rule{\dimexpr(0.5\textwidth-0.5\columnsep-0.4pt)}{0.4pt}%
+ \rule{0.4pt}{6pt}
+ \par %\vspace{6pt}
+ \parindent \@parindent
+ }%
+ {%
+ \par
+ \hfill\rule[-6pt]{0.4pt}{6.4pt}%
+ \rule{\dimexpr(0.5\textwidth-0.5\columnsep-1pt)}{0.4pt}
+ \end{strip}
+ }
+\else
+ \newenvironment{widetext}{}{}
+\fi
\ No newline at end of file
diff --git a/LegendMedCentral/widgets.R b/LegendMedCentral/widgets.R
new file mode 100644
index 00000000..24ad53df
--- /dev/null
+++ b/LegendMedCentral/widgets.R
@@ -0,0 +1,12 @@
+searchButton <- function(inputId, label, queryInput, ...) {
+ script <- "
+ var link=document.createElement('a');
+ link.id = 'searchLink';
+ link.href='?term='+encodeURI(document.getElementById('%id%').value);
+ document.body.appendChild(link);
+ document.getElementById('searchLink').click();
+ return false;
+ "
+ script <- gsub("%id%", queryInput, script)
+ tags$button(type = "button", onclick = script, label, ...)
+}
diff --git a/LegendMedCentral/www/favicon.ico b/LegendMedCentral/www/favicon.ico
new file mode 100644
index 00000000..849a1fa4
Binary files /dev/null and b/LegendMedCentral/www/favicon.ico differ
diff --git a/LegendMedCentral/www/logo.png b/LegendMedCentral/www/logo.png
new file mode 100644
index 00000000..c6307af6
Binary files /dev/null and b/LegendMedCentral/www/logo.png differ