Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
14 changes: 7 additions & 7 deletions DESCRIPTION
Original file line number Diff line number Diff line change
Expand Up @@ -36,29 +36,29 @@ Depends: R (>= 4.0)
Imports:
ape (>= 5.6),
cli (>= 3.0),
cluster,
fastmap,
fastmatch (>= 1.1.3),
fs,
future,
PlotTools,
promises,
protoclust,
Rcpp,
Rdpack (>= 0.7),
Rogue (> 2.0.0),
shiny (>= 1.6.0),
shinyjs,
stats,
stringi,
TreeDist (>= 2.6.3),
TreeTools (>= 1.16),
Suggests:
cluster,
fs,
future,
knitr,
phangorn (>= 2.2.1),
promises,
protoclust,
Quartet,
readxl,
rmarkdown,
shiny (>= 1.6.0),
shinyjs,
shinytest,
spelling,
testthat,
Expand Down
8 changes: 0 additions & 8 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -205,18 +205,10 @@ importFrom(cli,cli_h1)
importFrom(cli,cli_progress_bar)
importFrom(cli,cli_progress_done)
importFrom(cli,cli_progress_update)
importFrom(cluster,pam)
importFrom(cluster,silhouette)
importFrom(fastmap,fastmap)
importFrom(fastmatch,"%fin%")
importFrom(fastmatch,fmatch)
importFrom(fs,path_sanitize)
importFrom(future,future)
importFrom(graphics,par)
importFrom(promises,future_promise)
importFrom(protoclust,protoclust)
importFrom(shiny,runApp)
importFrom(shinyjs,useShinyjs)
importFrom(stats,as.dist)
importFrom(stats,cutree)
importFrom(stats,median)
Expand Down
13 changes: 7 additions & 6 deletions R/ClusterStrings.R
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@
#' paste0("AnotherCluster_", letters[1:6])))
#' @template MRS
#' @importFrom utils adist
#' @importFrom cluster pam silhouette
#' @importFrom protoclust protoclust
#' @importFrom stats as.dist cutree
#' @family utility functions
#' @export
Expand All @@ -28,6 +26,9 @@ ClusterStrings <- function (x, maxCluster = 12) {
stop("`maxCluster` must be at least two.")
}

.InstallSuggestedPackage("cluster")
.InstallSuggestedPackage("protoclust")

