dark-peak-analytics / assertHE

R package to assist in the verification of health economic decision models.
https://dark-peak-analytics.github.io/assertHE/
Other
4 stars 10 forks source link

Add external dependencies #59

Open RobertASmith opened 4 months ago

RobertASmith commented 4 months ago

This is important because, as in the model and package developed for GSK, a package may be used to run lots of the generic code (which can make up a high proportion of the model) and then what is left for the model visualisation is actually a smaller subset of model code.

Potential fix:

renv::dependencies() provides a table of dependencies by file path.

We can adapt and run by function! This will give external dependency list for each function. Then, for set functions we could load the arguments and body. It won't be possible to load the full code with Roxygen because this may be stored somewhere else.

Note: we won't always want full function by function dependencies as this will be massive, in most cases we will just want a list of packages used.

RobertASmith commented 2 months ago
rm(list = ls())

filename <- "tests/testthat/example_external_function/R/external_dependency.R"

df <- utils::getParseData(parse(filename, keep.source = TRUE),includeText = TRUE)

function_name <- assertHE::find_function_definitions(filename = filename)$text
source("tests/testthat/example_external_function/R/external_dependency.R")
df2 <- utils::getParseData(x = body(get(function_name)))

df2[df2$token == "SYMBOL_FUNCTION_CALL", ]

find("colMins")

assertHE::.called_by("external_dependency_NON_explicit")
parsed_output <- parse(filename, keep.source = TRUE)

  find("colMins")
RobertASmith commented 1 month ago
#' @title Identify the package of a function call
#'
#' @param id the id of the function call in the parsed code
#' @param df_ParsedData a dataframe of the parsed code
#'
#' @return
#' @export
#'
#' @examples
identify_SYMBOL_PACKAGE <- function(id, df_ParsedData){
  # get the parent of the function call
  parent_of_foo <- df_ParsedData$parent[which(df_ParsedData$id == id)]
  # get the package name if there is one
  package <- df_ParsedData$text[df_ParsedData$parent == parent_of_foo & df_ParsedData$token=="SYMBOL_PACKAGE"]
  # else find the package from environment
  if(length(package) == 0) package <- find(what = df_ParsedData$text[df_ParsedData$id == id])[1]

  # remove the text 'package:' from the object if it exists
  package <- gsub("package:", "", package)

  return(package)
}