Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dev/cohort assess #248

Open
wants to merge 58 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
58 commits
Select commit Hold shift + click to select a range
08376ba
Merge branch 'dev/dependencies_metric' into dev_ejm
May 25, 2021
c9cf0d9
Merge branch 'dev/namespace_metrics' into dev_ejm
May 25, 2021
c47d226
merge reverse dependency assessment into personal dev branch
May 25, 2021
399ec3a
fixed typo
Jul 15, 2021
c63a551
switched to lapply in place of sapply
Jul 15, 2021
e9dd378
initial cohort_ref class prototype
Jul 15, 2021
d841b3a
Merge branch 'pharmaR:master' into dev/cohort
emilliman5 Jul 19, 2021
14b9545
fixed typos in documentation
Jul 19, 2021
5043048
Merge branch 'dev/cohort' of github.com:emilliman5/riskmetric into de…
Jul 19, 2021
dbc5ae5
created shell for a cohort ref class, updated exported namespace asse…
Aug 12, 2021
7421b16
Merge branch 'master' of github.com:emilliman5/riskmetric into dev/co…
Aug 12, 2021
d3f8bb9
fixed some iteration errors in assess_reverse_dependencies for cohorts
Sep 1, 2021
31a7751
fixed documentation title
Sep 1, 2021
3afc305
update with with master
emilliman5 Mar 7, 2022
ae3f132
added cohort assessment of dependencies
emilliman5 Mar 8, 2022
18c2f6b
beefing up cohort_ref class
emilliman5 Mar 8, 2022
77d1a43
skeletons for two cohort metrics
emilliman5 Mar 8, 2022
a063a2d
create explicit list_of_package_ref constructors. renamed pkg_library…
emilliman5 Mar 23, 2022
7da875a
fixed missing parantheses
emilliman5 Mar 23, 2022
e27ede8
rewrote cohort_ref constructor. added print and as_tibble functions f…
emilliman5 Mar 23, 2022
a1550b0
remove pkg_cohort function, and replace with cohort_ref (to be consis…
emilliman5 Mar 24, 2022
93ff994
updated doc and ns
emilliman5 Mar 30, 2022
3d85369
copy pasta of pkg_metric for to cohort metric
emilliman5 Apr 6, 2022
1790e19
reformulation of dependency assess* and refs. In preperation for asse…
emilliman5 Apr 6, 2022
aaa40c6
new cohort assessment for dependency conflicts
emilliman5 Apr 6, 2022
2d912bf
renamed "pkg" from copy pasta to "cohort"
emilliman5 Apr 11, 2022
7aec287
add cohort metric method.
emilliman5 Apr 12, 2022
9d7d225
create aohort assessment dispatch function similar to pkg_assess
emilliman5 Apr 12, 2022
732ce8f
fixed return value of assess_namespace_export for cohort_ref
emilliman5 Apr 12, 2022
bd32eb4
fixed return value of assess_reverse_dependencies for cohort_ref. add…
emilliman5 Apr 12, 2022
fddcf76
namesspace and documentation update
emilliman5 Apr 12, 2022
1bf7bea
documentation update
emilliman5 Apr 12, 2022
7ca6815
cohort_score function, akin to pkg_score
emilliman5 Apr 12, 2022
9fb36c7
fixed some copy pasta errors
emilliman5 Apr 12, 2022
9760f62
renamed cohort_metric to metric_score
emilliman5 Apr 12, 2022
f327189
changed return object type
emilliman5 Apr 12, 2022
0656aa5
added metric_score for cohort_ref assessment. fixed class typo in ass…
emilliman5 Apr 13, 2022
aa13d58
fixed attribute typos
emilliman5 Apr 13, 2022
8b4c500
added summarized cohort score
emilliman5 Apr 13, 2022
460feca
namespace and description updates
emilliman5 Apr 15, 2022
87d14b3
removed unnessary assessment checks due to rework of where dependecy …
emilliman5 Apr 15, 2022
1291b21
tried to added an assessment for a pkg_ref to satisfy metric_label un…
emilliman5 Apr 15, 2022
b212f4a
fixed test now that table of dependencies is cached instead of comput…
emilliman5 Apr 15, 2022
c4aa559
documentation updated
emilliman5 Apr 15, 2022
ab9fc81
added a conditional. If no S3 methods exist for the classess provided…
emilliman5 Apr 15, 2022
12dfe71
added labels to all metric_score_* functions. this is to help ensure …
emilliman5 Apr 15, 2022
55d28c8
Merge branch 'metrics_score' into dev/cohort_assess
emilliman5 Apr 15, 2022
c63452f
moved dplyr to imports...for now. ulitmately want to remove it as a d…
emilliman5 Apr 15, 2022
08df7d3
fix argument consistentcy with print generic
emilliman5 Apr 15, 2022
1bfadd0
removed duplicate functions definitions
emilliman5 Apr 15, 2022
56f3031
added importFrom to assessment roxygen header
emilliman5 Apr 15, 2022
df7d71a
fixed function call from cohort_assessment to ass_cohort_assessment
emilliman5 Apr 15, 2022
5ed510e
added import directive for installed.packages from utils
emilliman5 Apr 15, 2022
5edc08e
documentation update
emilliman5 Apr 15, 2022
ee35d80
added stringr to imports. will investigate possibilibity of removing …
emilliman5 Apr 15, 2022
36fe2ba
documentation updates
emilliman5 Apr 19, 2022
e40a7bf
made s3 dispatch consistent
emilliman5 Apr 19, 2022
b45ba67
updated test expectations
emilliman5 Apr 19, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions DESCRIPTION
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,15 @@ Imports:
pillar,
tibble,
pkgload,
devtools
devtools,
igraph,
dplyr,
stringr
Suggests:
knitr,
rmarkdown,
withr,
magrittr,
dplyr,
testthat,
webmockr,
jsonlite
Expand Down
29 changes: 29 additions & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,14 @@ S3method("[<-",pkg_ref)
S3method("[[",pkg_ref)
S3method("[[<-",pkg_ref)
S3method(.DollarNames,pkg_ref)
S3method(as_cohort_metric,default)
S3method(as_cohort_metric,expr_output)
S3method(as_pkg_metric,default)
S3method(as_pkg_metric,expr_output)
S3method(as_pkg_ref,character)
S3method(as_pkg_ref,default)
S3method(as_pkg_ref,pkg_ref)
S3method(as_tibble,cohort_ref)
S3method(as_tibble,list_of_pkg_ref)
S3method(as_tibble,pkg_ref)
S3method(assess_covr_coverage,default)
Expand All @@ -25,9 +28,12 @@ S3method(assess_downloads_1yr,pkg_ref)
S3method(assess_export_help,pkg_install)
S3method(assess_export_help,pkg_remote)
S3method(assess_export_help,pkg_source)
S3method(assess_exported_namespace,cohort_ref)
S3method(assess_exported_namespace,default)
S3method(assess_exported_namespace,pkg_install)
S3method(assess_exported_namespace,pkg_source)
S3method(assess_has_bug_reports_url,pkg_ref)
S3method(assess_has_dependency_conflict,cohort_ref)
S3method(assess_has_news,pkg_ref)
S3method(assess_has_vignettes,pkg_ref)
S3method(assess_news_current,pkg_ref)
Expand All @@ -39,11 +45,19 @@ S3method(assess_r_cmd_check,pkg_source)
S3method(assess_remote_checks,default)
S3method(assess_remote_checks,pkg_bioc_remote)
S3method(assess_remote_checks,pkg_cran_remote)
S3method(assess_reverse_dependencies,cohort_ref)
S3method(assess_reverse_dependencies,default)
S3method(cohort_assess,cohort_ref)
S3method(cohort_score,list_of_cohort_metric)
S3method(format,cohort_metric)
S3method(format,cohort_metric_error)
S3method(format,pkg_metric)
S3method(format,pkg_metric_error)
S3method(format,pkg_missing)
S3method(format,pkg_ref)
S3method(metric_score,cohort_metric_dependency_conflict)
S3method(metric_score,cohort_metric_exported_namespace)
S3method(metric_score,cohort_metric_reverse_dependencies)
S3method(metric_score,default)
S3method(metric_score,pkg_metric_covr_coverage)
S3method(metric_score,pkg_metric_dependencies)
Expand Down Expand Up @@ -71,6 +85,7 @@ S3method(pkg_assess,pkg_ref)
S3method(pkg_assess,tbl_df)
S3method(pkg_score,list_of_pkg_metric)
S3method(pkg_score,tbl_df)
S3method(print,cohort_ref)
S3method(print,pkg_ref)
S3method(print,with_eval_recording)
S3method(summarize_scores,data.frame)
Expand All @@ -81,6 +96,9 @@ S3method(vec_ptype_abbr,pkg_metric)
S3method(vec_ptype_abbr,pkg_ref)
S3method(with,pkg_ref)
export(all_assessments)
export(all_cohort_assessments)
export(as_cohort_metric)
export(as_list_of_pkg_ref)
export(as_pkg_metric)
export(as_pkg_ref)
export(assess_covr_coverage)
Expand All @@ -89,6 +107,7 @@ export(assess_downloads_1yr)
export(assess_export_help)
export(assess_exported_namespace)
export(assess_has_bug_reports_url)
export(assess_has_dependency_conflict)
export(assess_has_maintainer)
export(assess_has_news)
export(assess_has_source_control)
Expand All @@ -103,8 +122,13 @@ export(assess_reverse_dependencies)
export(assessment_error_as_warning)
export(assessment_error_empty)
export(assessment_error_throw)
export(cohort_assess)
export(cohort_metric)
export(cohort_ref)
export(cohort_score)
export(get_assessments)
export(metric_score)
export(new_list_of_pkg_ref)
export(pkg_assess)
export(pkg_metric)
export(pkg_ref)
Expand All @@ -124,13 +148,16 @@ importFrom(cranlogs,cran_downloads)
importFrom(curl,nslookup)
importFrom(devtools,check)
importFrom(devtools,revdep)
importFrom(dplyr,bind_rows)
importFrom(httr,GET)
importFrom(httr,content)
importFrom(igraph,fit_power_law)
importFrom(memoise,memoise)
importFrom(pillar,new_pillar_shaft_simple)
importFrom(pillar,pillar_shaft)
importFrom(pillar,style_na)
importFrom(pkgload,parse_ns_file)
importFrom(stringr,str_extract)
importFrom(tibble,as_tibble)
importFrom(tibble,tibble)
importFrom(tools,Rd_db)
Expand All @@ -143,8 +170,10 @@ importFrom(utils,.DollarNames)
importFrom(utils,.S3methods)
importFrom(utils,available.packages)
importFrom(utils,capture.output)
importFrom(utils,compareVersion)
importFrom(utils,getS3method)
importFrom(utils,head)
importFrom(utils,installed.packages)
importFrom(utils,packageDescription)
importFrom(utils,packageName)
importFrom(utils,packageVersion)
Expand Down
31 changes: 8 additions & 23 deletions R/assess_dependencies.R
Original file line number Diff line number Diff line change
Expand Up @@ -26,45 +26,31 @@ assess_dependencies.default <- function(x, ...){
#' @export
assess_dependencies.pkg_source <- function(x, ...){
pkg_metric_eval(class = "pkg_metric_dependencies", {
parse_dcf_dependencies(x$path)
NROW(x$dependencies)
})
}

#' @export
assess_dependencies.pkg_install <- function(x, ...){
pkg_metric_eval(class = "pkg_metric_dependencies", {
parse_dcf_dependencies(x$path)
NROW(x$dependencies)
})
}

#' @export
assess_dependencies.pkg_cran_remote <- function(x, ...){
#Attempt to find CRAN URL by matching all urls returned by getOptions("repos") to memoise_cran_mirrors table
repos <- getOption("repos")[which(getOption("repos") %in% memoise_cran_mirrors()$URL)]

if(length(repos)==0){
repos <- grep("[\\.|//]cran\\.", getOption("repos"), ignore.case = T, value = T)
}
if(length(repos)==0){
repos <- getOption("repos")[["CRAN"]]
}

if(length(repos)==0){
as_pkg_metric_error(error = 'Could not determine which CRAN mirror you are using.')
} else{
pkg_metric_eval(class = "pkg_metric_dependencies", {
get_package_dependencies(x$name, repo = repos[1]) ##Will use the first CRAN mirror found in the users environment
NROW(x$dependencies)
})
}
}

#' @importFrom BiocManager repositories
#' @export
assess_dependencies.pkg_bioc_remote <- function(x, ...){
pkg_metric_eval(class = "pkg_metric_dependencies", {
get_package_dependencies(x$name, BiocManager::repositories()[1])
})
}
pkg_metric_eval(class = "pkg_metric_dependencies", {
NROW(x$dependencies)
})
}

#' Score a package for dependencies
#'
Expand All @@ -84,7 +70,7 @@ assess_dependencies.pkg_bioc_remote <- function(x, ...){
#'
#' @export
metric_score.pkg_metric_dependencies <- function(x, ...) {
1 - 1/(1 + exp(-0.5 * (NROW(x) - 4)))
1 - 1/(1 + exp(-0.5 * (x - 4)))
}
attributes(metric_score.pkg_metric_dependencies)$label <-
"The number of package dependencies"
Expand Down Expand Up @@ -138,7 +124,6 @@ remove_base_packages <- function(df){
inst_priority <- inst[,"Priority"]
inst_is_base_rec <- !is.na(inst_priority) & inst_priority %in% c("base", "recommended")
base_rec_pkgs <- inst[inst_is_base_rec, "Package"]

deps <- df[!grepl("^R\\s\\(.+\\)", df$package) | df$package %in% base_rec_pkgs, ] ##Remove "R" dependencies as well as base and recomended
return(deps)
}
39 changes: 37 additions & 2 deletions R/assess_exported_namespace.R
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#' Assess a package's results from running R CMD check
#' Assess a package's exported namespace
#'
#' @eval roxygen_assess_family(
#' "exported_namespace",
Expand All @@ -17,7 +17,7 @@ attributes(assess_exported_namespace)$label <- "Objects exported by package"
#' @export
assess_exported_namespace.default <- function(x, ...) {
as_pkg_metric_na(
pkg_metric(class = "pkg_metric_export_help"),
pkg_metric(class = "pkg_metric_exported_namespace"),
message = sprintf("Cannot export namespace from a %s", x$source))
}

Expand All @@ -37,6 +37,15 @@ assess_exported_namespace.pkg_source <- function(x, ...) {
})
}

