This Narrated Illustration of a Transparent Review Outline (NITRO)
accompanies the SysRevving book and
the metabefor
package. Throughout this file, links to the corresponding SysRevving
chapters will be provided. For general reference, you may want to keep
the SysRevving glossary
ready. For convenience, here
is the GitLab repo for this project, and here
is the URL to the rendered version of this R Markdown file.
In this fictional example, we want to conduct a systematic review about the determinants of substance use, specifically a scoping review. Note that this review is deliberately very rudimentary, to try to avoid the complexity of the review itself from interfering with understanding the structure.
Here we check for the required packages (without loading them into
R’s search path with library()
or require()
,
to safeguard against accidently forgetting to use the
package::function()
syntax), specify the paths, and set
script-wide settings.
###-----------------------------------------------------------------------------
### Some booleans (logical values, set to TRUE or FALSE) to control which
### actions are executed when the script runs
###-----------------------------------------------------------------------------
runScreeningChunks <- FALSE;
###-----------------------------------------------------------------------------
### Packages
###-----------------------------------------------------------------------------
if ((!(requireNamespace("metabefor", quietly = TRUE))) ||
(packageVersion("metabefor") < "0.3")) {
stop("You need to have at least version 0.3 of the `metabefor` package installed; ",
"install it with:\n\ninstall.packages('metabefor');");
}
metabefor::checkPkgs(
"here", ### For easily access to files using 'relative paths'
"preregr", ### For specifying (pre)registrations
"synthesisr", ### For plotting
"ggplot2" ### For plotting
);
### Potentially update to the development version of some packages
# ufs::quietGitLabUpdate("r-packages/preregr@dev", quiet = FALSE);
# ufs::quietGitLabUpdate("r-packages/rock@dev", quiet = FALSE);
# ufs::quietGitLabUpdate("r-packages/metabefor", quiet = FALSE);
# ufs::quietRemotesInstall("rmetaverse/synthesisr",
# func = "install_github", quiet = FALSE);
###-----------------------------------------------------------------------------
### Paths
###-----------------------------------------------------------------------------
basePath <- here::here();
preregPath <- file.path(basePath, "prereg");
scriptPath <- file.path(basePath, "scripts");
searchPath <- file.path(basePath, "search");
screeningPath <- file.path(basePath, "screening");
extractionPath <- file.path(basePath, "extraction");
rxsSpecPath <- file.path(basePath, "extraction-Rxs-spec");
outputPath <- file.path(basePath, "output");
###-----------------------------------------------------------------------------
### Settings
###-----------------------------------------------------------------------------
knitr::opts_chunk$set(
echo = TRUE,
comment = ""
);
###-----------------------------------------------------------------------------
### Extraction script Google sheets URL
###-----------------------------------------------------------------------------
rxsSpec_googleSheetsURL <-
paste0("https://docs.google.com/spreadsheets/d/",
"1Ty38BS7MVXOgC-GJ6zzr7E3rC_vQNOMKe-uCvIuHs3c");
(link to corresponding SysRevving chapter)
Example: The research question is whether the exponential explosion of the scientific literature is also reflected in a growing evidence base for health promotion interventions targeting recreational substance use.
(link to corresponding SysRevving chapter)
Example: To answer the research question, our synthesis will consist of a plot with years on the X axis, cumulative number of publications on the Y axis, and with spearately, differently colored lines for each substance.
(link to corresponding SysRevving chapter)
Example: The R extraction script specification (Rxs spec) is stored in this Rxs spec google sheet. The below chunks load it, convert it into the Rxs template (that will then be copied and completed for each source from which data are extracted), and show these specifications.
metabefor::show_rxsTree_in_rxsStructure(
rxsSpecObject,
output = outputPath
);
levelName 1 source 2 °--general 3 ¦--publicationYear 4 ¦--sourceAuthors 5 °--sourceTitle
levelName 1 source 2 °--methods 3 ¦--sample 4 ¦ ¦--sampleSize 5 ¦ °--samplingStrategy 6 ¦--method 7 °--variables 8 °--variable 9 ¦--variableIdentifier 10 °--measurementLevel
levelName 1 source 2 °--results 3 °--associations 4 °--association 5 ¦--associationIdentifier 6 ¦--varId1 7 ¦--varId2 8 ¦--r 9 °--t
cat(rxsSpecObject$rxsInstructions);
These instructions are for extractors using the minimal rxs example.
Normally, these instructions should be comprehensive enough to allow people to extract data reasonably accurately. The instructions with the heading “Opening Remarks” and “Closing Remarks” are added in every rxs file.
Welcome to the R Extraction Script (.rxs.Rmd file) for this source!
You can now start extracting. If you haven’t yet studied the extractor instructions, please do so first. If you’re all set, good luck!
Well done! You are now done extracting this source. Great job!!!
Now, please knit the R Extraction Script into an HTML file and carefully check whether you entered everything correctly, since it will cost much less time to correct any errors, now that you still have this source in your mind, than later on when you’ll have to dive into it all over.
cat(rxsSpecObject$entityOverview_list);
This is the extraction script generated based on the extraction script specification.
cat("\n\n<pre><textarea rows='40' cols='124' style='font-family:monospace;font-size:11px;white-space:pre;'>",
unlist(rxsSpecObject$rxsTemplate),
"</textarea></pre>\n\n",
sep="\n");
(link to corresponding SysRevving chapter)
Example: We will search using the Ebsco interface in the PsycINFO and Ebsco E-journals databases, and we will use PubMed (using its own interface).
We will only search in titles, and our conceptual query consists of two main terms (substance synonyms and determinant synonyms), where the first main term is split per set of synonyms for each substance.
In the Ebsco query syntax, the query is:
(TI (((ecstasy OR mdma) OR (coke OR cocaine) OR (GHB) OR (LSD) OR (ketamine OR "special K")) AND (determinants OR factors OR reasons)))
That will be used for the PsycINFO and Ebsco E-Journals databases.
In the PubMed query synax, the query is:
(((ecstasy[Title] OR mdma[Title]) OR (coke[Title] OR cocaine[Title]) OR (GHB[Title]) OR (LSD[Title]) OR (ketamine[Title] OR "special K"[Title])) AND (determinants[Title] OR factors[Title] OR reasons[Title]))
(link to corresponding SysRevving chapter)
### Note: this chunk doesn't need to be evaluated (i.e. chunk option "eval" is
### set to FALSE), but in case it is, it writes the template to a different
### file than the version with content added and included in the next chunk.
### (For a list of included packages, see data(package='preregr'))
preregr::form_to_rmd_template(
"genSysRev_v1",
file = file.path(scriptPath, "preregistration-autogenerated.Rmd"),
includeYAML = FALSE
);
### Note also that the preregistration form contains a level 2 heading
preregr::prereg_spec_to_pdf(
preregrObject,
file = file.path(preregPath, "registration-1---preregistration.pdf"),
author = rmarkdown::metadata$author
);
Example: …
(link to corresponding SysRevving chapter)
Example: The queries are entered into the specified
interfaces to search the specified databases, separately for each
database. The three RIS-files are stored using the following filename
convention:
YYYY-MM-DD_interface_database_originalFileName.ris
.
The hits in PubMed are saved in the PubMed format, which is basically
RIS. Both can be imported by the synthesisr
package, which
we will call from metabefor
:
searchResults <-
metabefor::import_search_results(
searchPath
);
This is the number of hits we have for each database:
knitr::kable(
table(searchResults$bibHitDf$originDatabase),
col.names = c("Database", "Number of records")
);
Database | Number of records |
---|---|
ejournals | 483 |
psychinfo | 336 |
pubmed | 235 |
We also see that only a minority of the records has a DOI - at least
one that was correctly recognized by synthesisr
:
knitr::kable(
table(!is.na(searchResults$bibHitDf$doi)),
col.names = c("DOI present?", "Number of records")
);
DOI present? | Number of records |
---|---|
FALSE | 773 |
TRUE | 281 |
We can make a crosstable with database to see whether maybe the
export from one or two databases doesn’t include DOIs — or maybe
includes them in a format not yet recognized by
synthesisr
:
knitr::kable(
table(!is.na(searchResults$bibHitDf$doi), searchResults$bibHitDf$originDatabase)
);
ejournals | psychinfo | pubmed | |
---|---|---|---|
FALSE | 483 | 55 | 235 |
TRUE | 0 | 281 | 0 |
It seems that results from the E-Journals database and from PubMed don’t include DOIs. Manual inspection of the RIS files reveals that …
(link to corresponding SysRevving chapter)
Example: …
###-----------------------------------------------------------------------------
### Process first search batch
### Note that these are sorted by batch
###-----------------------------------------------------------------------------
screenerPackages <-
metabefor::write_screenerPackage(
bibliographyDf = searchResults,
outputPath = screeningPath,
basename = "stage1_",
duplicateField = "duplicate"
);
### Potentially, to screen with revtools:
# revtools::screen_titles(bibHitDf[[1]]);