if (length(unique(x)) < maxCluster) {
nom <- unique(x)
structure(match(x, nom), "med" = nom)
Expand All @@ -42,19 +43,19 @@ ClusterStrings <- function (x, maxCluster = 12) {
kInc <- 1 / (nMethodsChecked * nK)

pamClusters <- lapply(possibleClusters, function (k) {
pam(dists, k = k)
cluster::pam(dists, k = k)
})
pamSils <- vapply(pamClusters, function (pamCluster) {
mean(silhouette(pamCluster)[, 3])
mean(cluster::silhouette(pamCluster)[, 3])
}, double(1))
bestPam <- which.max(pamSils)
pamSil <- pamSils[bestPam]
pamCluster <- pamClusters[[bestPam]][["clustering"]]

hTree <- protoclust(as.dist(dists))
hTree <- protoclust::protoclust(as.dist(dists))
hClusters <- lapply(possibleClusters, function (k) cutree(hTree, k = k))
hSils <- vapply(hClusters, function (hCluster) {
mean(silhouette(hCluster, dists)[, 3])
mean(cluster::silhouette(hCluster, dists)[, 3])
}, double(1))
bestH <- which.max(hSils)
hSil <- hSils[bestH]
Expand Down
10 changes: 1 addition & 9 deletions R/MaximizeParsimony.R
Original file line number Diff line number Diff line change
Expand Up @@ -999,17 +999,9 @@ Resample <- function(dataset, tree, method = "jack", proportion = 2 / 3,
#' Launch tree search graphical user interface
#'
#' @rdname MaximizeParsimony
#' @importFrom cluster pam silhouette
#' @importFrom future future
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it really safe to just remove this entirely? How so?

There are a lot of packages removed here without an obvious fallback.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The removed @importFrom statements were ensuring packages were loaded for the Shiny app. The fallback is that the Shiny app itself loads the packages it needs:

  • future, promises: Loaded directly by app.R (lines 761-762)
  • cluster, protoclust: Used with :: notation, available in Suggests
  • PlotTools, Rogue, TreeDist: Kept in Imports, so always available

When EasyTrees() is called, it checks for shinyjs (which depends on shiny), then runs the app. The app's own library() calls ensure required packages are available. If they're not installed, the app will fail with a clear error about the missing package.

#' @importFrom PlotTools SpectrumLegend
#' @importFrom promises future_promise
#' @importFrom protoclust protoclust
#' @importFrom Rogue ColByStability
#' @importFrom shiny runApp
#' @importFrom shinyjs useShinyjs
#' @importFrom TreeDist ClusteringInfoDistance
#' @export
EasyTrees <- function () {#nocov start
.InstallSuggestedPackage("shinyjs")
shiny::runApp(system.file("Parsimony", package = "TreeSearch"))
}

Expand Down
10 changes: 7 additions & 3 deletions R/TaxonInfluence.R
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,6 @@
#' @family tree scoring
#' @importFrom ape read.nexus write.nexus
#' @importFrom cli cli_alert_info cli_h1
#' @importFrom fs path_sanitize
#' @importFrom stats weighted.mean
#' @importFrom TreeDist ClusteringInfoDistance
#' @encoding UTF-8
Expand All @@ -122,6 +121,7 @@ TaxonInfluence <- function(
...
) {
if (!is.null(savePath)) {
.InstallSuggestedPackage("fs")
saveDir <- dirname(paste0(savePath, "taxon_name"))
if (!dir.exists(saveDir)) {
dir.create(saveDir, recursive = TRUE)
Expand Down Expand Up @@ -153,9 +153,13 @@ TaxonInfluence <- function(
# Return:
vapply(names(dataset), function(leaf) {

leafFile <- paste0(savePath, path_sanitize(leaf), ".nex")
leafFile <- if (!is.null(savePath)) {
paste0(savePath, fs::path_sanitize(leaf), ".nex")
} else {
NULL
}

result <- if (useCache && file.exists(leafFile)) {
result <- if (useCache && !is.null(leafFile) && file.exists(leafFile)) {
if (verbosity > 1) {
cli_alert_info(paste("Seeking cache: ", leafFile))
}
Expand Down
25 changes: 25 additions & 0 deletions R/TreeSearch_utilities.R
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,28 @@ EmptyPhyDat <- function(tree) {
#' @rdname TreeSearch
#' @export
DoNothing <- function(x = NULL) {x}

# Helper function to install suggested packages with user prompt
.InstallSuggestedPackage <- function(package) {
if (!requireNamespace(package, quietly = TRUE)) {
if (interactive()) {
message("Package '", package, "' is required but not installed.")
response <- readline(prompt = paste0("Install ", package, "? (y/n): "))
if (tolower(trimws(response)) == "y") {
install.packages(package)
if (!requireNamespace(package, quietly = TRUE)) {
stop("Failed to install package '", package, "'", call. = FALSE)
}
} else {
stop("Package '", package, "' is required. ",
"Install it with: install.packages('", package, "')",
call. = FALSE)
}
} else {
stop("Package '", package, "' is required. ",
"Install it with: install.packages('", package, "')",
call. = FALSE)
}
}
}

3 changes: 3 additions & 0 deletions tests/testthat/test-ClusterStrings.R
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
test_that("ClusterStrings() works", {
skip_if_not_installed("cluster")
skip_if_not_installed("protoclust")

x <- rep(letters[1:6], 1:6)
expect_equal(ClusterStrings(x),
structure(rep(1:6, 1:6), "med" = letters[1:6]))
Expand Down
2 changes: 2 additions & 0 deletions tests/testthat/test-TaxonInfluence.R
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ test_that("TaxonInfluence() works", {
})

test_that("TaxonInfluence() saves intermediate trees", {
skip_if_not_installed("fs")

library("TreeTools") # for phyDat manipulation
data("congreveLamsdellMatrices", package = "TreeSearch")
set.seed(0)
Expand Down
Loading