#' @export
assess_exported_namespace.cohort_ref <- function(x, ...) {
ns <- unlist(lapply(x$cohort, assess_exported_namespace))
return(cohort_metric_eval(class = "cohort_metric_exported_namespace",
ns
))
}


#' Score a package for the number of exported objects
#'
#' Score a package for the number of exported objects it has; regularized
Expand All @@ -61,3 +70,29 @@ metric_score.pkg_metric_exported_namespace <- function(x, ...) {

attributes(metric_score.pkg_metric_exported_namespace)$label <-
"The number of exported objects in a package"


#' Score a cohort for the number of exported objects
#'
#' Score a cohort for the number of exported objects it has; regularized
#' Convert the number of exported objects \code{length(x)} into a validation
#' score [0,1] \deqn{ 1 / (1 + exp(-0.5 * (sqrt(length(x)) + sqrt(5)))) }
#'
#' The scoring function is the classic logistic curve \deqn{
#' 1 / (1 + exp(-k(x-x[0])) } with a square root scale for the number of exported objects
#' \eqn{x = sqrt(length(x))}, sigmoid midpoint is 25 exported objects, ie. \eqn{x[0] =
#' sqrt(5)}, and logistic growth rate of \eqn{k = 0.25}.
#'
#' \deqn{ 1 / (1 + exp(-0.25 * sqrt(length(x))-sqrt(25))) }
#'
#' @eval roxygen_score_family("exported_namespace")
#' @return numeric value between \code{0} (high number of exported objects) and
#' \code{1} (low number of exported objects)
#'
#' @export
metric_score.cohort_metric_exported_namespace <- function(x, ...) {
1 - 1 / (1 + exp(-0.25 * (sqrt(length(x)) - sqrt(25))))
}

attributes(metric_score.cohort_metric_exported_namespace)$label <-
"The number of exported objects in a cohort"
6 changes: 2 additions & 4 deletions R/assess_has_bug_reports_url.R
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,7 @@
#'
#' @export
assess_has_bug_reports_url <- function(x, ...) {
pkg_metric_eval(class = "pkg_metric_has_bug_reports_url", {
as.character(x$bug_reports_url)
})
UseMethod("assess_has_bug_reports_url")
}

# assign a friendly name for assess column
Expand All @@ -20,7 +18,7 @@ attr(assess_has_bug_reports_url,"label") <- "presence of a bug reports url in re
#' @export
assess_has_bug_reports_url.pkg_ref <- function(x, ...) {
pkg_metric(class = "pkg_metric_has_bug_reports_url", {
length(x$bug_reports_url)
as.character(x$bug_reports_url)
})
}

Expand Down
67 changes: 67 additions & 0 deletions R/assess_has_dependency_conflict.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
#' Assess a cohort for the presence of dependency conflicts
#'
#' @param x cohort_ref
#' @param ... currently ignored
#' @export
#'
assess_has_dependency_conflict <- function(x, ...){
UseMethod("assess_has_dependency_conflict")
}
attributes(assess_has_dependency_conflict)$column_name <- "dependency_conflict"
attributes(assess_has_dependency_conflict)$label <- "Cohort dependency conflicts"

assess_has_dependency_conflict.pkg_ref <- function(x, ...){
as_pkg_metric_na(
pkg_metric(class = "pkg_metric_dependency_conflict"),
message = "Dependency conflicts not relevant for an individual package.")
}
attributes(assess_has_dependency_conflict)$column_name <- "dependency_conflict"
attributes(assess_has_dependency_conflict)$label <- "Cohort dependency conflicts"

#' @importFrom stringr str_extract
#' @importFrom utils compareVersion
#' @export
assess_has_dependency_conflict.cohort_ref <- function(x, ...){
dep <- lapply(x$cohort, "[[", "dependencies")
nm <- unlist(lapply(x$cohort, "[", "name"))

nm_lib <- as_tibble(x$library)[, c(1:2)]

dep <- data.frame(ref=rep(nm, sapply(dep, nrow)), bind_rows(dep))
dep$version <- str_extract(dep$package, "(?<=\\().+(?=\\))")
dep$version<- str_extract(dep$version, "\\d+\\.\\d+(\\.\\d+)*")
dep$package <- trimws(gsub("\\(.+\\)", "", dep$package))
dep2 <- list(minVer = tapply(dep$version, dep$package, function(x) sort(x, decreasing = T)[1]),
minDep = tapply(dep$type, dep$package, function(x) sort(x)[1]))
dep2 <- merge(as.data.frame(dep2$minVer), as.data.frame(dep2$minDep), by="row.names")

lib <- rbind(nm_lib, data.frame(package=nm, version=unlist(lapply(x$cohort, "[", "version"))))
dep3 <- merge(dep2, lib, by.x="Row.names", by.y="package", all.x = TRUE)
dep3$conflict <- apply(dep3, 1, function(x) {
if(is.na(x[4])){
return(TRUE)
} else if(is.na(x[2]) & !is.na(x[4])){
return(FALSE)
} else if (compareVersion(x[2],x[4])>0){
return(TRUE)
} else {
return(FALSE)
}
})
colnames(dep3) <- c("Pkg_dependency", "MinimumVersion","Type", "CurrentVersion", "IsConflict")
cohort_metric_eval(class= "cohort_metric_dependency_conflict",
dep3[dep3$IsConflict, ])
}

#' Score a package for presence of dependency conflicts
#'
#' @param x cohort assessment
#' @param ... named list of arguments to adjust metric scoring. currently ignored.
#' @return \code{1} if any dependencies are missing or conflicting, otherwise \code{0}
#'
#' @export
metric_score.cohort_metric_dependency_conflict <- function(x, ...) {
as.numeric(NROW(x) > 0)
}

attributes(metric_score.cohort_metric_dependency_conflict)$label <- "Binary indicator of the presence of a dependency conflict"
35 changes: 34 additions & 1 deletion R/assess_reverse_dependencies.R
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,28 @@ assess_reverse_dependencies.default <- function(x, ...){
)
}

