| June 9, 2020
Many contributed R packages lack documentation expected in software qualification, which is required within pharma and other regulated industries. For pharma, there are various regulations, which require documentation that demonstrates software is used appropriately and works as expected. Thus, industry needs to establish appropriate requirements for R packages using selected metadata and useful risk metrics.
In context of the R Validation Hub, the R package riskmetric
has been developed, which seeks to take the first steps in identifying metrics and best practices to quantify the quality of R packages. It provides a framework for retrieving package metadata, assessing package metrics, and summarizing the risk that the package might not provide accurate results. A corresponding Shiny app, that can be used to generate package reports using riskmetric, is under development.
In this blog post, we want to illustrate the capabilities and usage of riskmetric
and demonstrate how it could fit into an organizations validation process or its qualified environments.
The riskmetric
package is not yet on CRAN. Until it is, it can be installed using devtools
directly from GitHub:
devtools::install_github("pharmaR/riskmetric", force = TRUE)
Then, the package can be loaded:
library(riskmetric)
To illustrate how riskmetric
works, a few packages with a wide range of popularity have been selected.
riskmetric
(Metrics to evaluate the risk of R packages): Not on CRAN yetutils
(R utility functions): R core packageggplot2
(Create Elegant Data Visualisations Using the Grammar of Graphics): very popular packageHmisc
(Harrell Miscellaneous functions): something more old schoolsurvminer
(Drawing Survival Curves usingggplot2
): less popular, but established packagecoxrobust
(Robust Estimation in Cox Model): oldest R package on CRAN
When referencing a package, riskmetric first looks for installed packages but can also assess packages that have not been installed:
package_tbl <- pkg_ref(c("riskmetric", "utils", "ggplot2", "Hmisc", "survminer", "coxrobust"))
package_tbl$survminer
## <pkg_install, pkg_ref> survminer v0.4.7
## $path
## [1] "C:/Users/Andy/Documents/R/win-library/4.0/survminer"
## $source
## [1] "pkg_install"
## $version
## [1] '0.4.7'
## $name
## [1] "survminer"
## $bug_reports...
## $bug_reports_host...
## $bug_reports_url...
## $description...
## $downloads...
## $help...
## $help_aliases...
## $maintainer...
## $news...
## $release_date...
## $source_control_url...
## $vignettes...
## $website_urls...
Note that many fields have a trailing ...
; riskmetric will evaluate and cache the results of the queries later on. When we call the pkg_assess()
function on each reference, the metrics will be stored and become available. In other words, the necessary package metadata is assessed and an atomic value is added for each assessment and package.
Then, the information is scored in order to estimate associated risk. This final score converts the assessment value into a single numeric score between 0 (poor) and 1 (great). Finally each package’s risk is summarized as a weigthed sum of assessment scores.
For more information, check out the riskmetric
vignette.
res <- package_tbl %>%
pkg_assess() %>%
pkg_score() %>%
mutate(risk = summarize_scores(.))
The function summarize_scores()
serves as an example for how a risk score might be derived. Each organization should decide independently how to weight different assessments.
package | version | license | export_help | has_vignettes | has_bug_reports_url | bugs_status | has_news | |
---|---|---|---|---|---|---|---|---|
riskmetric | 0.1.0.9001 | NA | 1 | 0 | 1 | 0.5667 | 0 | |
utils | 3.6.2 | NA | 0.996 | 1 | 0 | 0 | 0 | |
ggplot2 | 3.2.1 | NA | 1 | 1 | 1 | 0.6333 | 1 | |
Hmisc | 4.3.1 | NA | 1 | 0 | 0 | 0 | 0 | |
survminer | 0.4.6 | NA | 1 | 1 | 1 | 0.2333 | 1 | |
coxrobust | 1.0 | NA | 1 | 0 | 0 | 0 | 0 | 0 |
There are many good programming and package development practices that establish a package is well made and maintained:
has_vignettes
- Number of published vignetteshas_news
- Number of releases with a NEWS updatehas_bug_reports_url
- Presence of a URL for users to report issues and bugs found in the package.
Community usage is determined based on the number of downloads. This is a useful proxy for community support and adhoc testing done by other developers.
downloads_1yr
– Number of downloads from CRAN, Bioconductor, and GitHub in the past year.
Furthermore, the test coverage of a package can provide well established insights on the package accuracy
covr_coverage
– Package unit test coverage percentage
Several other metrics are under active development that can interrogate package stability and complexity, e.g.
- Maturity – Package version and overall maturity
- Cyclomatic Complexity – Complexity of the code base itself
In addition to assessing the set of packages used to develop a project, riskmetric
can also be used to assess a package before you introduce it into your development environment. Here is an example reviewing the number of downloads for the survminer
package:
pkg_ref("survminer") %>%
assess_downloads_1yr() %>%
metric_score()
## [1] 0.6030633
## attr(,"class")
## [1] "pkg_metric_downloads_1yr" "pkg_metric"
## [3] "numeric"
Finally, this information can be used by a system administrator when evaluating the suitability of a package, or when writing a validation report:
survminer (v0.4.7)
Package survminer (v0.4.7) has 227894 downloads in the past year, which converts to a
riskmetric
score of 60.31%.
If you are interested in helping with development or the direction of the package, we are active on GitHub and welcome any contributions. More details can be found in the “Get Involved” section of the readme file for riskmetric
GitHub page.