#' @importFrom devtools revdep
#' @export
assess_reverse_dependencies.cohort_ref <- function(x, ...){
cohort_rev_deps <- lapply(x$cohort, assess_reverse_dependencies)
cohort_nm <- sapply(x$cohort, "[[", "name")

cohort_rev_deps <- data.frame(pkg=rep(cohort_nm, sapply(cohort_rev_deps, length)),
revdep=unlist(cohort_rev_deps))

if(length(x$library)){
lib_pkgs <- sapply(x$library, function(x) x$name)
}

return(cohort_metric_eval(class = "cohort_metric_reverse_dependencies",
cohort_rev_deps[cohort_rev_deps$revdep %in% c(lib_pkgs, cohort_nm), ]
)
)
}

attr(assess_reverse_dependencies, "column_name") <- "reverse_dependencies"
attr(assess_reverse_dependencies, "label") <- "List of reverse dependencies a package has"
attr(assess_reverse_dependencies, "label") <- "Table of reverse dependencies for each package."


#' Scoring method for number of reverse dependencies a package has
#'
Expand All @@ -48,3 +68,16 @@ metric_score.pkg_metric_reverse_dependencies <- function(x,...){
attributes(metric_score.pkg_metric_reverse_dependencies)$label <-
"The (log10) number of packages that depend on this package."


#' Metric for the assessment of reverse dependencies of a cohort.
#'
#' @param x cohort assessment
#' @param ... named list of arguments that are currently ignored
#' @importFrom igraph fit_power_law
#' @export
metric_score.cohort_metric_reverse_dependencies <- function(x, ...){
igraph::fit_power_law(tapply(x$revdep, x$pkg, length))$KS.p
}
attributes(metric_score.cohort_metric_reverse_dependencies)$label <-
"p-value of power law distribution fit"

Loading