From 898d5abd210edf9c488a3ec25fb769303926b9e7 Mon Sep 17 00:00:00 2001 From: Tim Brock Date: Thu, 8 Feb 2024 18:18:16 +0000 Subject: [PATCH 01/68] Fix typo in title --- R/place_title_logo.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/place_title_logo.R b/R/place_title_logo.R index 3486310..bcd61b6 100644 --- a/R/place_title_logo.R +++ b/R/place_title_logo.R @@ -8,7 +8,7 @@ place_title_logo = function() { src = "www/logo.png", contentType = "image/png", height = 80, width = 100), - "tpfbrowser") + "tfpbrowser") return(title) } From 93d86573c84fb04d56393856edbba52529de30e3 Mon Sep 17 00:00:00 2001 From: Russ Hyde Date: Thu, 14 Mar 2024 12:42:06 +0000 Subject: [PATCH 02/68] chore: bump lint GHA workflow --- .github/workflows/lint.yaml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml index 381410b..f60d047 100644 --- a/.github/workflows/lint.yaml +++ b/.github/workflows/lint.yaml @@ -14,7 +14,7 @@ jobs: env: GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - uses: r-lib/actions/setup-r@v2 with: @@ -28,3 +28,5 @@ jobs: - name: Lint run: lintr::lint_package() shell: Rscript {0} + env: + LINTR_ERROR_ON_LINT: true From 3f940911b7b7eb551ba135c4a3b105bd63fcc2f4 Mon Sep 17 00:00:00 2001 From: Russ Hyde Date: Thu, 14 Mar 2024 12:46:16 +0000 Subject: [PATCH 03/68] chore: bump R CMD check workflow --- .github/workflows/R-CMD-check.yaml | 29 ---------------- .github/workflows/check-standard.yaml | 50 +++++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 29 deletions(-) delete mode 100644 .github/workflows/R-CMD-check.yaml create mode 100644 .github/workflows/check-standard.yaml diff --git a/.github/workflows/R-CMD-check.yaml b/.github/workflows/R-CMD-check.yaml deleted file mode 100644 index b32be55..0000000 --- a/.github/workflows/R-CMD-check.yaml +++ /dev/null @@ -1,29 +0,0 @@ -# Workflow derived from https://github.com/r-lib/actions/tree/v2/examples -# Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help -on: - push: - branches: [main, master] - pull_request: - branches: [main, master] - -name: R-CMD-check - -jobs: - R-CMD-check: - runs-on: ubuntu-latest - env: - GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} - R_KEEP_PKG_SOURCE: yes - steps: - - uses: actions/checkout@v2 - - - uses: r-lib/actions/setup-r@v2 - with: - use-public-rspm: true - - - uses: r-lib/actions/setup-r-dependencies@v2 - with: - extra-packages: any::rcmdcheck - needs: check - - - uses: r-lib/actions/check-r-package@v2 diff --git a/.github/workflows/check-standard.yaml b/.github/workflows/check-standard.yaml new file mode 100644 index 0000000..14159b7 --- /dev/null +++ b/.github/workflows/check-standard.yaml @@ -0,0 +1,50 @@ +# Workflow derived from https://github.com/r-lib/actions/tree/v2/examples +# Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help +on: + push: + branches: [main, master] + pull_request: + branches: [main, master] + +name: R-CMD-check + +jobs: + R-CMD-check: + runs-on: ${{ matrix.config.os }} + + name: ${{ matrix.config.os }} (${{ matrix.config.r }}) + + strategy: + fail-fast: false + matrix: + config: + - {os: macos-latest, r: 'release'} + - {os: windows-latest, r: 'release'} + - {os: ubuntu-latest, r: 'devel', http-user-agent: 'release'} + - {os: ubuntu-latest, r: 'release'} + - {os: ubuntu-latest, r: 'oldrel-1'} + + env: + GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} + R_KEEP_PKG_SOURCE: yes + + steps: + - uses: actions/checkout@v4 + + - uses: r-lib/actions/setup-pandoc@v2 + + - uses: r-lib/actions/setup-r@v2 + with: + r-version: ${{ matrix.config.r }} + http-user-agent: ${{ matrix.config.http-user-agent }} + use-public-rspm: true + + - uses: r-lib/actions/setup-r-dependencies@v2 + with: + extra-packages: any::rcmdcheck + needs: check + + - uses: r-lib/actions/check-r-package@v2 + with: + upload-snapshots: true + build_args: 'c("--no-manual","--compact-vignettes=gs+qpdf")' From 1db2abe099a26585c12787ce995299f8a6990fbe Mon Sep 17 00:00:00 2001 From: Russ Hyde Date: Thu, 14 Mar 2024 14:03:45 +0000 Subject: [PATCH 04/68] env: bump renv definition to include Bioc 3.18 (because we couldn't install Bioc 3.17 packages in GHA runs) --- renv.lock | 790 +++++++++++++++++++++++---------------------- renv/activate.R | 425 ++++++++++++++++-------- renv/settings.json | 17 + 3 files changed, 715 insertions(+), 517 deletions(-) create mode 100644 renv/settings.json diff --git a/renv.lock b/renv.lock index 2b8eca9..c510492 100644 --- a/renv.lock +++ b/renv.lock @@ -1,7 +1,27 @@ { "R": { - "Version": "4.3.2", + "Version": "4.3.3", "Repositories": [ + { + "Name": "BioCsoft", + "URL": "https://bioconductor.org/packages/3.18/bioc" + }, + { + "Name": "BioCann", + "URL": "https://bioconductor.org/packages/3.18/data/annotation" + }, + { + "Name": "BioCexp", + "URL": "https://bioconductor.org/packages/3.18/data/experiment" + }, + { + "Name": "BioCworkflows", + "URL": "https://bioconductor.org/packages/3.18/workflows" + }, + { + "Name": "BioCbooks", + "URL": "https://bioconductor.org/packages/3.18/books" + }, { "Name": "CRAN", "URL": "https://cloud.r-project.org" @@ -9,7 +29,7 @@ ] }, "Bioconductor": { - "Version": "3.17" + "Version": "3.18" }, "Packages": { "AsioHeaders": { @@ -21,32 +41,32 @@ }, "BiocManager": { "Package": "BiocManager", - "Version": "1.30.20", + "Version": "1.30.22", "Source": "Repository", - "Repository": "RSPM", + "Repository": "CRAN", "Requirements": [ "utils" ], - "Hash": "a7fca16a50b6ef7771b49d636dd54b57" + "Hash": "d57e43105a1aa9cb54fdb4629725acb1" }, "BiocVersion": { "Package": "BiocVersion", - "Version": "3.17.1", + "Version": "3.18.1", "Source": "Bioconductor", "git_url": "https://git.bioconductor.org/packages/BiocVersion", - "git_branch": "master", - "git_last_commit": "a2d0c4c", - "git_last_commit_date": "2022-11-02", + "git_branch": "RELEASE_3_18", + "git_last_commit": "70680b8", + "git_last_commit_date": "2023-11-15", "Requirements": [ "R" ], - "Hash": "f7c0d5521799b7b0d0a211143ed0bfcb" + "Hash": "2ecaed86684f5fae76ed5530f9d29c4a" }, "MASS": { "Package": "MASS", - "Version": "7.3-60", + "Version": "7.3-60.0.1", "Source": "Repository", - "Repository": "RSPM", + "Repository": "CRAN", "Requirements": [ "R", "grDevices", @@ -55,15 +75,16 @@ "stats", "utils" ], - "Hash": "a56a6365b3fa73293ea8d084be0d9bb0" + "Hash": "b765b28387acc8ec9e9c1530713cb19c" }, "Matrix": { "Package": "Matrix", - "Version": "1.5-4.1", + "Version": "1.6-5", "Source": "Repository", - "Repository": "RSPM", + "Repository": "CRAN", "Requirements": [ "R", + "grDevices", "graphics", "grid", "lattice", @@ -71,7 +92,7 @@ "stats", "utils" ], - "Hash": "38082d362d317745fb932e13956dccbb" + "Hash": "8c7115cd3a0e048bda2a7cd110549f7a" }, "R6": { "Package": "R6", @@ -95,20 +116,14 @@ }, "Rcpp": { "Package": "Rcpp", - "Version": "1.0.10", + "Version": "1.0.12", "Source": "Repository", - "Repository": "RSPM", - "RemoteType": "standard", - "RemotePkgRef": "Rcpp", - "RemoteRef": "Rcpp", - "RemoteRepos": "https://packagemanager.rstudio.com/all/latest", - "RemotePkgPlatform": "source", - "RemoteSha": "1.0.10", + "Repository": "CRAN", "Requirements": [ "methods", "utils" ], - "Hash": "e749cae40fa9ef469b6050959517453c" + "Hash": "5ea2700d21e038ace58269ecdbeb9ec0" }, "ape": { "Package": "ape", @@ -131,10 +146,11 @@ }, "aplot": { "Package": "aplot", - "Version": "0.1.10", + "Version": "0.2.2", "Source": "Repository", - "Repository": "RSPM", + "Repository": "CRAN", "Requirements": [ + "R", "ggfun", "ggplot2", "ggplotify", @@ -143,17 +159,17 @@ "patchwork", "utils" ], - "Hash": "e5ce4f3b5fe236bb879712ff8f956f06" + "Hash": "869a35e6d38fe9936eb578e09091842b" }, "askpass": { "Package": "askpass", - "Version": "1.1", + "Version": "1.2.0", "Source": "Repository", - "Repository": "RSPM", + "Repository": "CRAN", "Requirements": [ "sys" ], - "Hash": "e8a22846fff485f0be3770c2da758713" + "Hash": "cad6cf7f1d5f6e906700b9d3e718c796" }, "backports": { "Package": "backports", @@ -201,16 +217,19 @@ }, "brio": { "Package": "brio", - "Version": "1.1.3", + "Version": "1.1.4", "Source": "Repository", - "Repository": "RSPM", - "Hash": "976cf154dfb043c012d87cddd8bca363" + "Repository": "CRAN", + "Requirements": [ + "R" + ], + "Hash": "68bd2b066e1fe780bbf62fc8bcc36de3" }, "bslib": { "Package": "bslib", - "Version": "0.4.2", + "Version": "0.6.1", "Source": "Repository", - "Repository": "RSPM", + "Repository": "CRAN", "Requirements": [ "R", "base64enc", @@ -219,62 +238,55 @@ "htmltools", "jquerylib", "jsonlite", + "lifecycle", "memoise", "mime", "rlang", "sass" ], - "Hash": "a7fbf03946ad741129dc81098722fca1" + "Hash": "c0d8599494bc7fb408cd206bbdd9cab0" }, "cachem": { "Package": "cachem", - "Version": "1.0.7", + "Version": "1.0.8", "Source": "Repository", - "Repository": "RSPM", - "RemotePkgRef": "cachem@1.0.7", - "RemoteType": "standard", - "RemoteEtag": "\"79ef8991588f9e5aad4cc465e8fa16aa\"", - "RemotePackaged": "TRUE", - "RemoteRef": "cachem", - "RemoteRepos": "https://packagemanager.rstudio.com/all/latest", - "RemotePkgPlatform": "source", - "RemoteSha": "1.0.7", + "Repository": "CRAN", "Requirements": [ "fastmap", "rlang" ], - "Hash": "cda74447c42f529de601fe4d4050daef" + "Hash": "c35768291560ce302c0a6589f92e837d" }, "callr": { "Package": "callr", - "Version": "3.7.3", + "Version": "3.7.5", "Source": "Repository", - "Repository": "RSPM", + "Repository": "CRAN", "Requirements": [ "R", "R6", "processx", "utils" ], - "Hash": "9b2191ede20fa29828139b9900922e51" + "Hash": "9f0e4fae4963ba775a5e5c520838c87b" }, "checkmate": { "Package": "checkmate", - "Version": "2.2.0", + "Version": "2.3.1", "Source": "Repository", - "Repository": "RSPM", + "Repository": "CRAN", "Requirements": [ "R", "backports", "utils" ], - "Hash": "ca9c113196136f4a9ca9ce6079c2c99e" + "Hash": "c01cab1cb0f9125211a6fc99d540e315" }, "chromote": { "Package": "chromote", - "Version": "0.1.1", + "Version": "0.2.0", "Source": "Repository", - "Repository": "RSPM", + "Repository": "CRAN", "Requirements": [ "R6", "curl", @@ -285,26 +297,21 @@ "processx", "promises", "rlang", + "utils", "websocket" ], - "Hash": "bb5817af24a2d8e6e33e758eb54978be" + "Hash": "3cfaf9cbd331e07055acada321664e12" }, "cli": { "Package": "cli", - "Version": "3.6.1", + "Version": "3.6.2", "Source": "Repository", - "Repository": "RSPM", - "RemoteType": "standard", - "RemotePkgRef": "cli", - "RemoteRef": "cli", - "RemoteRepos": "https://packagemanager.rstudio.com/all/latest", - "RemotePkgPlatform": "source", - "RemoteSha": "3.6.1", + "Repository": "CRAN", "Requirements": [ "R", "utils" ], - "Hash": "89e6d8219950eac806ae0c489052048a" + "Hash": "1216ac65ac55ec0058a6f75d7ca0fd52" }, "clipr": { "Package": "clipr", @@ -342,17 +349,20 @@ }, "commonmark": { "Package": "commonmark", - "Version": "1.9.0", + "Version": "1.9.1", "Source": "Repository", - "Repository": "RSPM", - "Hash": "d691c61bff84bd63c383874d2d0c3307" + "Repository": "CRAN", + "Hash": "5d8225445acb167abf7797de48b2ee3c" }, "cpp11": { "Package": "cpp11", - "Version": "0.4.3", + "Version": "0.4.7", "Source": "Repository", - "Repository": "RSPM", - "Hash": "ed588261931ee3be2c700d22e94a29ab" + "Repository": "CRAN", + "Requirements": [ + "R" + ], + "Hash": "5a295d7d963cc5035284dcdbaf334f4e" }, "crayon": { "Package": "crayon", @@ -368,9 +378,9 @@ }, "credentials": { "Package": "credentials", - "Version": "1.3.2", + "Version": "2.0.1", "Source": "Repository", - "Repository": "RSPM", + "Repository": "CRAN", "Requirements": [ "askpass", "curl", @@ -378,42 +388,54 @@ "openssl", "sys" ], - "Hash": "93762d0a34d78e6a025efdbfb5c6bb41" + "Hash": "c7844b32098dcbd1c59cbd8dddb4ecc6" + }, + "crosstalk": { + "Package": "crosstalk", + "Version": "1.2.1", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "R6", + "htmltools", + "jsonlite", + "lazyeval" + ], + "Hash": "ab12c7b080a57475248a30f4db6298c0" }, "curl": { "Package": "curl", - "Version": "5.0.0", + "Version": "5.2.1", "Source": "Repository", - "Repository": "RSPM", + "Repository": "CRAN", "Requirements": [ "R" ], - "Hash": "e4f97056611e8e6b8b852d13b7400cf1" + "Hash": "411ca2c03b1ce5f548345d2fc2685f7a" }, "data.table": { "Package": "data.table", - "Version": "1.14.8", + "Version": "1.15.2", "Source": "Repository", - "Repository": "RSPM", + "Repository": "CRAN", "Requirements": [ "R", "methods" ], - "Hash": "b4c06e554f33344e044ccd7fdca750a9" + "Hash": "536dfe4ac4093b5d115caed7a1a7223b" }, "desc": { "Package": "desc", - "Version": "1.4.2", + "Version": "1.4.3", "Source": "Repository", - "Repository": "RSPM", + "Repository": "CRAN", "Requirements": [ "R", "R6", "cli", - "rprojroot", "utils" ], - "Hash": "6b9602c7ebbe87101a9c8edb6e8b6d21" + "Hash": "99b79fcbd6c4d1ce087f5c5c758b384f" }, "diffobj": { "Package": "diffobj", @@ -432,20 +454,20 @@ }, "digest": { "Package": "digest", - "Version": "0.6.31", + "Version": "0.6.35", "Source": "Repository", - "Repository": "RSPM", + "Repository": "CRAN", "Requirements": [ "R", "utils" ], - "Hash": "8b708f296afd9ae69f450f9640be8990" + "Hash": "698ece7ba5a4fa4559e3d537e7ec3d31" }, "dplyr": { "Package": "dplyr", - "Version": "1.1.2", + "Version": "1.1.4", "Source": "Repository", - "Repository": "RSPM", + "Repository": "CRAN", "Requirements": [ "R", "R6", @@ -462,7 +484,7 @@ "utils", "vctrs" ], - "Hash": "dea6970ff715ca541c387de363ff405e" + "Hash": "fedd9d00c2944ff00a0e2696ccf048ec" }, "ellipsis": { "Package": "ellipsis", @@ -477,32 +499,26 @@ }, "evaluate": { "Package": "evaluate", - "Version": "0.21", + "Version": "0.23", "Source": "Repository", - "Repository": "RSPM", - "RemoteType": "standard", - "RemotePkgRef": "evaluate", - "RemoteRef": "evaluate", - "RemoteRepos": "https://packagemanager.rstudio.com/all/latest", - "RemotePkgPlatform": "source", - "RemoteSha": "0.21", + "Repository": "CRAN", "Requirements": [ "R", "methods" ], - "Hash": "d59f3b464e8da1aef82dc04b588b8dfb" + "Hash": "daf4a1246be12c1fa8c7705a0935c1a0" }, "fansi": { "Package": "fansi", - "Version": "1.0.4", + "Version": "1.0.6", "Source": "Repository", - "Repository": "RSPM", + "Repository": "CRAN", "Requirements": [ "R", "grDevices", "utils" ], - "Hash": "1d9e7ad3c8312a192dea7d3db0274fde" + "Hash": "962174cf2aeb5b9eea581522286a911f" }, "farver": { "Package": "farver", @@ -513,39 +529,33 @@ }, "fastmap": { "Package": "fastmap", - "Version": "1.1.0", + "Version": "1.1.1", "Source": "Repository", - "Repository": "RSPM", - "Hash": "77bd60a6157420d4ffa93b27cf6a58b8" + "Repository": "CRAN", + "Hash": "f7736a18de97dea803bde0a2daaafb27" }, "fontawesome": { "Package": "fontawesome", - "Version": "0.5.1", + "Version": "0.5.2", "Source": "Repository", - "Repository": "RSPM", + "Repository": "CRAN", "Requirements": [ "R", "htmltools", "rlang" ], - "Hash": "1e22b8cabbad1eae951a75e9f8b52378" + "Hash": "c2efdd5f0bcd1ea861c2d4e2a883a67d" }, "fs": { "Package": "fs", - "Version": "1.6.2", + "Version": "1.6.3", "Source": "Repository", - "Repository": "RSPM", - "RemoteType": "standard", - "RemotePkgRef": "fs", - "RemoteRef": "fs", - "RemoteRepos": "https://packagemanager.rstudio.com/all/latest", - "RemotePkgPlatform": "source", - "RemoteSha": "1.6.2", + "Repository": "CRAN", "Requirements": [ "R", "methods" ], - "Hash": "94af08e0aa9675a16fadbb3aaaa90d2a" + "Hash": "47b5f30c720c23999b913a1a635cf0bb" }, "generics": { "Package": "generics", @@ -560,9 +570,9 @@ }, "gert": { "Package": "gert", - "Version": "1.9.2", + "Version": "2.0.1", "Source": "Repository", - "Repository": "RSPM", + "Repository": "CRAN", "Requirements": [ "askpass", "credentials", @@ -571,36 +581,31 @@ "sys", "zip" ], - "Hash": "9122b3958e749badb5c939f498038b57" + "Hash": "f70d3fe2d9e7654213a946963d1591eb" }, "ggfun": { "Package": "ggfun", - "Version": "0.0.9", + "Version": "0.1.4", "Source": "Repository", - "Repository": "RSPM", + "Repository": "CRAN", "Requirements": [ + "R", + "cli", "ggplot2", "grid", "rlang", "utils" ], - "Hash": "c970ab268b09d3c8b0f524294050860f" + "Hash": "91780e07f1d631a1152835b4e25c66b9" }, "ggiraph": { "Package": "ggiraph", - "Version": "0.8.4", + "Version": "0.8.9", "Source": "Repository", - "Repository": "RSPM", - "RemotePkgRef": "ggiraph@0.8.4", - "RemoteType": "standard", - "RemoteEtag": "\"7d55b4cd82be7ae8d95b4ddd0a21b336\"", - "RemotePackaged": "TRUE", - "RemoteRef": "ggiraph", - "RemoteRepos": "https://packagemanager.rstudio.com/all/latest", - "RemotePkgPlatform": "source", - "RemoteSha": "0.8.4", + "Repository": "CRAN", "Requirements": [ "Rcpp", + "cli", "ggplot2", "grid", "htmltools", @@ -612,21 +617,13 @@ "uuid", "vctrs" ], - "Hash": "98e3965e27dd3c9bda630b377544e92b" + "Hash": "50a51e9be10ba75fc43ee7fb21c18af0" }, "ggplot2": { "Package": "ggplot2", - "Version": "3.4.0", + "Version": "3.5.0", "Source": "Repository", - "Repository": "RSPM", - "RemotePkgRef": "ggplot2@3.4.0", - "RemoteType": "standard", - "RemoteEtag": "\"bcfaa8d358bfaa987a4aff43c4dfc9da\"", - "RemotePackaged": "TRUE", - "RemoteRef": "ggplot2", - "RemoteRepos": "https://packagemanager.rstudio.com/all/latest", - "RemotePkgPlatform": "source", - "RemoteSha": "3.4.0", + "Repository": "CRAN", "Requirements": [ "MASS", "R", @@ -645,13 +642,13 @@ "vctrs", "withr" ], - "Hash": "fd2aab12f54400c6bca43687231e246b" + "Hash": "52ef83f93f74833007f193b2d4c159a2" }, "ggplotify": { "Package": "ggplotify", - "Version": "0.1.0", + "Version": "0.1.2", "Source": "Repository", - "Repository": "RSPM", + "Repository": "CRAN", "Requirements": [ "R", "ggplot2", @@ -661,17 +658,18 @@ "gridGraphics", "yulab.utils" ], - "Hash": "acbcedf783cdb8710168aa0edba42ac0" + "Hash": "1547863db3b472cf7181973acf649f1a" }, "ggtree": { "Package": "ggtree", - "Version": "3.8.2", - "Source": "Bioconductor", + "Version": "3.10.1", + "Source": "Repository", + "Repository": "Bioconductor 3.18", "Remotes": "GuangchuangYu/treeio", "git_url": "https://git.bioconductor.org/packages/ggtree", - "git_branch": "RELEASE_3_17", - "git_last_commit": "36ae5e5", - "git_last_commit_date": "2023-07-24", + "git_branch": "RELEASE_3_18", + "git_last_commit": "5014378", + "git_last_commit_date": "2024-02-25", "Requirements": [ "R", "ape", @@ -693,7 +691,7 @@ "utils", "yulab.utils" ], - "Hash": "8959d04f88a175de3f0cd2b46b4c2a65" + "Hash": "6b825b70c84bd46133ac63b6dccedef0" }, "gh": { "Package": "gh", @@ -723,25 +721,25 @@ }, "globals": { "Package": "globals", - "Version": "0.16.2", + "Version": "0.16.3", "Source": "Repository", - "Repository": "RSPM", + "Repository": "CRAN", "Requirements": [ "R", "codetools" ], - "Hash": "baa9585ab4ce47a9f4618e671778cc6f" + "Hash": "2580567908cafd4f187c1e5a91e98b7f" }, "glue": { "Package": "glue", - "Version": "1.6.2", + "Version": "1.7.0", "Source": "Repository", - "Repository": "RSPM", + "Repository": "CRAN", "Requirements": [ "R", "methods" ], - "Hash": "4f2596dfb05dac67b9dc558e5c6fba2e" + "Hash": "e0b3a53876554bd45879e596cdb10a52" }, "gridGraphics": { "Package": "gridGraphics", @@ -757,9 +755,9 @@ }, "gtable": { "Package": "gtable", - "Version": "0.3.3", + "Version": "0.3.4", "Source": "Repository", - "Repository": "RSPM", + "Repository": "CRAN", "Requirements": [ "R", "cli", @@ -768,7 +766,7 @@ "lifecycle", "rlang" ], - "Hash": "b44addadb528a0d227794121c00572a0" + "Hash": "b29cf3031f49b04ab9c852c912547eef" }, "highr": { "Package": "highr", @@ -803,9 +801,9 @@ }, "htmltools": { "Package": "htmltools", - "Version": "0.5.5", + "Version": "0.5.7", "Source": "Repository", - "Repository": "RSPM", + "Repository": "CRAN", "Requirements": [ "R", "base64enc", @@ -816,13 +814,13 @@ "rlang", "utils" ], - "Hash": "ba0240784ad50a62165058a27459304a" + "Hash": "2d7b3857980e0e0d0a1fd6f11928ab0f" }, "htmlwidgets": { "Package": "htmlwidgets", - "Version": "1.6.2", + "Version": "1.6.4", "Source": "Repository", - "Repository": "RSPM", + "Repository": "CRAN", "Requirements": [ "grDevices", "htmltools", @@ -831,13 +829,13 @@ "rmarkdown", "yaml" ], - "Hash": "a865aa85bcb2697f47505bfd70422471" + "Hash": "04291cc45198225444a397606810ac37" }, "httpuv": { "Package": "httpuv", - "Version": "1.6.11", + "Version": "1.6.14", "Source": "Repository", - "Repository": "RSPM", + "Repository": "CRAN", "Requirements": [ "R", "R6", @@ -846,13 +844,13 @@ "promises", "utils" ], - "Hash": "838602f54e32c1a0f8cc80708cefcefa" + "Hash": "16abeb167dbf511f8cc0552efaf05bab" }, "httr": { "Package": "httr", - "Version": "1.4.6", + "Version": "1.4.7", "Source": "Repository", - "Repository": "RSPM", + "Repository": "CRAN", "Requirements": [ "R", "R6", @@ -861,26 +859,28 @@ "mime", "openssl" ], - "Hash": "7e5e3cbd2a7bc07880c94e22348fb661" + "Hash": "ac107251d9d9fd72f0ca8049988f1d7f" }, "httr2": { "Package": "httr2", - "Version": "0.2.3", + "Version": "1.0.0", "Source": "Repository", - "Repository": "RSPM", + "Repository": "CRAN", "Requirements": [ "R", "R6", "cli", "curl", "glue", + "lifecycle", "magrittr", "openssl", "rappdirs", "rlang", + "vctrs", "withr" ], - "Hash": "193bb297368afbbb42dc85784a46b36e" + "Hash": "e2b30f1fc039a0bab047dd52bb20ef71" }, "ini": { "Package": "ini", @@ -940,19 +940,19 @@ }, "jsonlite": { "Package": "jsonlite", - "Version": "1.8.4", + "Version": "1.8.8", "Source": "Repository", - "Repository": "RSPM", + "Repository": "CRAN", "Requirements": [ "methods" ], - "Hash": "a4269a09a9b865579b2635c77e572374" + "Hash": "e1b9c55281c5adc4dd113652d9e26768" }, "knitr": { "Package": "knitr", - "Version": "1.43", + "Version": "1.45", "Source": "Repository", - "Repository": "RSPM", + "Repository": "CRAN", "Requirements": [ "R", "evaluate", @@ -962,41 +962,33 @@ "xfun", "yaml" ], - "Hash": "9775eb076713f627c07ce41d8199d8f6" + "Hash": "1ec462871063897135c1bcbe0fc8f07d" }, "labeling": { "Package": "labeling", - "Version": "0.4.2", + "Version": "0.4.3", "Source": "Repository", - "Repository": "RSPM", + "Repository": "CRAN", "Requirements": [ "graphics", "stats" ], - "Hash": "3d5108641f47470611a32d0bdf357a72" + "Hash": "b64ec208ac5bc1852b285f665d6368b3" }, "later": { "Package": "later", - "Version": "1.3.0", + "Version": "1.3.2", "Source": "Repository", - "Repository": "RSPM", - "RemotePkgRef": "later@1.3.0", - "RemoteType": "standard", - "RemoteEtag": "\"d88839554a04c066f8ca978670ee8a9d\"", - "RemotePackaged": "TRUE", - "RemoteRef": "later", - "RemoteRepos": "https://packagemanager.rstudio.com/all/latest", - "RemotePkgPlatform": "source", - "RemoteSha": "1.3.0", + "Repository": "CRAN", "Requirements": [ "Rcpp", "rlang" ], - "Hash": "7e7b457d7766bc47f2a5f21cc2984f8e" + "Hash": "a3e051d405326b8b0012377434c62b37" }, "lattice": { "Package": "lattice", - "Version": "0.21-8", + "Version": "0.22-5", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -1007,7 +999,7 @@ "stats", "utils" ], - "Hash": "0b8a6d63c8770f02a8b5635f3c431e6b" + "Hash": "7c5e89f04e72d6611c77451f6331a091" }, "lazyeval": { "Package": "lazyeval", @@ -1021,29 +1013,29 @@ }, "lifecycle": { "Package": "lifecycle", - "Version": "1.0.3", + "Version": "1.0.4", "Source": "Repository", - "Repository": "RSPM", + "Repository": "CRAN", "Requirements": [ "R", "cli", "glue", "rlang" ], - "Hash": "001cecbeac1cff9301bdc3775ee46a86" + "Hash": "b8552d117e1b808b09a832f589b79035" }, "lubridate": { "Package": "lubridate", - "Version": "1.9.2", + "Version": "1.9.3", "Source": "Repository", - "Repository": "RSPM", + "Repository": "CRAN", "Requirements": [ "R", "generics", "methods", "timechange" ], - "Hash": "e25f18436e3efd42c7c590a1c4c15390" + "Hash": "680ad542fbcf801442c83a6ac5a2126c" }, "magrittr": { "Package": "magrittr", @@ -1068,7 +1060,7 @@ }, "mgcv": { "Package": "mgcv", - "Version": "1.8-42", + "Version": "1.9-1", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -1081,7 +1073,7 @@ "stats", "utils" ], - "Hash": "3460beba7ccc8946249ba35327ba902a" + "Hash": "110ee9d83b496279960e162ac97764ce" }, "mime": { "Package": "mime", @@ -1106,7 +1098,7 @@ }, "nlme": { "Package": "nlme", - "Version": "3.1-162", + "Version": "3.1-164", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -1116,33 +1108,35 @@ "stats", "utils" ], - "Hash": "0984ce8da8da9ead8643c5cbbb60f83e" + "Hash": "a623a2239e642806158bc4dc3f51565d" }, "openssl": { "Package": "openssl", - "Version": "2.0.6", + "Version": "2.1.1", "Source": "Repository", - "Repository": "RSPM", + "Repository": "CRAN", "Requirements": [ "askpass" ], - "Hash": "0f7cd2962e3044bb940cca4f4b5cecbe" + "Hash": "2a0dc8c6adfb6f032e4d4af82d258ab5" }, "patchwork": { "Package": "patchwork", - "Version": "1.1.2", + "Version": "1.2.0", "Source": "Repository", - "Repository": "RSPM", + "Repository": "CRAN", "Requirements": [ + "cli", "ggplot2", "grDevices", "graphics", "grid", "gtable", + "rlang", "stats", "utils" ], - "Hash": "63b611e9d909a9ed057639d9c3b77152" + "Hash": "9c8ab14c00ac07e9e04d1664c0b74486" }, "pillar": { "Package": "pillar", @@ -1163,14 +1157,30 @@ }, "pingr": { "Package": "pingr", - "Version": "2.0.2", + "Version": "2.0.3", "Source": "Repository", - "Repository": "RSPM", + "Repository": "CRAN", "Requirements": [ + "R", "processx", "utils" ], - "Hash": "b762f8f7d305f7eb0bab96eb1a3c782a" + "Hash": "8d2db1d13f4198a00ebf2f066bf2ab67" + }, + "pkgbuild": { + "Package": "pkgbuild", + "Version": "1.4.3", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "R6", + "callr", + "cli", + "desc", + "processx" + ], + "Hash": "c0143443203205e6a2760ce553dafc24" }, "pkgconfig": { "Package": "pkgconfig", @@ -1184,9 +1194,9 @@ }, "pkgload": { "Package": "pkgload", - "Version": "1.3.2", + "Version": "1.3.4", "Source": "Repository", - "Repository": "RSPM", + "Repository": "CRAN", "Requirements": [ "R", "cli", @@ -1195,12 +1205,45 @@ "fs", "glue", "methods", + "pkgbuild", "rlang", "rprojroot", "utils", "withr" ], - "Hash": "6b0c222c5071efe0f3baf3dae9aa40e2" + "Hash": "876c618df5ae610be84356d5d7a5d124" + }, + "plotly": { + "Package": "plotly", + "Version": "4.10.4", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "R", + "RColorBrewer", + "base64enc", + "crosstalk", + "data.table", + "digest", + "dplyr", + "ggplot2", + "htmltools", + "htmlwidgets", + "httr", + "jsonlite", + "lazyeval", + "magrittr", + "promises", + "purrr", + "rlang", + "scales", + "tibble", + "tidyr", + "tools", + "vctrs", + "viridisLite" + ], + "Hash": "a1ac5c03ad5ad12b9d1597e00e23c3dd" }, "praise": { "Package": "praise", @@ -1211,80 +1254,73 @@ }, "prettyunits": { "Package": "prettyunits", - "Version": "1.1.1", + "Version": "1.2.0", "Source": "Repository", - "Repository": "RSPM", - "Hash": "95ef9167b75dde9d2ccc3c7528393e7e" + "Repository": "CRAN", + "Requirements": [ + "R" + ], + "Hash": "6b01fc98b1e86c4f705ce9dcfd2f57c7" }, "processx": { "Package": "processx", - "Version": "3.8.1", + "Version": "3.8.3", "Source": "Repository", - "Repository": "RSPM", - "RemoteType": "standard", - "RemotePkgRef": "processx", - "RemoteRef": "processx", - "RemoteRepos": "https://packagemanager.rstudio.com/all/latest", - "RemotePkgPlatform": "source", - "RemoteSha": "3.8.1", + "Repository": "CRAN", "Requirements": [ "R", "R6", "ps", "utils" ], - "Hash": "d75b4059d781336efba24021915902b4" + "Hash": "82d48b1aec56084d9438dbf98087a7e9" }, "progress": { "Package": "progress", - "Version": "1.2.2", + "Version": "1.2.3", "Source": "Repository", - "Repository": "RSPM", + "Repository": "CRAN", "Requirements": [ + "R", "R6", "crayon", "hms", "prettyunits" ], - "Hash": "14dc9f7a3c91ebb14ec5bb9208a07061" + "Hash": "f4625e061cb2865f111b47ff163a5ca6" }, "promises": { "Package": "promises", - "Version": "1.2.0.1", + "Version": "1.2.1", "Source": "Repository", - "Repository": "RSPM", + "Repository": "CRAN", "Requirements": [ "R6", "Rcpp", + "fastmap", "later", "magrittr", "rlang", "stats" ], - "Hash": "4ab2c43adb4d4699cf3690acd378d75d" + "Hash": "0d8a15c9d000970ada1ab21405387dee" }, "ps": { "Package": "ps", - "Version": "1.7.5", + "Version": "1.7.6", "Source": "Repository", - "Repository": "RSPM", - "RemoteType": "standard", - "RemotePkgRef": "ps", - "RemoteRef": "ps", - "RemoteRepos": "https://packagemanager.rstudio.com/all/latest", - "RemotePkgPlatform": "source", - "RemoteSha": "1.7.5", + "Repository": "CRAN", "Requirements": [ "R", "utils" ], - "Hash": "709d852d33178db54b17c722e5b1e594" + "Hash": "dd2b9319ee0656c8acf45c7f40c59de7" }, "purrr": { "Package": "purrr", - "Version": "1.0.1", + "Version": "1.0.2", "Source": "Repository", - "Repository": "RSPM", + "Repository": "CRAN", "Requirements": [ "R", "cli", @@ -1293,7 +1329,7 @@ "rlang", "vctrs" ], - "Hash": "d71c815267c640f17ddbf7f16144b4bb" + "Hash": "1cba04a4e9414bdefc9dcaa99649a8dc" }, "rappdirs": { "Package": "rappdirs", @@ -1307,13 +1343,13 @@ }, "reactR": { "Package": "reactR", - "Version": "0.4.4", + "Version": "0.5.0", "Source": "Repository", - "Repository": "RSPM", + "Repository": "CRAN", "Requirements": [ "htmltools" ], - "Hash": "75389c8091eb14ee21c6bc87a88b3809" + "Hash": "c9014fd1a435b2d790dd506589cb24e5" }, "reactable": { "Package": "reactable", @@ -1332,9 +1368,9 @@ }, "readr": { "Package": "readr", - "Version": "2.1.4", + "Version": "2.1.5", "Source": "Repository", - "Repository": "RSPM", + "Repository": "CRAN", "Requirements": [ "R", "R6", @@ -1351,7 +1387,7 @@ "utils", "vroom" ], - "Hash": "b5047343b3825f37ad9d3b5d89aa1078" + "Hash": "9de96463d2117f6ac49980577939dfb3" }, "rematch2": { "Package": "rematch2", @@ -1365,30 +1401,25 @@ }, "renv": { "Package": "renv", - "Version": "0.17.3", - "Source": "Repository", - "Repository": "RSPM", - "Requirements": [ - "utils" - ], - "Hash": "4543b8cd233ae25c6aba8548be9e747e" + "Version": "1.0.5", + "Source": "Repository" }, "rlang": { "Package": "rlang", - "Version": "1.1.1", + "Version": "1.1.3", "Source": "Repository", - "Repository": "RSPM", + "Repository": "CRAN", "Requirements": [ "R", "utils" ], - "Hash": "a85c767b55f0bf9b7ad16c6d7baee5bb" + "Hash": "42548638fae05fd9a9b5f3f437fbbbe2" }, "rmarkdown": { "Package": "rmarkdown", - "Version": "2.22", + "Version": "2.26", "Source": "Repository", - "Repository": "RSPM", + "Repository": "CRAN", "Requirements": [ "R", "bslib", @@ -1399,45 +1430,36 @@ "jsonlite", "knitr", "methods", - "stringr", "tinytex", "tools", "utils", "xfun", "yaml" ], - "Hash": "75a01be060d800ceb14e32c666cacac9" + "Hash": "9b148e7f95d33aac01f31282d49e4f44" }, "rprojroot": { "Package": "rprojroot", - "Version": "2.0.3", + "Version": "2.0.4", "Source": "Repository", - "Repository": "RSPM", + "Repository": "CRAN", "Requirements": [ "R" ], - "Hash": "1de7ab598047a87bba48434ba35d497d" + "Hash": "4c8415e0ec1e29f3f4f6fc108bef0144" }, "rstudioapi": { "Package": "rstudioapi", - "Version": "0.14", + "Version": "0.15.0", "Source": "Repository", - "Repository": "RSPM", - "Hash": "690bd2acc42a9166ce34845884459320" + "Repository": "CRAN", + "Hash": "5564500e25cffad9e22244ced1379887" }, "sass": { "Package": "sass", - "Version": "0.4.5", + "Version": "0.4.8", "Source": "Repository", - "Repository": "RSPM", - "RemotePkgRef": "sass@0.4.5", - "RemoteType": "standard", - "RemoteEtag": "\"3cac281329b169253ec2dc4243739459\"", - "RemotePackaged": "TRUE", - "RemoteRef": "sass", - "RemoteRepos": "https://packagemanager.rstudio.com/all/latest", - "RemotePkgPlatform": "source", - "RemoteSha": "0.4.5", + "Repository": "CRAN", "Requirements": [ "R6", "fs", @@ -1445,31 +1467,33 @@ "rappdirs", "rlang" ], - "Hash": "2bb4371a4c80115518261866eab6ab11" + "Hash": "168f9353c76d4c4b0a0bbf72e2c2d035" }, "scales": { "Package": "scales", - "Version": "1.2.1", + "Version": "1.3.0", "Source": "Repository", - "Repository": "RSPM", + "Repository": "CRAN", "Requirements": [ "R", "R6", "RColorBrewer", + "cli", "farver", + "glue", "labeling", "lifecycle", "munsell", "rlang", "viridisLite" ], - "Hash": "906cb23d2f1c5680b8ce439b44c6fa63" + "Hash": "c19df082ba346b0ffa6f833e92de34d1" }, "shiny": { "Package": "shiny", - "Version": "1.7.4", + "Version": "1.8.0", "Source": "Repository", - "Repository": "RSPM", + "Repository": "CRAN", "Requirements": [ "R", "R6", @@ -1497,7 +1521,7 @@ "withr", "xtable" ], - "Hash": "c2eae3d8c670fa9dfa35a12066f4a1d5" + "Hash": "3a1f41807d648a908e3c7f0334bf85e6" }, "shinybrowser": { "Package": "shinybrowser", @@ -1531,9 +1555,9 @@ }, "shinytest2": { "Package": "shinytest2", - "Version": "0.2.1", + "Version": "0.3.1", "Source": "Repository", - "Repository": "RSPM", + "Repository": "CRAN", "Requirements": [ "R6", "callr", @@ -1553,25 +1577,19 @@ "testthat", "withr" ], - "Hash": "da29b51211b28a7180977d94b638127e" + "Hash": "04e60b31d4afef1d221ede5fafb0c6f6" }, "snakecase": { "Package": "snakecase", - "Version": "0.11.0", + "Version": "0.11.1", "Source": "Repository", - "Repository": "RSPM", - "RemoteType": "standard", - "RemotePkgRef": "snakecase", - "RemoteRef": "snakecase", - "RemoteRepos": "https://packagemanager.rstudio.com/all/latest", - "RemotePkgPlatform": "source", - "RemoteSha": "0.11.0", + "Repository": "CRAN", "Requirements": [ "R", "stringi", "stringr" ], - "Hash": "4079070fc210c7901c0832a3aeab894f" + "Hash": "58767e44739b76965332e8a4fe3f91f1" }, "sourcetools": { "Package": "sourcetools", @@ -1585,28 +1603,22 @@ }, "stringi": { "Package": "stringi", - "Version": "1.7.12", + "Version": "1.8.3", "Source": "Repository", - "Repository": "RSPM", - "RemoteType": "standard", - "RemotePkgRef": "stringi", - "RemoteRef": "stringi", - "RemoteRepos": "https://packagemanager.rstudio.com/all/latest", - "RemotePkgPlatform": "source", - "RemoteSha": "1.7.12", + "Repository": "CRAN", "Requirements": [ "R", "stats", "tools", "utils" ], - "Hash": "ca8bd84263c77310739d2cf64d84d7c9" + "Hash": "058aebddea264f4c99401515182e656a" }, "stringr": { "Package": "stringr", - "Version": "1.5.0", + "Version": "1.5.1", "Source": "Repository", - "Repository": "RSPM", + "Repository": "CRAN", "Requirements": [ "R", "cli", @@ -1617,7 +1629,7 @@ "stringi", "vctrs" ], - "Hash": "671a4d384ae9d32fc47a14e98bfa3dc8" + "Hash": "960e2ae9e09656611e0b8214ad543207" }, "sys": { "Package": "sys", @@ -1628,20 +1640,20 @@ }, "systemfonts": { "Package": "systemfonts", - "Version": "1.0.4", + "Version": "1.0.6", "Source": "Repository", - "Repository": "RSPM", + "Repository": "CRAN", "Requirements": [ "R", "cpp11" ], - "Hash": "90b28393209827327de889f49935140a" + "Hash": "6d538cff441f0f1f36db2209ac7495ac" }, "testthat": { "Package": "testthat", - "Version": "3.1.8", + "Version": "3.2.1", "Source": "Repository", - "Repository": "RSPM", + "Repository": "CRAN", "Requirements": [ "R", "R6", @@ -1650,7 +1662,6 @@ "cli", "desc", "digest", - "ellipsis", "evaluate", "jsonlite", "lifecycle", @@ -1665,7 +1676,7 @@ "waldo", "withr" ], - "Hash": "e0eded5dd915510f8e0d6e6277506203" + "Hash": "4767a686ebe986e6cb01d075b3f09729" }, "tibble": { "Package": "tibble", @@ -1688,9 +1699,9 @@ }, "tidyr": { "Package": "tidyr", - "Version": "1.3.0", + "Version": "1.3.1", "Source": "Repository", - "Repository": "RSPM", + "Repository": "CRAN", "Requirements": [ "R", "cli", @@ -1707,13 +1718,13 @@ "utils", "vctrs" ], - "Hash": "e47debdc7ce599b070c8e78e8ac0cfcf" + "Hash": "915fb7ce036c22a6a33b5a8adb712eb1" }, "tidyselect": { "Package": "tidyselect", - "Version": "1.2.0", + "Version": "1.2.1", "Source": "Repository", - "Repository": "RSPM", + "Repository": "CRAN", "Requirements": [ "R", "cli", @@ -1723,13 +1734,13 @@ "vctrs", "withr" ], - "Hash": "79540e5fcd9e0435af547d885f184fd5" + "Hash": "829f27b9c4919c16b593794a6344d6c0" }, "tidytree": { "Package": "tidytree", - "Version": "0.4.2", + "Version": "0.4.6", "Source": "Repository", - "Repository": "RSPM", + "Repository": "CRAN", "Requirements": [ "R", "ape", @@ -1745,51 +1756,51 @@ "tidyselect", "yulab.utils" ], - "Hash": "6f2eb34d95db945d4dd022b0811e28db" + "Hash": "a700d295c0eff82fbce42eac067bb89d" }, "timechange": { "Package": "timechange", - "Version": "0.2.0", + "Version": "0.3.0", "Source": "Repository", - "Repository": "RSPM", + "Repository": "CRAN", "Requirements": [ "R", "cpp11" ], - "Hash": "8548b44f79a35ba1791308b61e6012d7" + "Hash": "c5f3c201b931cd6474d17d8700ccb1c8" }, "tinytex": { "Package": "tinytex", - "Version": "0.45", + "Version": "0.49", "Source": "Repository", - "Repository": "RSPM", + "Repository": "CRAN", "Requirements": [ "xfun" ], - "Hash": "e4e357f28c2edff493936b6cb30c3d65" + "Hash": "5ac22900ae0f386e54f1c307eca7d843" }, "treeio": { "Package": "treeio", - "Version": "1.24.3", + "Version": "1.26.0", "Source": "Bioconductor", "git_url": "https://git.bioconductor.org/packages/treeio", - "git_branch": "RELEASE_3_17", - "git_last_commit": "132fb4d", - "git_last_commit_date": "2023-07-24", + "git_branch": "RELEASE_3_18", + "git_last_commit": "cce8f0a", + "git_last_commit_date": "2023-10-24", "Requirements": [ "R", "ape", - "cli", "dplyr", "jsonlite", "magrittr", "methods", "rlang", + "stats", "tibble", "tidytree", "utils" ], - "Hash": "c8c8efbcec2f1512d6079af62b0f112b" + "Hash": "a09203806aa0bc49965563ca7016620e" }, "tzdb": { "Package": "tzdb", @@ -1804,9 +1815,9 @@ }, "usethis": { "Package": "usethis", - "Version": "2.1.6", + "Version": "2.2.3", "Source": "Repository", - "Repository": "RSPM", + "Repository": "CRAN", "Requirements": [ "R", "cli", @@ -1831,39 +1842,33 @@ "withr", "yaml" ], - "Hash": "a67a22c201832b12c036cc059f1d137d" + "Hash": "d524fd42c517035027f866064417d7e6" }, "utf8": { "Package": "utf8", - "Version": "1.2.3", + "Version": "1.2.4", "Source": "Repository", - "Repository": "RSPM", + "Repository": "CRAN", "Requirements": [ "R" ], - "Hash": "1fe17157424bb09c48a8b3b550c753bc" + "Hash": "62b65c52671e6665f803ff02954446e9" }, "uuid": { "Package": "uuid", - "Version": "1.1-0", + "Version": "1.2-0", "Source": "Repository", - "Repository": "RSPM", + "Repository": "CRAN", "Requirements": [ "R" ], - "Hash": "f1cb46c157d080b729159d407be83496" + "Hash": "303c19bfd970bece872f93a824e323d9" }, "vctrs": { "Package": "vctrs", - "Version": "0.6.2", + "Version": "0.6.5", "Source": "Repository", - "Repository": "RSPM", - "RemoteType": "standard", - "RemotePkgRef": "vctrs", - "RemoteRef": "vctrs", - "RemoteRepos": "https://packagemanager.rstudio.com/all/latest", - "RemotePkgPlatform": "source", - "RemoteSha": "0.6.2", + "Repository": "CRAN", "Requirements": [ "R", "cli", @@ -1871,7 +1876,7 @@ "lifecycle", "rlang" ], - "Hash": "a745bda7aff4734c17294bb41d4e4607" + "Hash": "c03fa420630029418f7e6da3667aac4a" }, "viridisLite": { "Package": "viridisLite", @@ -1885,9 +1890,9 @@ }, "vroom": { "Package": "vroom", - "Version": "1.6.3", + "Version": "1.6.5", "Source": "Repository", - "Repository": "RSPM", + "Repository": "CRAN", "Requirements": [ "R", "bit64", @@ -1907,14 +1912,15 @@ "vctrs", "withr" ], - "Hash": "8318e64ffb3a70e652494017ec455561" + "Hash": "390f9315bc0025be03012054103d227c" }, "waldo": { "Package": "waldo", - "Version": "0.5.1", + "Version": "0.5.2", "Source": "Repository", - "Repository": "RSPM", + "Repository": "CRAN", "Requirements": [ + "R", "cli", "diffobj", "fansi", @@ -1924,7 +1930,7 @@ "rlang", "tibble" ], - "Hash": "2c993415154cdb94649d99ae138ff5e5" + "Hash": "c7d3fd6d29ab077cbac8f0e2751449e6" }, "websocket": { "Package": "websocket", @@ -1948,27 +1954,27 @@ }, "withr": { "Package": "withr", - "Version": "2.5.0", + "Version": "3.0.0", "Source": "Repository", - "Repository": "RSPM", + "Repository": "CRAN", "Requirements": [ "R", "grDevices", - "graphics", - "stats" + "graphics" ], - "Hash": "c0e49a9760983e81e55cdd9be92e7182" + "Hash": "d31b6c62c10dcf11ec530ca6b0dd5d35" }, "xfun": { "Package": "xfun", - "Version": "0.39", + "Version": "0.42", "Source": "Repository", - "Repository": "RSPM", + "Repository": "CRAN", "Requirements": [ + "grDevices", "stats", "tools" ], - "Hash": "8f56e9acb54fb525e66464d57ab58bcb" + "Hash": "fd1349170df31f7a10bd98b0189e85af" }, "xtable": { "Package": "xtable", @@ -1984,28 +1990,34 @@ }, "yaml": { "Package": "yaml", - "Version": "2.3.7", + "Version": "2.3.8", "Source": "Repository", - "Repository": "RSPM", - "Hash": "0d0056cc5383fbc240ccd0cb584bf436" + "Repository": "CRAN", + "Hash": "29240487a071f535f5e5d5a323b7afbd" }, "yulab.utils": { "Package": "yulab.utils", - "Version": "0.0.6", + "Version": "0.1.4", "Source": "Repository", - "Repository": "RSPM", + "Repository": "CRAN", "Requirements": [ + "cli", + "digest", + "fs", + "memoise", + "rlang", "stats", + "tools", "utils" ], - "Hash": "0d0b7cc6da5efc21f07f6b8d966a9cc1" + "Hash": "60ee2aaa179dc282e9fa7367bad76e89" }, "zip": { "Package": "zip", - "Version": "2.3.0", + "Version": "2.3.1", "Source": "Repository", - "Repository": "RSPM", - "Hash": "d98c94dacb7e0efcf83b0a133a705504" + "Repository": "CRAN", + "Hash": "fcc4bd8e6da2d2011eb64a5e5cc685ab" } } } diff --git a/renv/activate.R b/renv/activate.R index a8fdc32..96e1809 100644 --- a/renv/activate.R +++ b/renv/activate.R @@ -2,11 +2,27 @@ local({ # the requested version of renv - version <- "0.17.3" + version <- ..version.. + attr(version, "sha") <- ..sha.. # the project directory project <- getwd() + # use start-up diagnostics if enabled + diagnostics <- Sys.getenv("RENV_STARTUP_DIAGNOSTICS", unset = "FALSE") + if (diagnostics) { + start <- Sys.time() + profile <- tempfile("renv-startup-", fileext = ".Rprof") + utils::Rprof(profile) + on.exit({ + utils::Rprof(NULL) + elapsed <- signif(difftime(Sys.time(), start, units = "auto"), digits = 2L) + writeLines(sprintf("- renv took %s to run the autoloader.", format(elapsed))) + writeLines(sprintf("- Profile: %s", profile)) + print(utils::summaryRprof(profile)) + }, add = TRUE) + } + # figure out whether the autoloader is enabled enabled <- local({ @@ -15,6 +31,14 @@ local({ if (!is.null(override)) return(override) + # if we're being run in a context where R_LIBS is already set, + # don't load -- presumably we're being run as a sub-process and + # the parent process has already set up library paths for us + rcmd <- Sys.getenv("R_CMD", unset = NA) + rlibs <- Sys.getenv("R_LIBS", unset = NA) + if (!is.na(rlibs) && !is.na(rcmd)) + return(FALSE) + # next, check environment variables # TODO: prefer using the configuration one in the future envvars <- c( @@ -34,9 +58,22 @@ local({ }) - if (!enabled) + # bail if we're not enabled + if (!enabled) { + + # if we're not enabled, we might still need to manually load + # the user profile here + profile <- Sys.getenv("R_PROFILE_USER", unset = "~/.Rprofile") + if (file.exists(profile)) { + cfg <- Sys.getenv("RENV_CONFIG_USER_PROFILE", unset = "TRUE") + if (tolower(cfg) %in% c("true", "t", "1")) + sys.source(profile, envir = globalenv()) + } + return(FALSE) + } + # avoid recursion if (identical(getOption("renv.autoloader.running"), TRUE)) { warning("ignoring recursive attempt to run renv autoloader") @@ -60,25 +97,75 @@ local({ # load bootstrap tools `%||%` <- function(x, y) { - if (is.environment(x) || length(x)) x else y + if (is.null(x)) y else x } - `%??%` <- function(x, y) { - if (is.null(x)) y else x + catf <- function(fmt, ..., appendLF = TRUE) { + + quiet <- getOption("renv.bootstrap.quiet", default = FALSE) + if (quiet) + return(invisible()) + + msg <- sprintf(fmt, ...) + cat(msg, file = stdout(), sep = if (appendLF) "\n" else "") + + invisible(msg) + + } + + header <- function(label, + ..., + prefix = "#", + suffix = "-", + n = min(getOption("width"), 78)) + { + label <- sprintf(label, ...) + n <- max(n - nchar(label) - nchar(prefix) - 2L, 8L) + if (n <= 0) + return(paste(prefix, label)) + + tail <- paste(rep.int(suffix, n), collapse = "") + paste0(prefix, " ", label, " ", tail) + + } + + startswith <- function(string, prefix) { + substring(string, 1, nchar(prefix)) == prefix } bootstrap <- function(version, library) { + friendly <- renv_bootstrap_version_friendly(version) + section <- header(sprintf("Bootstrapping renv %s", friendly)) + catf(section) + # attempt to download renv - tarball <- tryCatch(renv_bootstrap_download(version), error = identity) - if (inherits(tarball, "error")) - stop("failed to download renv ", version) + catf("- Downloading renv ... ", appendLF = FALSE) + withCallingHandlers( + tarball <- renv_bootstrap_download(version), + error = function(err) { + catf("FAILED") + stop("failed to download:\n", conditionMessage(err)) + } + ) + catf("OK") + on.exit(unlink(tarball), add = TRUE) # now attempt to install - status <- tryCatch(renv_bootstrap_install(version, tarball, library), error = identity) - if (inherits(status, "error")) - stop("failed to install renv ", version) + catf("- Installing renv ... ", appendLF = FALSE) + withCallingHandlers( + status <- renv_bootstrap_install(version, tarball, library), + error = function(err) { + catf("FAILED") + stop("failed to install:\n", conditionMessage(err)) + } + ) + catf("OK") + + # add empty line to break up bootstrapping from normal output + catf("") + return(invisible()) } renv_bootstrap_tests_running <- function() { @@ -108,13 +195,6 @@ local({ if (!inherits(repos, "error") && length(repos)) return(repos) - # if we're testing, re-use the test repositories - if (renv_bootstrap_tests_running()) { - repos <- getOption("renv.tests.repos") - if (!is.null(repos)) - return(repos) - } - # retrieve current repos repos <- getOption("repos") @@ -158,33 +238,34 @@ local({ renv_bootstrap_download <- function(version) { - # if the renv version number has 4 components, assume it must - # be retrieved via github - nv <- numeric_version(version) - components <- unclass(nv)[[1]] - - # if this appears to be a development version of 'renv', we'll - # try to restore from github - dev <- length(components) == 4L - - # begin collecting different methods for finding renv - methods <- c( - renv_bootstrap_download_tarball, - if (dev) - renv_bootstrap_download_github - else c( - renv_bootstrap_download_cran_latest, - renv_bootstrap_download_cran_archive + sha <- attr(version, "sha", exact = TRUE) + + methods <- if (!is.null(sha)) { + + # attempting to bootstrap a development version of renv + c( + function() renv_bootstrap_download_tarball(sha), + function() renv_bootstrap_download_github(sha) ) - ) + + } else { + + # attempting to bootstrap a release version of renv + c( + function() renv_bootstrap_download_tarball(version), + function() renv_bootstrap_download_cran_latest(version), + function() renv_bootstrap_download_cran_archive(version) + ) + + } for (method in methods) { - path <- tryCatch(method(version), error = identity) + path <- tryCatch(method(), error = identity) if (is.character(path) && file.exists(path)) return(path) } - stop("failed to download renv ", version) + stop("All download methods failed") } @@ -248,8 +329,6 @@ local({ type <- spec$type repos <- spec$repos - message("* Downloading renv ", version, " ... ", appendLF = FALSE) - baseurl <- utils::contrib.url(repos = repos, type = type) ext <- if (identical(type, "source")) ".tar.gz" @@ -266,13 +345,10 @@ local({ condition = identity ) - if (inherits(status, "condition")) { - message("FAILED") + if (inherits(status, "condition")) return(FALSE) - } # report success and return - message("OK (downloaded ", type, ")") destfile } @@ -329,8 +405,6 @@ local({ urls <- file.path(repos, "src/contrib/Archive/renv", name) destfile <- file.path(tempdir(), name) - message("* Downloading renv ", version, " ... ", appendLF = FALSE) - for (url in urls) { status <- tryCatch( @@ -338,14 +412,11 @@ local({ condition = identity ) - if (identical(status, 0L)) { - message("OK") + if (identical(status, 0L)) return(destfile) - } } - message("FAILED") return(FALSE) } @@ -368,7 +439,7 @@ local({ if (!file.exists(tarball)) { # let the user know we weren't able to honour their request - fmt <- "* RENV_BOOTSTRAP_TARBALL is set (%s) but does not exist." + fmt <- "- RENV_BOOTSTRAP_TARBALL is set (%s) but does not exist." msg <- sprintf(fmt, tarball) warning(msg) @@ -377,10 +448,7 @@ local({ } - fmt <- "* Bootstrapping with tarball at path '%s'." - msg <- sprintf(fmt, tarball) - message(msg) - + catf("- Using local tarball '%s'.", tarball) tarball } @@ -407,8 +475,6 @@ local({ on.exit(do.call(base::options, saved), add = TRUE) } - message("* Downloading renv ", version, " from GitHub ... ", appendLF = FALSE) - url <- file.path("https://api.github.com/repos/rstudio/renv/tarball", version) name <- sprintf("renv_%s.tar.gz", version) destfile <- file.path(tempdir(), name) @@ -418,26 +484,105 @@ local({ condition = identity ) - if (!identical(status, 0L)) { - message("FAILED") + if (!identical(status, 0L)) return(FALSE) - } - message("OK") + renv_bootstrap_download_augment(destfile) + return(destfile) } + # Add Sha to DESCRIPTION. This is stop gap until #890, after which we + # can use renv::install() to fully capture metadata. + renv_bootstrap_download_augment <- function(destfile) { + sha <- renv_bootstrap_git_extract_sha1_tar(destfile) + if (is.null(sha)) { + return() + } + + # Untar + tempdir <- tempfile("renv-github-") + on.exit(unlink(tempdir, recursive = TRUE), add = TRUE) + untar(destfile, exdir = tempdir) + pkgdir <- dir(tempdir, full.names = TRUE)[[1]] + + # Modify description + desc_path <- file.path(pkgdir, "DESCRIPTION") + desc_lines <- readLines(desc_path) + remotes_fields <- c( + "RemoteType: github", + "RemoteHost: api.github.com", + "RemoteRepo: renv", + "RemoteUsername: rstudio", + "RemotePkgRef: rstudio/renv", + paste("RemoteRef: ", sha), + paste("RemoteSha: ", sha) + ) + writeLines(c(desc_lines[desc_lines != ""], remotes_fields), con = desc_path) + + # Re-tar + local({ + old <- setwd(tempdir) + on.exit(setwd(old), add = TRUE) + + tar(destfile, compression = "gzip") + }) + invisible() + } + + # Extract the commit hash from a git archive. Git archives include the SHA1 + # hash as the comment field of the tarball pax extended header + # (see https://www.kernel.org/pub/software/scm/git/docs/git-archive.html) + # For GitHub archives this should be the first header after the default one + # (512 byte) header. + renv_bootstrap_git_extract_sha1_tar <- function(bundle) { + + # open the bundle for reading + # We use gzcon for everything because (from ?gzcon) + # > Reading from a connection which does not supply a 'gzip' magic + # > header is equivalent to reading from the original connection + conn <- gzcon(file(bundle, open = "rb", raw = TRUE)) + on.exit(close(conn)) + + # The default pax header is 512 bytes long and the first pax extended header + # with the comment should be 51 bytes long + # `52 comment=` (11 chars) + 40 byte SHA1 hash + len <- 0x200 + 0x33 + res <- rawToChar(readBin(conn, "raw", n = len)[0x201:len]) + + if (grepl("^52 comment=", res)) { + sub("52 comment=", "", res) + } else { + NULL + } + } + renv_bootstrap_install <- function(version, tarball, library) { # attempt to install it into project library - message("* Installing renv ", version, " ... ", appendLF = FALSE) dir.create(library, showWarnings = FALSE, recursive = TRUE) + output <- renv_bootstrap_install_impl(library, tarball) + + # check for successful install + status <- attr(output, "status") + if (is.null(status) || identical(status, 0L)) + return(status) + + # an error occurred; report it + header <- "installation of renv failed" + lines <- paste(rep.int("=", nchar(header)), collapse = "") + text <- paste(c(header, lines, output), collapse = "\n") + stop(text) + + } + + renv_bootstrap_install_impl <- function(library, tarball) { # invoke using system2 so we can capture and report output bin <- R.home("bin") exe <- if (Sys.info()[["sysname"]] == "Windows") "R.exe" else "R" - r <- file.path(bin, exe) + R <- file.path(bin, exe) args <- c( "--vanilla", "CMD", "INSTALL", "--no-multiarch", @@ -445,19 +590,7 @@ local({ shQuote(path.expand(tarball)) ) - output <- system2(r, args, stdout = TRUE, stderr = TRUE) - message("Done!") - - # check for successful install - status <- attr(output, "status") - if (is.numeric(status) && !identical(status, 0L)) { - header <- "Error installing renv:" - lines <- paste(rep.int("=", nchar(header)), collapse = "") - text <- c(header, lines, output) - writeLines(text, con = stderr()) - } - - status + system2(R, args, stdout = TRUE, stderr = TRUE) } @@ -667,34 +800,62 @@ local({ } - renv_bootstrap_validate_version <- function(version) { + renv_bootstrap_validate_version <- function(version, description = NULL) { - loadedversion <- utils::packageDescription("renv", fields = "Version") - if (version == loadedversion) - return(TRUE) + # resolve description file + # + # avoid passing lib.loc to `packageDescription()` below, since R will + # use the loaded version of the package by default anyhow. note that + # this function should only be called after 'renv' is loaded + # https://github.com/rstudio/renv/issues/1625 + description <- description %||% packageDescription("renv") - # assume four-component versions are from GitHub; - # three-component versions are from CRAN - components <- strsplit(loadedversion, "[.-]")[[1]] - remote <- if (length(components) == 4L) - paste("rstudio/renv", loadedversion, sep = "@") + # check whether requested version 'version' matches loaded version of renv + sha <- attr(version, "sha", exact = TRUE) + valid <- if (!is.null(sha)) + renv_bootstrap_validate_version_dev(sha, description) else - paste("renv", loadedversion, sep = "@") + renv_bootstrap_validate_version_release(version, description) + + if (valid) + return(TRUE) + + # the loaded version of renv doesn't match the requested version; + # give the user instructions on how to proceed + remote <- if (!is.null(description[["RemoteSha"]])) { + paste("rstudio/renv", description[["RemoteSha"]], sep = "@") + } else { + paste("renv", description[["Version"]], sep = "@") + } + + # display both loaded version + sha if available + friendly <- renv_bootstrap_version_friendly( + version = description[["Version"]], + sha = description[["RemoteSha"]] + ) fmt <- paste( "renv %1$s was loaded from project library, but this project is configured to use renv %2$s.", - "Use `renv::record(\"%3$s\")` to record renv %1$s in the lockfile.", - "Use `renv::restore(packages = \"renv\")` to install renv %2$s into the project library.", + "- Use `renv::record(\"%3$s\")` to record renv %1$s in the lockfile.", + "- Use `renv::restore(packages = \"renv\")` to install renv %2$s into the project library.", sep = "\n" ) - - msg <- sprintf(fmt, loadedversion, version, remote) - warning(msg, call. = FALSE) + catf(fmt, friendly, renv_bootstrap_version_friendly(version), remote) FALSE } + renv_bootstrap_validate_version_dev <- function(version, description) { + expected <- description[["RemoteSha"]] + is.character(expected) && startswith(expected, version) + } + + renv_bootstrap_validate_version_release <- function(version, description) { + expected <- description[["Version"]] + is.character(expected) && identical(expected, version) + } + renv_bootstrap_hash_text <- function(text) { hashfile <- tempfile("renv-hash-") @@ -718,7 +879,7 @@ local({ hooks <- getHook("renv::autoload") for (hook in hooks) if (is.function(hook)) - tryCatch(hook(), error = warning) + tryCatch(hook(), error = warnify) # load the project renv::load(project) @@ -859,6 +1020,40 @@ local({ } + renv_bootstrap_version_friendly <- function(version, shafmt = NULL, sha = NULL) { + sha <- sha %||% attr(version, "sha", exact = TRUE) + parts <- c(version, sprintf(shafmt %||% " [sha: %s]", substring(sha, 1L, 7L))) + paste(parts, collapse = "") + } + + renv_bootstrap_exec <- function(project, libpath, version) { + if (!renv_bootstrap_load(project, libpath, version)) + renv_bootstrap_run(version, libpath) + } + + renv_bootstrap_run <- function(version, libpath) { + + # perform bootstrap + bootstrap(version, libpath) + + # exit early if we're just testing bootstrap + if (!is.na(Sys.getenv("RENV_BOOTSTRAP_INSTALL_ONLY", unset = NA))) + return(TRUE) + + # try again to load + if (requireNamespace("renv", lib.loc = libpath, quietly = TRUE)) { + return(renv::load(project = getwd())) + } + + # failed to download or load renv; warn the user + msg <- c( + "Failed to find an renv installation: the project will not be loaded.", + "Use `renv::activate()` to re-initialize the project." + ) + + warning(paste(msg, collapse = "\n"), call. = FALSE) + + } renv_json_read <- function(file = NULL, text = NULL) { @@ -867,7 +1062,7 @@ local({ # if jsonlite is loaded, use that instead if ("jsonlite" %in% loadedNamespaces()) { - json <- catch(renv_json_read_jsonlite(file, text)) + json <- tryCatch(renv_json_read_jsonlite(file, text), error = identity) if (!inherits(json, "error")) return(json) @@ -876,7 +1071,7 @@ local({ } # otherwise, fall back to the default JSON reader - json <- catch(renv_json_read_default(file, text)) + json <- tryCatch(renv_json_read_default(file, text), error = identity) if (!inherits(json, "error")) return(json) @@ -889,14 +1084,14 @@ local({ } renv_json_read_jsonlite <- function(file = NULL, text = NULL) { - text <- paste(text %||% read(file), collapse = "\n") + text <- paste(text %||% readLines(file, warn = FALSE), collapse = "\n") jsonlite::fromJSON(txt = text, simplifyVector = FALSE) } renv_json_read_default <- function(file = NULL, text = NULL) { # find strings in the JSON - text <- paste(text %||% read(file), collapse = "\n") + text <- paste(text %||% readLines(file, warn = FALSE), collapse = "\n") pattern <- '["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]' locs <- gregexpr(pattern, text, perl = TRUE)[[1]] @@ -944,14 +1139,14 @@ local({ map <- as.list(map) # remap strings in object - remapped <- renv_json_remap(json, map) + remapped <- renv_json_read_remap(json, map) # evaluate eval(remapped, envir = baseenv()) } - renv_json_remap <- function(json, map) { + renv_json_read_remap <- function(json, map) { # fix names if (!is.null(names(json))) { @@ -978,7 +1173,7 @@ local({ # recurse if (is.recursive(json)) { for (i in seq_along(json)) { - json[i] <- list(renv_json_remap(json[[i]], map)) + json[i] <- list(renv_json_read_remap(json[[i]], map)) } } @@ -998,35 +1193,9 @@ local({ # construct full libpath libpath <- file.path(root, prefix) - # attempt to load - if (renv_bootstrap_load(project, libpath, version)) - return(TRUE) - - # load failed; inform user we're about to bootstrap - prefix <- paste("# Bootstrapping renv", version) - postfix <- paste(rep.int("-", 77L - nchar(prefix)), collapse = "") - header <- paste(prefix, postfix) - message(header) - - # perform bootstrap - bootstrap(version, libpath) - - # exit early if we're just testing bootstrap - if (!is.na(Sys.getenv("RENV_BOOTSTRAP_INSTALL_ONLY", unset = NA))) - return(TRUE) - - # try again to load - if (requireNamespace("renv", lib.loc = libpath, quietly = TRUE)) { - message("* Successfully installed and loaded renv ", version, ".") - return(renv::load()) - } - - # failed to download or load renv; warn the user - msg <- c( - "Failed to find an renv installation: the project will not be loaded.", - "Use `renv::activate()` to re-initialize the project." - ) + # run bootstrap code + renv_bootstrap_exec(project, libpath, version) - warning(paste(msg, collapse = "\n"), call. = FALSE) + invisible() }) diff --git a/renv/settings.json b/renv/settings.json new file mode 100644 index 0000000..a3f6796 --- /dev/null +++ b/renv/settings.json @@ -0,0 +1,17 @@ +{ + "bioconductor.version": "3.18", + "external.libraries": [], + "ignored.packages": [], + "package.dependency.fields": [ + "Imports", + "Depends", + "LinkingTo" + ], + "r.version": null, + "snapshot.type": "implicit", + "use.cache": true, + "vcs.ignore.cellar": true, + "vcs.ignore.library": true, + "vcs.ignore.local": true, + "vcs.manage.ignores": true +} From 3b817632405bf1bff4adadf6c789a487ffed5dd8 Mon Sep 17 00:00:00 2001 From: Russ Hyde Date: Thu, 14 Mar 2024 14:31:54 +0000 Subject: [PATCH 05/68] fix renv activate script for renv >=v1 --- renv/activate.R | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/renv/activate.R b/renv/activate.R index 96e1809..9b2e7f1 100644 --- a/renv/activate.R +++ b/renv/activate.R @@ -2,8 +2,8 @@ local({ # the requested version of renv - version <- ..version.. - attr(version, "sha") <- ..sha.. + version <- "1.0.5" + attr(version, "sha") <- NULL # the project directory project <- getwd() From f19dae2271b4263a4dc45dec418085615ce1f3ec Mon Sep 17 00:00:00 2001 From: Russ Hyde Date: Thu, 14 Mar 2024 14:54:09 +0000 Subject: [PATCH 06/68] refac: use {styler} to fix some indentation lints --- R/app_server.R | 43 ++++---- R/app_ui.R | 163 ++++++++++++++++--------------- R/module_plots.R | 26 ++--- R/module_rds.R | 25 ++--- R/module_tables.R | 33 ++++--- R/place_title_logo.R | 6 +- R/utils.R | 40 +++++--- R/zzz.R | 6 +- tests/testthat/test-shinytest2.R | 3 +- 9 files changed, 190 insertions(+), 155 deletions(-) diff --git a/R/app_server.R b/R/app_server.R index 4fbbee7..f6c4318 100644 --- a/R/app_server.R +++ b/R/app_server.R @@ -83,30 +83,34 @@ app_server = function(input, output, session) { shiny::bindCache(input$widgetChoice) -# Mutation colouring ------------------------------------------------------ + # Mutation colouring ------------------------------------------------------ # disable dropdown unless mutation treeview shiny::observe({ choice = ifelse(input$widgetChoice != "", input$widgetChoice, "") # toggle mutation dropdown - shinyjs::toggleElement(id = "mutationChoice", - condition = choice == "tree-mutations.rds") + shinyjs::toggleElement( + id = "mutationChoice", + condition = choice == "tree-mutations.rds" + ) # toggle sequence dropdown - shinyjs::toggleElement(id = "sequenceChoice", - condition = choice == "tree-sequences.rds") + shinyjs::toggleElement( + id = "sequenceChoice", + condition = choice == "tree-sequences.rds" + ) # select input for sequences if (choice == "tree-sequences.rds") { avail_seqs = data.table::as.data.table(available_sequences(data_dir)) names(avail_seqs) = "Sequences" - shiny::updateSelectInput(inputId = "sequenceChoice", - choices = avail_seqs - ) + shiny::updateSelectInput( + inputId = "sequenceChoice", + choices = avail_seqs + ) } }) # get selected nodes from mutation choice shiny::observeEvent(input$mutationChoice, { - nodeChoice = selected_mut_nodes(input$mutationChoice, data_dir) # the 'node' column contains integers that define the IDs for graph-nodes in the htmlwidget @@ -124,11 +128,10 @@ app_server = function(input, output, session) { ) }) -# Sequence colouring ------------------------------------------------------ + # Sequence colouring ------------------------------------------------------ # get selected nodes from sequence choice shiny::observeEvent(input$sequenceChoice, { - nodeChoice = selected_seq_nodes(input$sequenceChoice, data_dir) # the 'node' column contains integers that define the IDs for graph-nodes in the htmlwidget @@ -146,15 +149,17 @@ app_server = function(input, output, session) { ) }) -# Get click --------------------------------------------------------------- + # Get click --------------------------------------------------------------- # get selected cluster id based on widget choice selected_cluster_id = shiny::reactive({ shiny::req(input$widgetChoice) shiny::req(input$treeview_selected) - get_selected_cluster_id(widgetChoice = input$widgetChoice, - treeviewSelected = utils::tail(input$treeview_selected, 1), - data_dir = data_dir) + get_selected_cluster_id( + widgetChoice = input$widgetChoice, + treeviewSelected = utils::tail(input$treeview_selected, 1), + data_dir = data_dir + ) }) %>% shiny::bindCache(input$widgetChoice, input$treeview_selected) @@ -169,9 +174,10 @@ app_server = function(input, output, session) { shiny::req(input$widgetChoice) fname = stringr::str_replace(input$widgetChoice, ".rds", ".md") shiny::includeMarkdown(system.file("app", "www", "content", "treeview", - fname, - package = "tfpbrowser", - mustWork = TRUE)) + fname, + package = "tfpbrowser", + mustWork = TRUE + )) }) # Tables Tab -------------------------------------------------------------- @@ -194,5 +200,4 @@ app_server = function(input, output, session) { cluster_choice = selected_cluster_id, data_dir = data_dir ) - } # end server function diff --git a/R/app_ui.R b/R/app_ui.R index a9451f2..3c99238 100644 --- a/R/app_ui.R +++ b/R/app_ui.R @@ -6,100 +6,106 @@ app_ui = function(request) { data_dir <- get_data_dir() shiny::tagList( - shinyjs::useShinyjs(), shinybrowser::detect(), - shiny::navbarPage( # title title = place_title_logo(), - header = add_ext_resources(data_dir), # theme - theme = bslib::bs_theme(version = 4, - bootswatch = "minty", - bg = "#EBEEEE", - fg = "#002147", - primary = "#003E74", - secondary = "#9D9D9D"), + theme = bslib::bs_theme( + version = 4, + bootswatch = "minty", + bg = "#EBEEEE", + fg = "#002147", + primary = "#003E74", + secondary = "#9D9D9D" + ), # Input widgets shiny::tabPanel( title = "Data", - shiny::fluidRow( - shiny::column(12, - # use details and summary to create expandable section - htmltools::tags$details( - # preview of expandable section - htmltools::tags$summary("Cluster statistics (click to expand)"), - - shiny::br(), - - # text to print choice - shiny::textOutput("select_text"), - shiny::br(), - - # output options - shiny::tabsetPanel(id = "plot_tabs", - - # Tables tab - tablesUI("table1"), - - # Plots tab - plotsUI("plot1"), - - # RDS tab - rdsUI("rds1") - - ) - ) + shiny::column( + 12, + # use details and summary to create expandable section + htmltools::tags$details( + # preview of expandable section + htmltools::tags$summary("Cluster statistics (click to expand)"), + shiny::br(), + + # text to print choice + shiny::textOutput("select_text"), + shiny::br(), + + # output options + shiny::tabsetPanel( + id = "plot_tabs", + + # Tables tab + tablesUI("table1"), + + # Plots tab + plotsUI("plot1"), + + # RDS tab + rdsUI("rds1") + ) + ) ) ), # end fluid row # Bottom row - show tree (static html output from tfpscanner) shiny::fluidRow( shiny::column(12, - id="view-container", - shiny::div(id="view-selection", - htmltools::tags$details( - id="sidebar-toggle", - open="open", - `aria-role`="button", - `aria-label`="Toggle sidebar visibility", - htmltools::tags$summary( - shiny::span(">>"), - shiny::span("<<") - ) - ), - # choose type of treeview - shiny::selectInput(inputId = "widgetChoice", - label = "View", - choices = c("None" = ""), - selectize = FALSE), - - # choose type of mutation - shiny::selectInput(inputId = "mutationChoice", - label = "Mutation", - choices = character(0), - selectize = FALSE), - - # choose type of sequence - shiny::selectInput(inputId = "sequenceChoice", - label = "Sequence", - choices = NULL, - selectize = FALSE), + id = "view-container", + shiny::div( + id = "view-selection", + htmltools::tags$details( + id = "sidebar-toggle", + open = "open", + `aria-role` = "button", + `aria-label` = "Toggle sidebar visibility", + htmltools::tags$summary( + shiny::span(">>"), + shiny::span("<<") + ) + ), + # choose type of treeview + shiny::selectInput( + inputId = "widgetChoice", + label = "View", + choices = c("None" = ""), + selectize = FALSE + ), + + # choose type of mutation + shiny::selectInput( + inputId = "mutationChoice", + label = "Mutation", + choices = character(0), + selectize = FALSE + ), + + # choose type of sequence + shiny::selectInput( + inputId = "sequenceChoice", + label = "Sequence", + choices = NULL, + selectize = FALSE + ), ), - shiny::div(id="view-graphic", - # markdown files to add description - shiny::uiOutput("tree_md_files"), - - # show treeview widget - shiny::wellPanel( - ggiraph::girafeOutput("treeview"), - style = "background: white; height: 1800px;", - ), - shiny::br() + shiny::div( + id = "view-graphic", + # markdown files to add description + shiny::uiOutput("tree_md_files"), + + # show treeview widget + shiny::wellPanel( + ggiraph::girafeOutput("treeview"), + style = "background: white; height: 1800px;", + ), + shiny::br() ) ) ) # end fluid row @@ -109,11 +115,10 @@ app_ui = function(request) { shiny::tabPanel( title = "About", shiny::includeMarkdown(system.file("app", "www", "content", "about.md", - package = "tfpbrowser", - mustWork = TRUE)) + package = "tfpbrowser", + mustWork = TRUE + )) ) - ) # end navbar page ) # end tag list - } diff --git a/R/module_plots.R b/R/module_plots.R index 849feac..b9dafb6 100644 --- a/R/module_plots.R +++ b/R/module_plots.R @@ -6,11 +6,12 @@ plotsUI = function(id) { ns = shiny::NS(id) # Plots tab panel - downloader_tab_panel(title = "Plots", - chooser_id = ns("plot_type"), - download_button_id = ns("download_plot"), - panel = display_panel(shiny::uiOutput(ns("display_plot")))) - + downloader_tab_panel( + title = "Plots", + chooser_id = ns("plot_type"), + download_button_id = ns("download_plot"), + panel = display_panel(shiny::uiOutput(ns("display_plot"))) + ) } #' Plots tab Server @@ -35,17 +36,20 @@ plotsServer = function(id, cluster_choice, data_dir) { # drop down for plots shiny::observeEvent(all_files(), { - all_images = filter_by_filetype(filenames = all_files(), - filetypes = c("png", "PNG")) + all_images = filter_by_filetype( + filenames = all_files(), + filetypes = c("png", "PNG") + ) if (length(all_images) != 0) { shinyjs::enable("plot_type") } else { shinyjs::disable("plot_type") } shiny::updateSelectInput(session, - "plot_type", - label = "Select plot type:", - choices = all_images) + "plot_type", + label = "Select plot type:", + choices = all_images + ) }) # the path to the plot, from the server's perspective @@ -101,7 +105,5 @@ plotsServer = function(id, cluster_choice, data_dir) { file.copy(plot_file(), file) } ) - }) - } diff --git a/R/module_rds.R b/R/module_rds.R index 438fd54..d2553dc 100644 --- a/R/module_rds.R +++ b/R/module_rds.R @@ -5,10 +5,12 @@ rdsUI = function(id) { ns = shiny::NS(id) # RDS files tab panel - downloader_tab_panel(title = "RDS Files", - chooser_id = ns("rds_type"), - download_button_id = ns("download_rds"), - panel = display_panel(shiny::uiOutput(ns("display_rds")))) + downloader_tab_panel( + title = "RDS Files", + chooser_id = ns("rds_type"), + download_button_id = ns("download_rds"), + panel = display_panel(shiny::uiOutput(ns("display_rds"))) + ) } #' rds tab Server @@ -33,17 +35,20 @@ rdsServer = function(id, cluster_choice, data_dir) { # drop down for rds shiny::observeEvent(all_files(), { - all_rds = filter_by_filetype(filenames = all_files(), - filetypes = c("rds", "RDS")) + all_rds = filter_by_filetype( + filenames = all_files(), + filetypes = c("rds", "RDS") + ) if (length(all_rds) != 0) { shinyjs::enable("rds_type") } else { shinyjs::disable("rds_type") } shiny::updateSelectInput(session, - "rds_type", - label = "Select RDS file:", - choices = all_rds) + "rds_type", + label = "Select RDS file:", + choices = all_rds + ) }) # get rds file @@ -95,7 +100,5 @@ rdsServer = function(id, cluster_choice, data_dir) { file.copy(rds_file(), file) } ) - }) - } diff --git a/R/module_tables.R b/R/module_tables.R index 063ef6f..34b72ec 100644 --- a/R/module_tables.R +++ b/R/module_tables.R @@ -6,10 +6,12 @@ tablesUI = function(id) { ns = shiny::NS(id) # Tables tab panel - downloader_tab_panel(title = "Tables", - chooser_id = ns("table_type"), - download_button_id = ns("download_table"), - panel = display_panel(reactable::reactableOutput(ns("display_table")))) + downloader_tab_panel( + title = "Tables", + chooser_id = ns("table_type"), + download_button_id = ns("download_table"), + panel = display_panel(reactable::reactableOutput(ns("display_table"))) + ) } #' Tables tab Server @@ -34,17 +36,20 @@ tablesServer = function(id, cluster_choice, data_dir) { # drop down for tables shiny::observeEvent(all_files(), { - all_tables = filter_by_filetype(filenames = all_files(), - filetypes = c("csv", "CSV")) + all_tables = filter_by_filetype( + filenames = all_files(), + filetypes = c("csv", "CSV") + ) if (length(all_tables) != 0) { shinyjs::enable("table_type") } else { shinyjs::disable("table_type") } shiny::updateSelectInput(session, - "table_type", - label = "Select table type:", - choices = all_tables) + "table_type", + label = "Select table type:", + choices = all_tables + ) }) # get table file path @@ -72,10 +77,11 @@ tablesServer = function(id, cluster_choice, data_dir) { table_to_display = suppressMessages(readr::read_csv(table_file())) table_to_display_nice = reformat_table(table_to_display) reactable::reactable(table_to_display_nice, - striped = TRUE, - defaultPageSize = 8, - wrap = FALSE, - height = 400) + striped = TRUE, + defaultPageSize = 8, + wrap = FALSE, + height = 400 + ) } else { shiny::p("No tables available.", style = "color: red; text-align: left") } @@ -99,6 +105,5 @@ tablesServer = function(id, cluster_choice, data_dir) { file.copy(table_file(), file) } ) - }) } diff --git a/R/place_title_logo.R b/R/place_title_logo.R index bcd61b6..b47946d 100644 --- a/R/place_title_logo.R +++ b/R/place_title_logo.R @@ -7,8 +7,10 @@ place_title_logo = function() { shiny::img( src = "www/logo.png", contentType = "image/png", - height = 80, width = 100), - "tfpbrowser") + height = 80, width = 100 + ), + "tfpbrowser" + ) return(title) } diff --git a/R/utils.R b/R/utils.R index a1e145b..c0f6dd1 100644 --- a/R/utils.R +++ b/R/utils.R @@ -7,9 +7,13 @@ available_treeview = function(data_dir) { file.path(data_dir, "treeview"), pattern = "\\.rds$" ) - all_trees = factor(all_trees, - c(stringr::str_subset(all_trees, "tree"), - stringr::str_subset(all_trees, "sina"))) + all_trees = factor( + all_trees, + c( + stringr::str_subset(all_trees, "tree"), + stringr::str_subset(all_trees, "sina") + ) + ) all_trees = as.character(sort(all_trees)) names(all_trees) = all_trees %>% stringr::str_replace_all("_|-|\\.rds", " ") %>% @@ -73,8 +77,9 @@ get_unique_mutations = function(filename) { get_all_clusters = function(filename) { all_files = list.files(filename) has_no_dot = stringr::str_detect(all_files, - pattern = "\\.", - negate = TRUE) + pattern = "\\.", + negate = TRUE + ) all_clusters = all_files[which(has_no_dot)] return(all_clusters) } @@ -128,7 +133,9 @@ filter_by_filetype = function(filenames, filetypes) { file_names = stringr::str_to_title( stringr::str_replace_all( - gsub("\\..*", "", matching_files), "_", " ")) + gsub("\\..*", "", matching_files), "_", " " + ) + ) names(matching_files) = file_names return(matching_files) @@ -149,14 +156,16 @@ downloader_tab_panel = function(title, shiny::fluidRow( # drop down menu to select dataset shiny::column(3, - align = "center", - shiny::selectInput(chooser_id, - label = "Select type:", - choices = NULL, - selected = NULL), - shiny::br(), - shiny::downloadButton(download_button_id, - label = "Download") + align = "center", + shiny::selectInput(chooser_id, + label = "Select type:", + choices = NULL, + selected = NULL + ), + shiny::br(), + shiny::downloadButton(download_button_id, + label = "Download" + ) ), # display data shiny::column(9, align = "center", panel) @@ -188,7 +197,8 @@ get_selected_cluster_id = function(widgetChoice, filepath = file.path(data_dir, "treeview", "node_lookup", filename) # load look up ids = readr::read_csv(filepath, - col_types = list(readr::col_double(), readr::col_double())) + col_types = list(readr::col_double(), readr::col_double()) + ) selected_cluster = as.numeric(ids[which(ids$data_id == treeviewSelected), 2]) return(selected_cluster) } diff --git a/R/zzz.R b/R/zzz.R index ee0aab5..d198a6b 100644 --- a/R/zzz.R +++ b/R/zzz.R @@ -7,7 +7,9 @@ .onload = function(...) { shiny::addResourcePath( "www", - system.file("www", package = "tfpbrowser", - mustWork = TRUE) + system.file("www", + package = "tfpbrowser", + mustWork = TRUE + ) ) } diff --git a/tests/testthat/test-shinytest2.R b/tests/testthat/test-shinytest2.R index 373c5b8..c9d436d 100644 --- a/tests/testthat/test-shinytest2.R +++ b/tests/testthat/test-shinytest2.R @@ -2,7 +2,8 @@ test_that("tfpbrowser app initial values are consistent", { if (interactive()) { shiny_app = tfpbrowser::run_app() app = shinytest2::AppDriver$new(shiny_app, - name = "tfpbrowser") + name = "tfpbrowser" + ) navbar_tab_items = app$get_text(".nav-item") observed_navbar_tab_items = stringr::str_squish(navbar_tab_items) expected_navbar_tab_items = c("Data", "About", "Tables", "Plots", "RDS Files") From 5fca50c77f9baccae728ca7bcf957ca7b6a6762c Mon Sep 17 00:00:00 2001 From: Russ Hyde Date: Thu, 14 Mar 2024 14:55:19 +0000 Subject: [PATCH 07/68] refac: fix some undesirable op lints --- R/app_ui.R | 2 +- R/config.R | 2 +- R/module_plots.R | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/R/app_ui.R b/R/app_ui.R index 3c99238..b705e93 100644 --- a/R/app_ui.R +++ b/R/app_ui.R @@ -3,7 +3,7 @@ #' @param request Internal parameter for `{shiny}`. #' @noRd app_ui = function(request) { - data_dir <- get_data_dir() + data_dir = get_data_dir() shiny::tagList( shinyjs::useShinyjs(), diff --git a/R/config.R b/R/config.R index 3598039..9217639 100644 --- a/R/config.R +++ b/R/config.R @@ -7,7 +7,7 @@ #' #' @return Scalar string. The data-directory for use in the app. -get_data_dir <- function() { +get_data_dir = function() { Sys.getenv( "APP_DATA_DIR", system.file("app", "www", "data", package = "tfpbrowser") diff --git a/R/module_plots.R b/R/module_plots.R index b9dafb6..596332d 100644 --- a/R/module_plots.R +++ b/R/module_plots.R @@ -64,7 +64,7 @@ plotsServer = function(id, cluster_choice, data_dir) { plot_url = shiny::reactive({ shiny::req(plot_file()) - plot_subpath <- fs::path_rel(plot_file(), data_dir) + plot_subpath = fs::path_rel(plot_file(), data_dir) glue::glue("data/{plot_subpath}") }) From d4f223213a00c7eacd26863bf53de90623015455 Mon Sep 17 00:00:00 2001 From: Russ Hyde Date: Thu, 14 Mar 2024 15:02:20 +0000 Subject: [PATCH 08/68] chore: bump roxygen2 version --- DESCRIPTION | 2 +- man/tfpbrowser.Rd | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index 12ae5bc..d89144f 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -36,4 +36,4 @@ Suggests: Encoding: UTF-8 LazyData: true Roxygen: list(markdown = TRUE) -RoxygenNote: 7.2.3 +RoxygenNote: 7.3.1 diff --git a/man/tfpbrowser.Rd b/man/tfpbrowser.Rd index 77e3982..ba25644 100644 --- a/man/tfpbrowser.Rd +++ b/man/tfpbrowser.Rd @@ -2,8 +2,8 @@ % Please edit documentation in R/tfpbrowser.R \docType{package} \name{tfpbrowser} -\alias{tfpbrowser} \alias{tfpbrowser-package} +\alias{tfpbrowser} \title{\code{{tfpbrowser}} package} \description{ An R package to build a Shiny application to explore {tfpscanner} outputs. From 61dc14c96d51842f974d20f2344eb5decf8eb596 Mon Sep 17 00:00:00 2001 From: Russ Hyde Date: Thu, 14 Mar 2024 14:47:19 +0000 Subject: [PATCH 09/68] refac: style the code that imports the about.md page --- R/app_ui.R | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/R/app_ui.R b/R/app_ui.R index b705e93..50bd4b7 100644 --- a/R/app_ui.R +++ b/R/app_ui.R @@ -114,10 +114,9 @@ app_ui = function(request) { # about page shiny::tabPanel( title = "About", - shiny::includeMarkdown(system.file("app", "www", "content", "about.md", - package = "tfpbrowser", - mustWork = TRUE - )) + shiny::includeMarkdown( + system.file("app", "www", "content", "about.md", package = "tfpbrowser", mustWork = TRUE) + ) ) ) # end navbar page ) # end tag list From f5267d1406e0329d3cdc4c3f50e62933509be706 Mon Sep 17 00:00:00 2001 From: Russ Hyde Date: Thu, 14 Mar 2024 14:47:52 +0000 Subject: [PATCH 10/68] feat: add 'About' page text based on Kieran's word document --- inst/app/www/content/about.md | 98 ++++++++++++++++++++++++++++++++++- 1 file changed, 97 insertions(+), 1 deletion(-) diff --git a/inst/app/www/content/about.md b/inst/app/www/content/about.md index bf3bbf4..731e728 100644 --- a/inst/app/www/content/about.md +++ b/inst/app/www/content/about.md @@ -1 +1,97 @@ -This is a page containing some information about the project. +# tfpbrowser + +## About + +The Transmission Fitness Polymorphism Browser (tfpbrowser) is a visualisation tool for output from +the Transmission Fitness Polymorphism Scanner (tfpscanner)[1-3]. Information on the visualisation +options can be found below, while details regarding installation of the tfpbrowser package and the +source code can be found at +[https://github.com/mrc-ide/tfpbrowser](https://github.com/mrc-ide/tfpbrowser). + +Six different visualisations can be accessed by selecting from the ‘View’ dropdown menu on the +left-hand side. If the ‘View’ option is not visible, then the left-hand side menu may need to be +expanded by clicking on the double arrow button. + +### Tree Visualisations + +There are four different tree visualisation options. These are described below, but a number of +characteristics are common to each tree visualisation: + +- The size of the circles (for internal nodes) and triangles (tips) indicates the size of the +cluster that they represent. +- The colour indicates a particular characteristic of the cluster. +- On the right-hand side of each tree visualisation, the colouring of the bars indicates whether a +genotype (for which a key mutation is labelled) is present (true) or absent (false) in the clusters +at the same vertical level. +- Further information on each cluster can be viewed by hovering over it with the mouse cursor. + +The four tree visualisation options in the ‘View’ menu are: + +#### Tree Clock Outlier + +Displays a phylogenetic tree with clusters colour coded (key at the top) according to the value of +the molecular clock outlier (MCO) statistic. This is computed by the tfpscanner as a measure of the +degree to which evolutionary rates differed in the lineage leading to a phylogenetic cluster. +Root-to-tip regression is used to predict the divergence of tips in a cluster and contrasts this +with divergence within an ancestral clade including the given cluster. This predicted divergence is +then compared to the true divergence of the cluster. + +#### Tree Logistic Growth Rate + +Displays a phylogenetic tree with clusters colour coded (key at the top) according to the value of +the logistic growth rate. This is computed in the tfpscanner using one of two different methods +depending on the level of model support calculated using the Akaike Information Criterion (AIC) and +‘relative likelihood’. The first method uses a generalised linear model (GLM) to calculate the log +odds of a sample being from a cluster of interest compared to a geographically and temporally +matched sample weighted by prevalence, and multiplied by the estimated mean generation time to +calculate the relative LGR per generation for each cluster of interest. The second method uses a +generalised additive model (GAM) combined with a Gaussian process model to identify changes in +growth rates over time. + +#### Tree Mutations + +This visualisation has a ‘Mutation’ menu from which to select a particular mutation to be +highlighted in the phylogenetic tree. Clusters containing the mutation selected will be coloured red +in the phylogenetic tree while clusters not containing this mutation will be grey. + +#### Tree Sequences + +This visualisation has a ‘Sequence’ menu from which to select a particular sequence ID. Clusters +containing this sequence will be coloured red in the phylogenetic tree while those not containing it +will be grey. + +### Scatter plots + +The molecular clock outlier and logistic growth rate statistics can also be viewed in scatter plots: + +#### Sina Clock Outlier + +Displays a scatter plot of the molecular clock outlier statistic value for each phylogenetic cluster +on the y-axis and the lineage and/or mutation is stratified along the x-axis. The plot marker +colours indicate the lineage and/or mutation and the size indicates the cluster size, both as per +the legend on the right-hand side of the plot. _See ‘Tree Clock Outlier’ above for details of the +molecular clock outlier statistic_. + +#### Sina Logistic Growth Rate + +Displays a scatter plot of the logistic growth rate value for each phylogenetic cluster on the +y-axis and the lineage and/or mutation is stratified along the x-axis. The circle colours indicate +the lineage and/or mutation and the size indicates the cluster size, both as per the legend on the +right-hand side of the plot. _See ‘Tree Logistic Growth Rate’ above for details of this statistic_. + +### Downloads + +Tables, plots and .rds files can also be downloaded by clicking on the ‘Cluster statistics’ tab and +selecting the relevant option. + +### References + +[1] Volz EM, Boyd O. Transmission Fitness Polymorphism Scanner. Available from: +https://github.com/mrc-ide/tfpscanner + +[2] Volz EM. Fitness, growth and transmissibility of SARS-CoV-2 genetic variants. Nat Rev Genet +2023. https://doi.org/10.1038/s41576-023-00610-z + +[3] Drake KO, Boyd O, Franceschi VB, Colquhoun RM, Ellaby NAF, Volz EM. Phylogenomic early warning +signals for SARS-CoV-2 epidemic waves. eBioMedicine 2024: 100. +https://doi.org/10.1016/j.ebiom.2023.104939 From bd18837dc56e29aff7becac95e861f839423ff25 Mon Sep 17 00:00:00 2001 From: Russ Hyde Date: Fri, 23 Feb 2024 15:44:30 +0000 Subject: [PATCH 11/68] refac: extract function for cluster-stats UI --- R/app_ui.R | 28 +--------------------------- R/module_cluster_stats.R | 28 ++++++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 27 deletions(-) create mode 100644 R/module_cluster_stats.R diff --git a/R/app_ui.R b/R/app_ui.R index 50bd4b7..80188f9 100644 --- a/R/app_ui.R +++ b/R/app_ui.R @@ -26,33 +26,7 @@ app_ui = function(request) { shiny::tabPanel( title = "Data", shiny::fluidRow( - shiny::column( - 12, - # use details and summary to create expandable section - htmltools::tags$details( - # preview of expandable section - htmltools::tags$summary("Cluster statistics (click to expand)"), - shiny::br(), - - # text to print choice - shiny::textOutput("select_text"), - shiny::br(), - - # output options - shiny::tabsetPanel( - id = "plot_tabs", - - # Tables tab - tablesUI("table1"), - - # Plots tab - plotsUI("plot1"), - - # RDS tab - rdsUI("rds1") - ) - ) - ) + shiny::column(12, clusterStatsUI(id = NULL)) ), # end fluid row # Bottom row - show tree (static html output from tfpscanner) diff --git a/R/module_cluster_stats.R b/R/module_cluster_stats.R new file mode 100644 index 0000000..ac82940 --- /dev/null +++ b/R/module_cluster_stats.R @@ -0,0 +1,28 @@ +clusterStatsUI = function(id) { + ns = NS(id) + + # use details and summary to create expandable section + htmltools::tags$details( + # preview of expandable section + htmltools::tags$summary("Cluster statistics (click to expand)"), + shiny::br(), + + # text to print choice + shiny::textOutput(ns("select_text")), + shiny::br(), + + # output options + shiny::tabsetPanel( + id = ns("plot_tabs"), + + # Tables tab + tablesUI(ns("table1")), + + # Plots tab + plotsUI(ns("plot1")), + + # RDS tab + rdsUI(ns("rds1")) + ) + ) +} From 7e0b3fa5a38c0cd93dd62a298115faecdf7e32d4 Mon Sep 17 00:00:00 2001 From: Russ Hyde Date: Fri, 23 Feb 2024 17:23:08 +0000 Subject: [PATCH 12/68] refac: separate content for cluster-stats from details/summary --- R/module_cluster_stats.R | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/R/module_cluster_stats.R b/R/module_cluster_stats.R index ac82940..f7b13d2 100644 --- a/R/module_cluster_stats.R +++ b/R/module_cluster_stats.R @@ -1,10 +1,7 @@ clusterStatsUI = function(id) { ns = NS(id) - # use details and summary to create expandable section - htmltools::tags$details( - # preview of expandable section - htmltools::tags$summary("Cluster statistics (click to expand)"), + box_content = tagList( shiny::br(), # text to print choice @@ -15,14 +12,17 @@ clusterStatsUI = function(id) { shiny::tabsetPanel( id = ns("plot_tabs"), - # Tables tab + # Tabs for "Tables", "Plots" and "RDS" tablesUI(ns("table1")), - - # Plots tab plotsUI(ns("plot1")), - - # RDS tab rdsUI(ns("rds1")) ) ) + + # use details and summary to create expandable section + htmltools::tags$details( + # preview of expandable section + htmltools::tags$summary("Cluster statistics (click to expand)"), + box_content + ) } From c174ad9f11eaedc0e2a1b40d283d8705ac12a71c Mon Sep 17 00:00:00 2001 From: Russ Hyde Date: Fri, 23 Feb 2024 16:55:12 +0000 Subject: [PATCH 13/68] bump to bootstrap v5 --- R/app_ui.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/app_ui.R b/R/app_ui.R index 80188f9..f60fae9 100644 --- a/R/app_ui.R +++ b/R/app_ui.R @@ -14,7 +14,7 @@ app_ui = function(request) { header = add_ext_resources(data_dir), # theme theme = bslib::bs_theme( - version = 4, + version = 5, bootswatch = "minty", bg = "#EBEEEE", fg = "#002147", From 7e7576074184f48629452e7a24dc9fd1791916ea Mon Sep 17 00:00:00 2001 From: Russ Hyde Date: Fri, 23 Feb 2024 17:46:19 +0000 Subject: [PATCH 14/68] add help icon alongside details/summary for cluster-statistics --- R/module_cluster_stats.R | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/R/module_cluster_stats.R b/R/module_cluster_stats.R index f7b13d2..df369e3 100644 --- a/R/module_cluster_stats.R +++ b/R/module_cluster_stats.R @@ -20,9 +20,18 @@ clusterStatsUI = function(id) { ) # use details and summary to create expandable section - htmltools::tags$details( - # preview of expandable section - htmltools::tags$summary("Cluster statistics (click to expand)"), - box_content + fluidRow( + column( + width = 11, + htmltools::tags$details( + # preview of expandable section + htmltools::tags$summary("Cluster statistics (click to expand)"), + box_content + ) + ), + column( + width = 1, + bslib::popover(bsicons::bs_icon("question-circle"), "Help!") + ) ) } From 67ed1a078317333f3f9ba6fbf4bad4bc0639ab11 Mon Sep 17 00:00:00 2001 From: Russ Hyde Date: Fri, 15 Mar 2024 14:10:43 +0000 Subject: [PATCH 15/68] feat: add help text to help icon for 'Cluster Statistics' panel --- R/module_cluster_stats.R | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/R/module_cluster_stats.R b/R/module_cluster_stats.R index df369e3..962b888 100644 --- a/R/module_cluster_stats.R +++ b/R/module_cluster_stats.R @@ -19,6 +19,11 @@ clusterStatsUI = function(id) { ) ) + help_text <- tags$p( + "The 'Cluster statistics' panel can be used to view or download data about a cluster.", + "First, select a cluster by clicking on a node in one of the tree-views or scatter plots." + ) + # use details and summary to create expandable section fluidRow( column( @@ -31,7 +36,7 @@ clusterStatsUI = function(id) { ), column( width = 1, - bslib::popover(bsicons::bs_icon("question-circle"), "Help!") + bslib::popover(bsicons::bs_icon("question-circle"), help_text) ) ) } From 6f2542dae5583678fb02c63095dce50f6ac9e620 Mon Sep 17 00:00:00 2001 From: Russ Hyde Date: Tue, 19 Mar 2024 10:55:37 +0000 Subject: [PATCH 16/68] feat: add a help icon inside the cluster-statistics accordion summary --- R/module_cluster_stats.R | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/R/module_cluster_stats.R b/R/module_cluster_stats.R index 962b888..fa8f811 100644 --- a/R/module_cluster_stats.R +++ b/R/module_cluster_stats.R @@ -19,24 +19,24 @@ clusterStatsUI = function(id) { ) ) - help_text <- tags$p( + # Help icon for the cluster-statistics panel + # - Clicking this icon does not lead to the underlying accordion_panel being expanded + help_text = tags$p( "The 'Cluster statistics' panel can be used to view or download data about a cluster.", "First, select a cluster by clicking on a node in one of the tree-views or scatter plots." ) + help_popover = bsicons::bs_icon("question-circle") %>% + bslib::popover(help_text) %>% + htmltools::tagAppendAttributes(`data-bs-toggle` = "collapse", `data-bs-target` = NA) - # use details and summary to create expandable section - fluidRow( - column( - width = 11, - htmltools::tags$details( - # preview of expandable section - htmltools::tags$summary("Cluster statistics (click to expand)"), - box_content - ) - ), - column( - width = 1, - bslib::popover(bsicons::bs_icon("question-circle"), help_text) + # Expandable panel containing the cluster-statistics details + bslib::accordion( + id = "cluster_stats_accordion", + open = FALSE, + bslib::accordion_panel( + title = "Cluster statistics (click to expand)", + box_content, + icon = help_popover ) ) } From 50f872d35d3084923262b330c43e08ea8cecf4a5 Mon Sep 17 00:00:00 2001 From: Russ Hyde Date: Thu, 21 Mar 2024 10:26:00 +0000 Subject: [PATCH 17/68] add margin/padding around accordion (using the values for the outdated summary/details) --- inst/app/www/tfpbrowser-style.css | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/inst/app/www/tfpbrowser-style.css b/inst/app/www/tfpbrowser-style.css index c81da6e..b9a1188 100644 --- a/inst/app/www/tfpbrowser-style.css +++ b/inst/app/www/tfpbrowser-style.css @@ -1,9 +1,8 @@ -summary { - background: #d6d6d6; +.accordion-item { padding: 1em; } -details { +.accordion { margin-bottom: 2rem; } From e0172f5a69ff6621184ba8996e1b745cc2e65b11 Mon Sep 17 00:00:00 2001 From: Russ Hyde Date: Thu, 21 Mar 2024 10:38:19 +0000 Subject: [PATCH 18/68] increase help-icon size from 1em to 1.5em --- R/module_cluster_stats.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/module_cluster_stats.R b/R/module_cluster_stats.R index fa8f811..d4f667f 100644 --- a/R/module_cluster_stats.R +++ b/R/module_cluster_stats.R @@ -25,7 +25,7 @@ clusterStatsUI = function(id) { "The 'Cluster statistics' panel can be used to view or download data about a cluster.", "First, select a cluster by clicking on a node in one of the tree-views or scatter plots." ) - help_popover = bsicons::bs_icon("question-circle") %>% + help_popover = bsicons::bs_icon("question-circle", size = "1.5em") %>% bslib::popover(help_text) %>% htmltools::tagAppendAttributes(`data-bs-toggle` = "collapse", `data-bs-target` = NA) From a9dc079295f63b3149be014308f8bdc9a8e71026 Mon Sep 17 00:00:00 2001 From: Russ Hyde Date: Thu, 21 Mar 2024 11:29:48 +0000 Subject: [PATCH 19/68] namespace some shiny functions --- R/module_cluster_stats.R | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/R/module_cluster_stats.R b/R/module_cluster_stats.R index d4f667f..7a48091 100644 --- a/R/module_cluster_stats.R +++ b/R/module_cluster_stats.R @@ -1,7 +1,7 @@ clusterStatsUI = function(id) { - ns = NS(id) + ns = shiny::NS(id) - box_content = tagList( + box_content = shiny::tagList( shiny::br(), # text to print choice @@ -21,7 +21,7 @@ clusterStatsUI = function(id) { # Help icon for the cluster-statistics panel # - Clicking this icon does not lead to the underlying accordion_panel being expanded - help_text = tags$p( + help_text = shiny::tags$p( "The 'Cluster statistics' panel can be used to view or download data about a cluster.", "First, select a cluster by clicking on a node in one of the tree-views or scatter plots." ) From 36d45fc045504366a815c4a2586207bd0699b7e2 Mon Sep 17 00:00:00 2001 From: Russ Hyde Date: Thu, 21 Mar 2024 11:39:39 +0000 Subject: [PATCH 20/68] env: add bsicons to DESCRIPTION --- DESCRIPTION | 1 + 1 file changed, 1 insertion(+) diff --git a/DESCRIPTION b/DESCRIPTION index d89144f..89c47da 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -9,6 +9,7 @@ License: MIT + file LICENSE Depends: R (>= 4.0.0) Imports: + bsicons, bslib, data.table, dplyr, From 26b188454242a2d3e206412f38b6c645bdddf31d Mon Sep 17 00:00:00 2001 From: Russ Hyde Date: Tue, 16 Apr 2024 13:50:30 +0100 Subject: [PATCH 21/68] env: bump the version of {renv} --- renv.lock | 5 ++++- renv/activate.R | 43 +++++++++++++++++++++++++++++++------------ 2 files changed, 35 insertions(+), 13 deletions(-) diff --git a/renv.lock b/renv.lock index c510492..f14bce5 100644 --- a/renv.lock +++ b/renv.lock @@ -1401,7 +1401,10 @@ }, "renv": { "Package": "renv", - "Version": "1.0.5", + "Version": "1.0.7", + "OS_type": null, + "NeedsCompilation": "no", + "Repository": "CRAN", "Source": "Repository" }, "rlang": { diff --git a/renv/activate.R b/renv/activate.R index 9b2e7f1..d13f993 100644 --- a/renv/activate.R +++ b/renv/activate.R @@ -2,11 +2,13 @@ local({ # the requested version of renv - version <- "1.0.5" + version <- "1.0.7" attr(version, "sha") <- NULL # the project directory - project <- getwd() + project <- Sys.getenv("RENV_PROJECT") + if (!nzchar(project)) + project <- getwd() # use start-up diagnostics if enabled diagnostics <- Sys.getenv("RENV_STARTUP_DIAGNOSTICS", unset = "FALSE") @@ -129,6 +131,21 @@ local({ } + heredoc <- function(text, leave = 0) { + + # remove leading, trailing whitespace + trimmed <- gsub("^\\s*\\n|\\n\\s*$", "", text) + + # split into lines + lines <- strsplit(trimmed, "\n", fixed = TRUE)[[1L]] + + # compute common indent + indent <- regexpr("[^[:space:]]", lines) + common <- min(setdiff(indent, -1L)) - leave + paste(substring(lines, common), collapse = "\n") + + } + startswith <- function(string, prefix) { substring(string, 1, nchar(prefix)) == prefix } @@ -631,6 +648,9 @@ local({ # if the user has requested an automatic prefix, generate it auto <- Sys.getenv("RENV_PATHS_PREFIX_AUTO", unset = NA) + if (is.na(auto) && getRversion() >= "4.4.0") + auto <- "TRUE" + if (auto %in% c("TRUE", "True", "true", "1")) return(renv_bootstrap_platform_prefix_auto()) @@ -822,24 +842,23 @@ local({ # the loaded version of renv doesn't match the requested version; # give the user instructions on how to proceed - remote <- if (!is.null(description[["RemoteSha"]])) { + dev <- identical(description[["RemoteType"]], "github") + remote <- if (dev) paste("rstudio/renv", description[["RemoteSha"]], sep = "@") - } else { + else paste("renv", description[["Version"]], sep = "@") - } # display both loaded version + sha if available friendly <- renv_bootstrap_version_friendly( version = description[["Version"]], - sha = description[["RemoteSha"]] + sha = if (dev) description[["RemoteSha"]] ) - fmt <- paste( - "renv %1$s was loaded from project library, but this project is configured to use renv %2$s.", - "- Use `renv::record(\"%3$s\")` to record renv %1$s in the lockfile.", - "- Use `renv::restore(packages = \"renv\")` to install renv %2$s into the project library.", - sep = "\n" - ) + fmt <- heredoc(" + renv %1$s was loaded from project library, but this project is configured to use renv %2$s. + - Use `renv::record(\"%3$s\")` to record renv %1$s in the lockfile. + - Use `renv::restore(packages = \"renv\")` to install renv %2$s into the project library. + ") catf(fmt, friendly, renv_bootstrap_version_friendly(version), remote) FALSE From 78d5e7a4147964ca99c55a2c36cb47306895cafc Mon Sep 17 00:00:00 2001 From: Russ Hyde Date: Tue, 16 Apr 2024 14:05:16 +0100 Subject: [PATCH 22/68] env: add {bsicons} to renv.lock --- renv.lock | 46 ++++++++++++++++++++++------------------------ 1 file changed, 22 insertions(+), 24 deletions(-) diff --git a/renv.lock b/renv.lock index f14bce5..325cd49 100644 --- a/renv.lock +++ b/renv.lock @@ -225,6 +225,20 @@ ], "Hash": "68bd2b066e1fe780bbf62fc8bcc36de3" }, + "bsicons": { + "Package": "bsicons", + "Version": "0.1.2", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "cli", + "htmltools", + "rlang", + "utils" + ], + "Hash": "d8f892fbd94d0b9b1f6d688b05b8633c" + }, "bslib": { "Package": "bslib", "Version": "0.6.1", @@ -772,13 +786,7 @@ "Package": "highr", "Version": "0.10", "Source": "Repository", - "Repository": "RSPM", - "RemoteType": "standard", - "RemotePkgRef": "highr", - "RemoteRef": "highr", - "RemoteRepos": "https://packagemanager.rstudio.com/all/latest", - "RemotePkgPlatform": "source", - "RemoteSha": "0.10", + "Repository": "https://packagemanager.rstudio.com/all/latest", "Requirements": [ "R", "xfun" @@ -904,13 +912,7 @@ "Package": "janitor", "Version": "2.2.0", "Source": "Repository", - "Repository": "RSPM", - "RemoteType": "standard", - "RemotePkgRef": "janitor", - "RemoteRef": "janitor", - "RemoteRepos": "https://packagemanager.rstudio.com/all/latest", - "RemotePkgPlatform": "source", - "RemoteSha": "2.2.0", + "Repository": "https://packagemanager.rstudio.com/all/latest", "Requirements": [ "R", "dplyr", @@ -1402,10 +1404,12 @@ "renv": { "Package": "renv", "Version": "1.0.7", - "OS_type": null, - "NeedsCompilation": "no", + "Source": "Repository", "Repository": "CRAN", - "Source": "Repository" + "Requirements": [ + "utils" + ], + "Hash": "397b7b2a265bc5a7a06852524dabae20" }, "rlang": { "Package": "rlang", @@ -1530,13 +1534,7 @@ "Package": "shinybrowser", "Version": "1.0.0", "Source": "Repository", - "Repository": "RSPM", - "RemoteType": "standard", - "RemotePkgRef": "shinybrowser", - "RemoteRef": "shinybrowser", - "RemoteRepos": "https://packagemanager.rstudio.com/all/latest", - "RemotePkgPlatform": "source", - "RemoteSha": "1.0.0", + "Repository": "https://packagemanager.rstudio.com/all/latest", "Requirements": [ "R", "shiny" From c3dc4a2a2eeef3ce473e9519d667c23ba4bb8ce1 Mon Sep 17 00:00:00 2001 From: Russ Hyde Date: Tue, 16 Apr 2024 16:04:40 +0100 Subject: [PATCH 23/68] fix: get_data_dir() should return fully-specified path for data directory --- R/config.R | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/R/config.R b/R/config.R index 9217639..c904513 100644 --- a/R/config.R +++ b/R/config.R @@ -8,8 +8,10 @@ #' @return Scalar string. The data-directory for use in the app. get_data_dir = function() { - Sys.getenv( + path = Sys.getenv( "APP_DATA_DIR", system.file("app", "www", "data", package = "tfpbrowser") ) + + normalizePath(path) } From 34151f47910f3b221fdf5811b0abd6de1c116e1b Mon Sep 17 00:00:00 2001 From: Russ Hyde Date: Tue, 12 Mar 2024 15:14:56 +0000 Subject: [PATCH 24/68] [TEMP] use renv::use() to specify env for creating browser data The script just adds a small renv definition for running `tfpscanner::create_browser_data()`. It doesn't yet include argument handling for passing in the scanner environment or output directory for the data. --- scripts/create_browser_data.R | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 scripts/create_browser_data.R diff --git a/scripts/create_browser_data.R b/scripts/create_browser_data.R new file mode 100644 index 0000000..b074e9e --- /dev/null +++ b/scripts/create_browser_data.R @@ -0,0 +1,18 @@ +renv::use( + "ggplot2@3.4.0", + "igraph@1.5.0", + "ggiraph@0.8.4", + "ggtree@3.8.2", + "mrc-ide/tfpscanner@ab29cb0e2126c8792fa471ae3200e12144eaa173" +) + +message("Hello world!") + +for(pkg in c("ggplot2", "igraph", "ggiraph", "ggtree", "tfpscanner")) { + message(pkg, " version: ", packageVersion(pkg)) +} + +tfpscanner::create_browser_data( + "Some environment", + output_dir = "Some directory" +) From 4dfdd5603c8774487badae41916cdfdfbaec3fbd Mon Sep 17 00:00:00 2001 From: Russ Hyde Date: Tue, 16 Apr 2024 11:01:15 +0100 Subject: [PATCH 25/68] update version of tfpscanner used in browser-data script --- scripts/create_browser_data.R | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/scripts/create_browser_data.R b/scripts/create_browser_data.R index b074e9e..a5d4899 100644 --- a/scripts/create_browser_data.R +++ b/scripts/create_browser_data.R @@ -1,9 +1,14 @@ renv::use( + # The CRAN versions of these packages should match those used in the 'renv.lock' for tfpbrowser, + # to ensure that the figure formatting "ggplot2@3.4.0", "igraph@1.5.0", "ggiraph@0.8.4", "ggtree@3.8.2", - "mrc-ide/tfpscanner@ab29cb0e2126c8792fa471ae3200e12144eaa173" + # This is the HEAD of `jumpingrivers:draft-all-features-202403` as of 2024-04-15 + # If the commit ID is absent, this will use the latest 'master' branch + # Including the commit ID allows us to use development-versions of the 'tfpscanner' package + "mrc-ide/tfpscanner@7ee27416d69ec3eaf7e4158f38c31125b3c38c7d" ) message("Hello world!") From b0460c449b47da420d5ca79c2a3b57e1de69cba0 Mon Sep 17 00:00:00 2001 From: Russ Hyde Date: Tue, 16 Apr 2024 11:01:53 +0100 Subject: [PATCH 26/68] configure / run create_browser_data() in browser-data script --- scripts/create_browser_data.R | 40 +++++++++++++++++++++++++++++------ 1 file changed, 33 insertions(+), 7 deletions(-) diff --git a/scripts/create_browser_data.R b/scripts/create_browser_data.R index a5d4899..84d20d9 100644 --- a/scripts/create_browser_data.R +++ b/scripts/create_browser_data.R @@ -11,13 +11,39 @@ renv::use( "mrc-ide/tfpscanner@7ee27416d69ec3eaf7e4158f38c31125b3c38c7d" ) -message("Hello world!") +# User parameters +# - The scanner environment file ("path/to/scanner_output/scanner-env-YYYY-MM-DD.rds") +# - The output directory for the treeviews +# - Any non-default arguments for the `treeview()` function +env_file <- file.path() +output_dir <- file.path() +treeview_args <- list( + # branch_cols = c("logistic_growth_rate", "clock_outlier"), + # mutations = c("S:A222V", "S:Y145H", "N:Q9L", "S:E484K"), + # lineages = c("AY\\.9", "AY\\.43", "AY\\.4\\.2"), + # output_format = c("rds", "html"), + # dendrogram_colours = c("#2166ac", "#738fc0", "#afbad4", "#e8e8e8", "#e0a9a4", "#ce6964", "#b2182b"), + # heatmap_width = 0.075, + # heatmap_offset = 8, + # heatmap_lab_offset = -6, + # heatmap_fill = c(`FALSE` = "grey90", `TRUE` = "grey70") +) + +## ============================================================================================== ## + +# Arguments for `create_browser_data` +browser_args <- append( + list( + e0 = normalizePath(env_file), + output_dir = normalisePath(output_dir) + ), + treeview_args +) -for(pkg in c("ggplot2", "igraph", "ggiraph", "ggtree", "tfpscanner")) { - message(pkg, " version: ", packageVersion(pkg)) -} +stopifnot(file.exists(browser_args$e0)) +stopifnot(dir.exists(browser_args$output_dir)) -tfpscanner::create_browser_data( - "Some environment", - output_dir = "Some directory" +do.call( + tfpscanner::create_browser_data, + browser_args ) From a47a47ab2e508f93a84e63b3f878a42e1eec5e1f Mon Sep 17 00:00:00 2001 From: Russ Hyde Date: Fri, 19 Apr 2024 09:53:31 +0100 Subject: [PATCH 27/68] browser-data script outputs a message on how to use the new browser-data in the app --- scripts/create_browser_data.R | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/scripts/create_browser_data.R b/scripts/create_browser_data.R index 84d20d9..8b4e5a1 100644 --- a/scripts/create_browser_data.R +++ b/scripts/create_browser_data.R @@ -5,7 +5,7 @@ renv::use( "igraph@1.5.0", "ggiraph@0.8.4", "ggtree@3.8.2", - # This is the HEAD of `jumpingrivers:draft-all-features-202403` as of 2024-04-15 + # This is the HEAD of `jumpingrivers:dev-202403` as of 2024-04-15 # If the commit ID is absent, this will use the latest 'master' branch # Including the commit ID allows us to use development-versions of the 'tfpscanner' package "mrc-ide/tfpscanner@7ee27416d69ec3eaf7e4158f38c31125b3c38c7d" @@ -15,6 +15,8 @@ renv::use( # - The scanner environment file ("path/to/scanner_output/scanner-env-YYYY-MM-DD.rds") # - The output directory for the treeviews # - Any non-default arguments for the `treeview()` function +# +# File paths can be specified either relative to the working directory, or as absolute paths env_file <- file.path() output_dir <- file.path() treeview_args <- list( @@ -47,3 +49,15 @@ do.call( tfpscanner::create_browser_data, browser_args ) + +# =============================================================================================== ## + +app_message <- glue::glue(' +# To run the "tfpbrowser" app over this dataset, please perform the following in R: + +Sys.setenv(APP_DATA_DIR = "{output_dir}") +pkgload::load_all() +run_app() +') + +message(app_message) From ce391afb88f47013014d2edbf60c1f0b6f44f6b0 Mon Sep 17 00:00:00 2001 From: Russ Hyde Date: Fri, 19 Apr 2024 10:23:06 +0100 Subject: [PATCH 28/68] comment-wash the create_browser_data script --- scripts/create_browser_data.R | 44 +++++++++++++++++++++++++++++------ 1 file changed, 37 insertions(+), 7 deletions(-) diff --git a/scripts/create_browser_data.R b/scripts/create_browser_data.R index 8b4e5a1..be40a43 100644 --- a/scripts/create_browser_data.R +++ b/scripts/create_browser_data.R @@ -1,3 +1,26 @@ +# create_browser_data.R ----------------------------------------------------------------------- + +# To run this script for a new dataset: +# - modify the "User parameters" section below (see the comments in that section) +# - Either run it using +# - `Rscript ./scripts/create_browser_data.R` at the command line +# - or `source("./scripts/create_browser_data.R")` in R +# - Once finished, this script will explain how to use the created figures within tfpbrowser. + +# Ensure that the R session used when running this script is closed before running the app, because +# this script runs in a defined environment that doesn't contain some of the packages needed by the +# app. + +# Script environment -------------------------------------------------------------------------- + +# Here we define a running environment that is compatible with the versions of ggplot2, igraph etc +# that are used when running the app. +# +# If the renv.lock for the app is updated, the versions of the packages defined here should be +# updated to be in-sync with the renv.lock. +# +# {tfpscanner} is not directly used by the app, so it isn't present in the renv.lock for the app. + renv::use( # The CRAN versions of these packages should match those used in the 'renv.lock' for tfpbrowser, # to ensure that the figure formatting @@ -11,14 +34,17 @@ renv::use( "mrc-ide/tfpscanner@7ee27416d69ec3eaf7e4158f38c31125b3c38c7d" ) -# User parameters -# - The scanner environment file ("path/to/scanner_output/scanner-env-YYYY-MM-DD.rds") -# - The output directory for the treeviews -# - Any non-default arguments for the `treeview()` function -# +# User parameters ----------------------------------------------------------------------------- + # File paths can be specified either relative to the working directory, or as absolute paths +# +# 1) The scanner environment file ("path/to/scanner_output/scanner-env-YYYY-MM-DD.rds") env_file <- file.path() + +# 2) The output directory for the treeviews (typically the parent of the 'scanner_output' directory) output_dir <- file.path() + +# 3) Any non-default arguments for the `treeview()` function treeview_args <- list( # branch_cols = c("logistic_growth_rate", "clock_outlier"), # mutations = c("S:A222V", "S:Y145H", "N:Q9L", "S:E484K"), @@ -31,7 +57,9 @@ treeview_args <- list( # heatmap_fill = c(`FALSE` = "grey90", `TRUE` = "grey70") ) -## ============================================================================================== ## +# Create the browser data / figures ----------------------------------------------------------- + +# Please don't edit this section # Arguments for `create_browser_data` browser_args <- append( @@ -50,11 +78,13 @@ do.call( browser_args ) -# =============================================================================================== ## +# How to use the new browser data ------------------------------------------------------------- app_message <- glue::glue(' # To run the "tfpbrowser" app over this dataset, please perform the following in R: +# Start a new session first +# - the environment for this script will interfere with that used by the app Sys.setenv(APP_DATA_DIR = "{output_dir}") pkgload::load_all() run_app() From 938a71ed4fcebda574b21a8b9941a54e2c84ee05 Mon Sep 17 00:00:00 2001 From: Russ Hyde Date: Fri, 19 Apr 2024 10:28:57 +0100 Subject: [PATCH 29/68] fix: normalisePath -> normalizePath --- scripts/create_browser_data.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/create_browser_data.R b/scripts/create_browser_data.R index be40a43..e60b2fe 100644 --- a/scripts/create_browser_data.R +++ b/scripts/create_browser_data.R @@ -65,7 +65,7 @@ treeview_args <- list( browser_args <- append( list( e0 = normalizePath(env_file), - output_dir = normalisePath(output_dir) + output_dir = normalizePath(output_dir) ), treeview_args ) From 7cc51b62b353e053bbec6b889957e6ffed6db4ee Mon Sep 17 00:00:00 2001 From: Russ Hyde Date: Fri, 19 Apr 2024 10:48:31 +0100 Subject: [PATCH 30/68] temp --- scripts/create_browser_data.R | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/scripts/create_browser_data.R b/scripts/create_browser_data.R index e60b2fe..b4672dc 100644 --- a/scripts/create_browser_data.R +++ b/scripts/create_browser_data.R @@ -81,7 +81,9 @@ do.call( # How to use the new browser data ------------------------------------------------------------- app_message <- glue::glue(' -# To run the "tfpbrowser" app over this dataset, please perform the following in R: +# ================================================================================ # +# To run the "tfpbrowser" app over this dataset, please perform the following from +# the "tfpbrowser" home directory in R: # Start a new session first # - the environment for this script will interfere with that used by the app From 621352db512c642bcf6c6ddc57efd7de713f878a Mon Sep 17 00:00:00 2001 From: Russ Hyde Date: Fri, 19 Apr 2024 10:48:58 +0100 Subject: [PATCH 31/68] define {svglite} in the env for create_browser_data() --- scripts/create_browser_data.R | 2 ++ 1 file changed, 2 insertions(+) diff --git a/scripts/create_browser_data.R b/scripts/create_browser_data.R index b4672dc..482d839 100644 --- a/scripts/create_browser_data.R +++ b/scripts/create_browser_data.R @@ -28,6 +28,8 @@ renv::use( "igraph@1.5.0", "ggiraph@0.8.4", "ggtree@3.8.2", + # These packages are required implicitly by {tfpscanner}, but not by {tfpbrowser} + "svglite@2.1.3", # This is the HEAD of `jumpingrivers:dev-202403` as of 2024-04-15 # If the commit ID is absent, this will use the latest 'master' branch # Including the commit ID allows us to use development-versions of the 'tfpscanner' package From 4cc490c6cea117c81f58d36a780c664e0aa5b5fa Mon Sep 17 00:00:00 2001 From: Russ Hyde Date: Fri, 19 Apr 2024 14:51:19 +0100 Subject: [PATCH 32/68] match create-browser env to tfpbrowser env --- scripts/create_browser_data.R | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/scripts/create_browser_data.R b/scripts/create_browser_data.R index 482d839..e864c5e 100644 --- a/scripts/create_browser_data.R +++ b/scripts/create_browser_data.R @@ -24,10 +24,10 @@ renv::use( # The CRAN versions of these packages should match those used in the 'renv.lock' for tfpbrowser, # to ensure that the figure formatting - "ggplot2@3.4.0", - "igraph@1.5.0", - "ggiraph@0.8.4", - "ggtree@3.8.2", + "ggplot2@3.5.0", + # "igraph@1.5.0", + "ggiraph@0.8.9", + "ggtree@3.10.1", # These packages are required implicitly by {tfpscanner}, but not by {tfpbrowser} "svglite@2.1.3", # This is the HEAD of `jumpingrivers:dev-202403` as of 2024-04-15 From 80b1c2af69197a32deba28807d118b00ff1f3345 Mon Sep 17 00:00:00 2001 From: Russ Hyde Date: Fri, 19 Apr 2024 15:15:13 +0100 Subject: [PATCH 33/68] dynamically match the create-browser env to the renv.lock, for it's required packages --- scripts/create_browser_data.R | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/scripts/create_browser_data.R b/scripts/create_browser_data.R index e864c5e..95e565c 100644 --- a/scripts/create_browser_data.R +++ b/scripts/create_browser_data.R @@ -13,7 +13,7 @@ # Script environment -------------------------------------------------------------------------- -# Here we define a running environment that is compatible with the versions of ggplot2, igraph etc +# Here we define a running environment that is compatible with the versions of ggplot2, ggiraph etc # that are used when running the app. # # If the renv.lock for the app is updated, the versions of the packages defined here should be @@ -21,13 +21,24 @@ # # {tfpscanner} is not directly used by the app, so it isn't present in the renv.lock for the app. +tfpbrowser_env <- jsonlite::read_json("renv.lock") + +required_packages <- c("ggplot2", "ggiraph", "ggtree") +required_versions <- Map( + function(package, pkg_details) { + paste0(package, "@", pkg_details[["Version"]]) + }, + required_packages, + tfpbrowser_env[["Packages"]][required_packages] +) + renv::use( # The CRAN versions of these packages should match those used in the 'renv.lock' for tfpbrowser, # to ensure that the figure formatting - "ggplot2@3.5.0", + required_versions[["ggplot2"]], # "igraph@1.5.0", - "ggiraph@0.8.9", - "ggtree@3.10.1", + required_versions[["ggiraph"]], + required_versions[["ggtree"]], # These packages are required implicitly by {tfpscanner}, but not by {tfpbrowser} "svglite@2.1.3", # This is the HEAD of `jumpingrivers:dev-202403` as of 2024-04-15 From b3c088445a5aab165948d5f919f5a688d937fd3e Mon Sep 17 00:00:00 2001 From: Russ Hyde Date: Thu, 23 May 2024 15:35:55 +0100 Subject: [PATCH 34/68] refac: put user-modified section at start of script --- scripts/create_browser_data.R | 62 ++++++++++++++++++----------------- 1 file changed, 32 insertions(+), 30 deletions(-) diff --git a/scripts/create_browser_data.R b/scripts/create_browser_data.R index 95e565c..9f07eab 100644 --- a/scripts/create_browser_data.R +++ b/scripts/create_browser_data.R @@ -7,12 +7,35 @@ # - or `source("./scripts/create_browser_data.R")` in R # - Once finished, this script will explain how to use the created figures within tfpbrowser. -# Ensure that the R session used when running this script is closed before running the app, because -# this script runs in a defined environment that doesn't contain some of the packages needed by the -# app. +# User parameters ----------------------------------------------------------------------------- + +# File paths can be specified either relative to the working directory, or as absolute paths +# +# 1) The scanner environment file ("path/to/scanner_output/scanner-env-YYYY-MM-DD.rds") +env_file <- file.path() + +# 2) The output directory for the treeviews (typically the parent of the 'scanner_output' directory) +output_dir <- file.path() + +# 3) Any non-default arguments for the `treeview()` function +treeview_args <- list( + # branch_cols = c("logistic_growth_rate", "clock_outlier"), + # mutations = c("S:A222V", "S:Y145H", "N:Q9L", "S:E484K"), + # lineages = c("AY\\.9", "AY\\.43", "AY\\.4\\.2"), + # output_format = c("rds", "html"), + # dendrogram_colours = c("#2166ac", "#738fc0", "#afbad4", "#e8e8e8", "#e0a9a4", "#ce6964", "#b2182b"), + # heatmap_width = 0.075, + # heatmap_offset = 8, + # heatmap_lab_offset = -6, + # heatmap_fill = c(`FALSE` = "grey90", `TRUE` = "grey70") +) # Script environment -------------------------------------------------------------------------- +# Ensure that the R session used when running this script is closed before running the app, because +# this script runs in a defined environment that doesn't contain some of the packages needed by the +# app. +# # Here we define a running environment that is compatible with the versions of ggplot2, ggiraph etc # that are used when running the app. # @@ -23,7 +46,7 @@ tfpbrowser_env <- jsonlite::read_json("renv.lock") -required_packages <- c("ggplot2", "ggiraph", "ggtree") +required_packages <- c("BiocVersion", "ggplot2", "ggiraph", "ggtree") required_versions <- Map( function(package, pkg_details) { paste0(package, "@", pkg_details[["Version"]]) @@ -32,11 +55,13 @@ required_versions <- Map( tfpbrowser_env[["Packages"]][required_packages] ) +# {BiocManager} will be loaded along with {renv} when an R session is started in this repository + renv::use( - # The CRAN versions of these packages should match those used in the 'renv.lock' for tfpbrowser, - # to ensure that the figure formatting + # The versions of these packages should match those used in the 'renv.lock' for tfpbrowser, to + # ensure that the figure formatting + required_versions[["BiocVersion"]], required_versions[["ggplot2"]], - # "igraph@1.5.0", required_versions[["ggiraph"]], required_versions[["ggtree"]], # These packages are required implicitly by {tfpscanner}, but not by {tfpbrowser} @@ -47,29 +72,6 @@ renv::use( "mrc-ide/tfpscanner@7ee27416d69ec3eaf7e4158f38c31125b3c38c7d" ) -# User parameters ----------------------------------------------------------------------------- - -# File paths can be specified either relative to the working directory, or as absolute paths -# -# 1) The scanner environment file ("path/to/scanner_output/scanner-env-YYYY-MM-DD.rds") -env_file <- file.path() - -# 2) The output directory for the treeviews (typically the parent of the 'scanner_output' directory) -output_dir <- file.path() - -# 3) Any non-default arguments for the `treeview()` function -treeview_args <- list( - # branch_cols = c("logistic_growth_rate", "clock_outlier"), - # mutations = c("S:A222V", "S:Y145H", "N:Q9L", "S:E484K"), - # lineages = c("AY\\.9", "AY\\.43", "AY\\.4\\.2"), - # output_format = c("rds", "html"), - # dendrogram_colours = c("#2166ac", "#738fc0", "#afbad4", "#e8e8e8", "#e0a9a4", "#ce6964", "#b2182b"), - # heatmap_width = 0.075, - # heatmap_offset = 8, - # heatmap_lab_offset = -6, - # heatmap_fill = c(`FALSE` = "grey90", `TRUE` = "grey70") -) - # Create the browser data / figures ----------------------------------------------------------- # Please don't edit this section From 7af7313d7a59dcb5bc549883bd6f0d7e23bfc8d2 Mon Sep 17 00:00:00 2001 From: Russ Hyde Date: Thu, 23 May 2024 15:40:15 +0100 Subject: [PATCH 35/68] ensure repos are defined before the script runs --- .Rprofile | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.Rprofile b/.Rprofile index 81b960f..12e9a76 100644 --- a/.Rprofile +++ b/.Rprofile @@ -1 +1,10 @@ source("renv/activate.R") + +options("repos" = c( + "BioCsoft" = "https://bioconductor.org/packages/3.18/bioc", + "BioCann" = "https://bioconductor.org/packages/3.18/data/annotation", + "BioCexp" = "https://bioconductor.org/packages/3.18/data/experiment", + "BioCworkflows" = "https://bioconductor.org/packages/3.18/workflows", + "BioCbooks" = "https://bioconductor.org/packages/3.18/books", + "CRAN" = "https://cloud.r-project.org" +)) From e91e7c887ead2af673864173318efbdc0e78a5f0 Mon Sep 17 00:00:00 2001 From: Russ Hyde Date: Thu, 23 May 2024 15:45:26 +0100 Subject: [PATCH 36/68] ensure renv doesn't use fig-prep script when defining the app environment --- .renvignore | 1 + 1 file changed, 1 insertion(+) create mode 100644 .renvignore diff --git a/.renvignore b/.renvignore new file mode 100644 index 0000000..447045d --- /dev/null +++ b/.renvignore @@ -0,0 +1 @@ +scripts/create_browser_data.R From c2cae29c83bfa8016544d97b46fd25baf44127b2 Mon Sep 17 00:00:00 2001 From: Russ Hyde Date: Thu, 13 Jun 2024 12:30:12 +0100 Subject: [PATCH 37/68] {renv} needn't check the www/data directory --- .renvignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.renvignore b/.renvignore index 447045d..2c9bd9f 100644 --- a/.renvignore +++ b/.renvignore @@ -1 +1,2 @@ scripts/create_browser_data.R +inst/app/www/data/ From f2ead90aa1fc9e8f5264f68823ac086f8aa0abae Mon Sep 17 00:00:00 2001 From: Russ Hyde Date: Thu, 13 Jun 2024 12:28:53 +0100 Subject: [PATCH 38/68] use bioconductor 3.16 for R 4.2.x --- .Rprofile | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.Rprofile b/.Rprofile index 12e9a76..2e9dc1f 100644 --- a/.Rprofile +++ b/.Rprofile @@ -1,10 +1,10 @@ source("renv/activate.R") options("repos" = c( - "BioCsoft" = "https://bioconductor.org/packages/3.18/bioc", - "BioCann" = "https://bioconductor.org/packages/3.18/data/annotation", - "BioCexp" = "https://bioconductor.org/packages/3.18/data/experiment", - "BioCworkflows" = "https://bioconductor.org/packages/3.18/workflows", - "BioCbooks" = "https://bioconductor.org/packages/3.18/books", + "BioCsoft" = "https://bioconductor.org/packages/3.16/bioc", + "BioCann" = "https://bioconductor.org/packages/3.16/data/annotation", + "BioCexp" = "https://bioconductor.org/packages/3.16/data/experiment", + "BioCworkflows" = "https://bioconductor.org/packages/3.16/workflows", + "BioCbooks" = "https://bioconductor.org/packages/3.16/books", "CRAN" = "https://cloud.r-project.org" )) From 4a902182398278bdb1bfa2855bf4dce620c0b4b2 Mon Sep 17 00:00:00 2001 From: Russ Hyde Date: Thu, 13 Jun 2024 12:31:43 +0100 Subject: [PATCH 39/68] env: get ggtree from github, since BioC 3.16 version is incompatible with new {ggplot2} --- DESCRIPTION | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/DESCRIPTION b/DESCRIPTION index 89c47da..60aab9c 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -16,6 +16,7 @@ Imports: fs, ggiraph (>= 0.8.4), ggplot2, + ggtree (>= 3.13.0.1), glue, htmltools, janitor, @@ -30,7 +31,6 @@ Imports: stringr, tibble Suggests: - ggtree, shinytest2, testthat, usethis @@ -38,3 +38,5 @@ Encoding: UTF-8 LazyData: true Roxygen: list(markdown = TRUE) RoxygenNote: 7.3.1 +Remotes: + YuLab-SMU/ggtree@daf3371 From f342320008d1fc4af708976929ef5ba962a6813e Mon Sep 17 00:00:00 2001 From: Russ Hyde Date: Thu, 13 Jun 2024 12:32:16 +0100 Subject: [PATCH 40/68] env: define renv.lock using BioC 3.16 dependencies (for R 4.2.x) --- renv.lock | 417 ++++++++++++++---------------------------------------- 1 file changed, 108 insertions(+), 309 deletions(-) diff --git a/renv.lock b/renv.lock index 325cd49..69a1228 100644 --- a/renv.lock +++ b/renv.lock @@ -1,26 +1,26 @@ { "R": { - "Version": "4.3.3", + "Version": "4.2.3", "Repositories": [ { "Name": "BioCsoft", - "URL": "https://bioconductor.org/packages/3.18/bioc" + "URL": "https://bioconductor.org/packages/3.16/bioc" }, { "Name": "BioCann", - "URL": "https://bioconductor.org/packages/3.18/data/annotation" + "URL": "https://bioconductor.org/packages/3.16/data/annotation" }, { "Name": "BioCexp", - "URL": "https://bioconductor.org/packages/3.18/data/experiment" + "URL": "https://bioconductor.org/packages/3.16/data/experiment" }, { "Name": "BioCworkflows", - "URL": "https://bioconductor.org/packages/3.18/workflows" + "URL": "https://bioconductor.org/packages/3.16/workflows" }, { "Name": "BioCbooks", - "URL": "https://bioconductor.org/packages/3.18/books" + "URL": "https://bioconductor.org/packages/3.16/books" }, { "Name": "CRAN", @@ -41,30 +41,26 @@ }, "BiocManager": { "Package": "BiocManager", - "Version": "1.30.22", + "Version": "1.30.23", "Source": "Repository", "Repository": "CRAN", "Requirements": [ "utils" ], - "Hash": "d57e43105a1aa9cb54fdb4629725acb1" + "Hash": "47e968dfe563c1b22c2e20a067ec21d5" }, "BiocVersion": { "Package": "BiocVersion", - "Version": "3.18.1", + "Version": "3.16.0", "Source": "Bioconductor", - "git_url": "https://git.bioconductor.org/packages/BiocVersion", - "git_branch": "RELEASE_3_18", - "git_last_commit": "70680b8", - "git_last_commit_date": "2023-11-15", "Requirements": [ "R" ], - "Hash": "2ecaed86684f5fae76ed5530f9d29c4a" + "Hash": "44c5824508b9a10e52dbb505c34fa880" }, "MASS": { "Package": "MASS", - "Version": "7.3-60.0.1", + "Version": "7.3-58.2", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -75,16 +71,15 @@ "stats", "utils" ], - "Hash": "b765b28387acc8ec9e9c1530713cb19c" + "Hash": "e02d1a0f6122fd3e634b25b433704344" }, "Matrix": { "Package": "Matrix", - "Version": "1.6-5", + "Version": "1.5-3", "Source": "Repository", "Repository": "CRAN", "Requirements": [ "R", - "grDevices", "graphics", "grid", "lattice", @@ -92,7 +87,7 @@ "stats", "utils" ], - "Hash": "8c7115cd3a0e048bda2a7cd110549f7a" + "Hash": "4006dffe49958d2dd591c17e61e60591" }, "R6": { "Package": "R6", @@ -127,9 +122,9 @@ }, "ape": { "Package": "ape", - "Version": "5.7-1", + "Version": "5.8", "Source": "Repository", - "Repository": "RSPM", + "Repository": "CRAN", "Requirements": [ "R", "Rcpp", @@ -142,7 +137,7 @@ "stats", "utils" ], - "Hash": "10705eec964349f270504754d8fe8ef1" + "Hash": "16b5ff4dff0ead9ea955f62f794b1535" }, "aplot": { "Package": "aplot", @@ -173,13 +168,13 @@ }, "backports": { "Package": "backports", - "Version": "1.4.1", + "Version": "1.5.0", "Source": "Repository", - "Repository": "RSPM", + "Repository": "CRAN", "Requirements": [ "R" ], - "Hash": "c39fbec8a30d23e721980b8afb31984c" + "Hash": "e1e1b9d75c37401117b636b7ae50827a" }, "base64enc": { "Package": "base64enc", @@ -217,13 +212,13 @@ }, "brio": { "Package": "brio", - "Version": "1.1.4", + "Version": "1.1.5", "Source": "Repository", "Repository": "CRAN", "Requirements": [ "R" ], - "Hash": "68bd2b066e1fe780bbf62fc8bcc36de3" + "Hash": "c1ee497a6d999947c2c224ae46799b1a" }, "bsicons": { "Package": "bsicons", @@ -241,13 +236,14 @@ }, "bslib": { "Package": "bslib", - "Version": "0.6.1", + "Version": "0.7.0", "Source": "Repository", "Repository": "CRAN", "Requirements": [ "R", "base64enc", "cachem", + "fastmap", "grDevices", "htmltools", "jquerylib", @@ -258,22 +254,22 @@ "rlang", "sass" ], - "Hash": "c0d8599494bc7fb408cd206bbdd9cab0" + "Hash": "8644cc53f43828f19133548195d7e59e" }, "cachem": { "Package": "cachem", - "Version": "1.0.8", + "Version": "1.1.0", "Source": "Repository", "Repository": "CRAN", "Requirements": [ "fastmap", "rlang" ], - "Hash": "c35768291560ce302c0a6589f92e837d" + "Hash": "cd9a672193789068eb5a2aad65a0dedf" }, "callr": { "Package": "callr", - "Version": "3.7.5", + "Version": "3.7.6", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -282,7 +278,7 @@ "processx", "utils" ], - "Hash": "9f0e4fae4963ba775a5e5c520838c87b" + "Hash": "d7e13f49c19103ece9e58ad2d83a7354" }, "checkmate": { "Package": "checkmate", @@ -390,33 +386,6 @@ ], "Hash": "e8a1e41acf02548751f45c718d55aa6a" }, - "credentials": { - "Package": "credentials", - "Version": "2.0.1", - "Source": "Repository", - "Repository": "CRAN", - "Requirements": [ - "askpass", - "curl", - "jsonlite", - "openssl", - "sys" - ], - "Hash": "c7844b32098dcbd1c59cbd8dddb4ecc6" - }, - "crosstalk": { - "Package": "crosstalk", - "Version": "1.2.1", - "Source": "Repository", - "Repository": "RSPM", - "Requirements": [ - "R6", - "htmltools", - "jsonlite", - "lazyeval" - ], - "Hash": "ab12c7b080a57475248a30f4db6298c0" - }, "curl": { "Package": "curl", "Version": "5.2.1", @@ -429,14 +398,14 @@ }, "data.table": { "Package": "data.table", - "Version": "1.15.2", + "Version": "1.15.4", "Source": "Repository", "Repository": "CRAN", "Requirements": [ "R", "methods" ], - "Hash": "536dfe4ac4093b5d115caed7a1a7223b" + "Hash": "8ee9ac56ef633d0c7cab8b2ca87d683e" }, "desc": { "Package": "desc", @@ -500,17 +469,6 @@ ], "Hash": "fedd9d00c2944ff00a0e2696ccf048ec" }, - "ellipsis": { - "Package": "ellipsis", - "Version": "0.3.2", - "Source": "Repository", - "Repository": "RSPM", - "Requirements": [ - "R", - "rlang" - ], - "Hash": "bb0eec2fe32e88d9e2836c2f73ea2077" - }, "evaluate": { "Package": "evaluate", "Version": "0.23", @@ -536,17 +494,17 @@ }, "farver": { "Package": "farver", - "Version": "2.1.1", + "Version": "2.1.2", "Source": "Repository", - "Repository": "RSPM", - "Hash": "8106d78941f34855c440ddb946b8f7a5" + "Repository": "CRAN", + "Hash": "680887028577f3fa2a81e410ed0d6e42" }, "fastmap": { "Package": "fastmap", - "Version": "1.1.1", + "Version": "1.2.0", "Source": "Repository", "Repository": "CRAN", - "Hash": "f7736a18de97dea803bde0a2daaafb27" + "Hash": "aa5e1cd11c2d15497494c5292d7ffcc8" }, "fontawesome": { "Package": "fontawesome", @@ -562,14 +520,14 @@ }, "fs": { "Package": "fs", - "Version": "1.6.3", + "Version": "1.6.4", "Source": "Repository", "Repository": "CRAN", "Requirements": [ "R", "methods" ], - "Hash": "47b5f30c720c23999b913a1a635cf0bb" + "Hash": "15aeb8c27f5ea5161f9f6a641fafd93a" }, "generics": { "Package": "generics", @@ -582,39 +540,25 @@ ], "Hash": "15e9634c0fcd294799e9b2e929ed1b86" }, - "gert": { - "Package": "gert", - "Version": "2.0.1", - "Source": "Repository", - "Repository": "CRAN", - "Requirements": [ - "askpass", - "credentials", - "openssl", - "rstudioapi", - "sys", - "zip" - ], - "Hash": "f70d3fe2d9e7654213a946963d1591eb" - }, "ggfun": { "Package": "ggfun", - "Version": "0.1.4", + "Version": "0.1.5", "Source": "Repository", "Repository": "CRAN", "Requirements": [ "R", "cli", + "dplyr", "ggplot2", "grid", "rlang", "utils" ], - "Hash": "91780e07f1d631a1152835b4e25c66b9" + "Hash": "4fca342cc17bb91af2a279146bc57fef" }, "ggiraph": { "Package": "ggiraph", - "Version": "0.8.9", + "Version": "0.8.10", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -631,11 +575,11 @@ "uuid", "vctrs" ], - "Hash": "50a51e9be10ba75fc43ee7fb21c18af0" + "Hash": "15748f4335af873289fbdd31610c3f96" }, "ggplot2": { "Package": "ggplot2", - "Version": "3.5.0", + "Version": "3.5.1", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -656,7 +600,7 @@ "vctrs", "withr" ], - "Hash": "52ef83f93f74833007f193b2d4c159a2" + "Hash": "44c6a2f8202d5b7e878ea274b1092426" }, "ggplotify": { "Package": "ggplotify", @@ -676,14 +620,14 @@ }, "ggtree": { "Package": "ggtree", - "Version": "3.10.1", - "Source": "Repository", - "Repository": "Bioconductor 3.18", - "Remotes": "GuangchuangYu/treeio", - "git_url": "https://git.bioconductor.org/packages/ggtree", - "git_branch": "RELEASE_3_18", - "git_last_commit": "5014378", - "git_last_commit_date": "2024-02-25", + "Version": "3.13.0.001", + "Source": "GitHub", + "RemoteType": "github", + "RemoteHost": "api.github.com", + "RemoteRepo": "ggtree", + "RemoteUsername": "YuLab-SMU", + "RemoteRef": "daf3371", + "RemoteSha": "daf3371032abd76645a8a5121913ae06edc90b86", "Requirements": [ "R", "ape", @@ -705,33 +649,7 @@ "utils", "yulab.utils" ], - "Hash": "6b825b70c84bd46133ac63b6dccedef0" - }, - "gh": { - "Package": "gh", - "Version": "1.4.0", - "Source": "Repository", - "Repository": "RSPM", - "Requirements": [ - "R", - "cli", - "gitcreds", - "httr2", - "ini", - "jsonlite", - "rlang" - ], - "Hash": "03533b1c875028233598f848fda44c4c" - }, - "gitcreds": { - "Package": "gitcreds", - "Version": "0.1.2", - "Source": "Repository", - "Repository": "RSPM", - "Requirements": [ - "R" - ], - "Hash": "ab08ac61f3e1be454ae21911eb8bc2fe" + "Hash": "e313a37ca4d92945369633a9d0b5754d" }, "globals": { "Package": "globals", @@ -769,7 +687,7 @@ }, "gtable": { "Package": "gtable", - "Version": "0.3.4", + "Version": "0.3.5", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -780,18 +698,18 @@ "lifecycle", "rlang" ], - "Hash": "b29cf3031f49b04ab9c852c912547eef" + "Hash": "e18861963cbc65a27736e02b3cd3c4a0" }, "highr": { "Package": "highr", - "Version": "0.10", + "Version": "0.11", "Source": "Repository", - "Repository": "https://packagemanager.rstudio.com/all/latest", + "Repository": "CRAN", "Requirements": [ "R", "xfun" ], - "Hash": "06230136b2d2b9ba5805e1963fa6e890" + "Hash": "d65ba49117ca223614f71b60d85b8ab7" }, "hms": { "Package": "hms", @@ -809,20 +727,19 @@ }, "htmltools": { "Package": "htmltools", - "Version": "0.5.7", + "Version": "0.5.8.1", "Source": "Repository", "Repository": "CRAN", "Requirements": [ "R", "base64enc", "digest", - "ellipsis", "fastmap", "grDevices", "rlang", "utils" ], - "Hash": "2d7b3857980e0e0d0a1fd6f11928ab0f" + "Hash": "81d371a9cc60640e74e4ab6ac46dcedc" }, "htmlwidgets": { "Package": "htmlwidgets", @@ -841,7 +758,7 @@ }, "httpuv": { "Package": "httpuv", - "Version": "1.6.14", + "Version": "1.6.15", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -852,7 +769,7 @@ "promises", "utils" ], - "Hash": "16abeb167dbf511f8cc0552efaf05bab" + "Hash": "d55aa087c47a63ead0f6fc10f8fa1ee0" }, "httr": { "Package": "httr", @@ -869,34 +786,6 @@ ], "Hash": "ac107251d9d9fd72f0ca8049988f1d7f" }, - "httr2": { - "Package": "httr2", - "Version": "1.0.0", - "Source": "Repository", - "Repository": "CRAN", - "Requirements": [ - "R", - "R6", - "cli", - "curl", - "glue", - "lifecycle", - "magrittr", - "openssl", - "rappdirs", - "rlang", - "vctrs", - "withr" - ], - "Hash": "e2b30f1fc039a0bab047dd52bb20ef71" - }, - "ini": { - "Package": "ini", - "Version": "0.3.1", - "Source": "Repository", - "Repository": "RSPM", - "Hash": "6154ec2223172bce8162d4153cda21f7" - }, "isoband": { "Package": "isoband", "Version": "0.2.7", @@ -912,7 +801,7 @@ "Package": "janitor", "Version": "2.2.0", "Source": "Repository", - "Repository": "https://packagemanager.rstudio.com/all/latest", + "Repository": "CRAN", "Requirements": [ "R", "dplyr", @@ -952,7 +841,7 @@ }, "knitr": { "Package": "knitr", - "Version": "1.45", + "Version": "1.47", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -964,7 +853,7 @@ "xfun", "yaml" ], - "Hash": "1ec462871063897135c1bcbe0fc8f07d" + "Hash": "7c99b2d55584b982717fcc0950378612" }, "labeling": { "Package": "labeling", @@ -990,7 +879,7 @@ }, "lattice": { "Package": "lattice", - "Version": "0.22-5", + "Version": "0.20-45", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -1001,7 +890,7 @@ "stats", "utils" ], - "Hash": "7c5e89f04e72d6611c77451f6331a091" + "Hash": "b64cdbb2b340437c4ee047a1f4c4377b" }, "lazyeval": { "Package": "lazyeval", @@ -1062,7 +951,7 @@ }, "mgcv": { "Package": "mgcv", - "Version": "1.9-1", + "Version": "1.8-42", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -1075,7 +964,7 @@ "stats", "utils" ], - "Hash": "110ee9d83b496279960e162ac97764ce" + "Hash": "3460beba7ccc8946249ba35327ba902a" }, "mime": { "Package": "mime", @@ -1089,18 +978,18 @@ }, "munsell": { "Package": "munsell", - "Version": "0.5.0", + "Version": "0.5.1", "Source": "Repository", - "Repository": "RSPM", + "Repository": "CRAN", "Requirements": [ "colorspace", "methods" ], - "Hash": "6dfe8bf774944bd5595785e3229d8771" + "Hash": "4fd8900853b746af55b81fda99da7695" }, "nlme": { "Package": "nlme", - "Version": "3.1-164", + "Version": "3.1-162", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -1110,17 +999,17 @@ "stats", "utils" ], - "Hash": "a623a2239e642806158bc4dc3f51565d" + "Hash": "0984ce8da8da9ead8643c5cbbb60f83e" }, "openssl": { "Package": "openssl", - "Version": "2.1.1", + "Version": "2.2.0", "Source": "Repository", "Repository": "CRAN", "Requirements": [ "askpass" ], - "Hash": "2a0dc8c6adfb6f032e4d4af82d258ab5" + "Hash": "2bcca3848e4734eb3b16103bc9aa4b8e" }, "patchwork": { "Package": "patchwork", @@ -1171,7 +1060,7 @@ }, "pkgbuild": { "Package": "pkgbuild", - "Version": "1.4.3", + "Version": "1.4.4", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -1182,7 +1071,7 @@ "desc", "processx" ], - "Hash": "c0143443203205e6a2760ce553dafc24" + "Hash": "a29e8e134a460a01e0ca67a4763c595b" }, "pkgconfig": { "Package": "pkgconfig", @@ -1215,38 +1104,6 @@ ], "Hash": "876c618df5ae610be84356d5d7a5d124" }, - "plotly": { - "Package": "plotly", - "Version": "4.10.4", - "Source": "Repository", - "Repository": "RSPM", - "Requirements": [ - "R", - "RColorBrewer", - "base64enc", - "crosstalk", - "data.table", - "digest", - "dplyr", - "ggplot2", - "htmltools", - "htmlwidgets", - "httr", - "jsonlite", - "lazyeval", - "magrittr", - "promises", - "purrr", - "rlang", - "scales", - "tibble", - "tidyr", - "tools", - "vctrs", - "viridisLite" - ], - "Hash": "a1ac5c03ad5ad12b9d1597e00e23c3dd" - }, "praise": { "Package": "praise", "Version": "1.0.0", @@ -1266,7 +1123,7 @@ }, "processx": { "Package": "processx", - "Version": "3.8.3", + "Version": "3.8.4", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -1275,7 +1132,7 @@ "ps", "utils" ], - "Hash": "82d48b1aec56084d9438dbf98087a7e9" + "Hash": "0c90a7d71988856bad2a2a45dd871bb9" }, "progress": { "Package": "progress", @@ -1293,7 +1150,7 @@ }, "promises": { "Package": "promises", - "Version": "1.2.1", + "Version": "1.3.0", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -1305,7 +1162,7 @@ "rlang", "stats" ], - "Hash": "0d8a15c9d000970ada1ab21405387dee" + "Hash": "434cd5388a3979e74be5c219bcd6e77d" }, "ps": { "Package": "ps", @@ -1413,18 +1270,18 @@ }, "rlang": { "Package": "rlang", - "Version": "1.1.3", + "Version": "1.1.4", "Source": "Repository", "Repository": "CRAN", "Requirements": [ "R", "utils" ], - "Hash": "42548638fae05fd9a9b5f3f437fbbbe2" + "Hash": "3eec01f8b1dee337674b2e34ab1f9bc1" }, "rmarkdown": { "Package": "rmarkdown", - "Version": "2.26", + "Version": "2.27", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -1443,7 +1300,7 @@ "xfun", "yaml" ], - "Hash": "9b148e7f95d33aac01f31282d49e4f44" + "Hash": "27f9502e1cdbfa195f94e03b0f517484" }, "rprojroot": { "Package": "rprojroot", @@ -1455,16 +1312,9 @@ ], "Hash": "4c8415e0ec1e29f3f4f6fc108bef0144" }, - "rstudioapi": { - "Package": "rstudioapi", - "Version": "0.15.0", - "Source": "Repository", - "Repository": "CRAN", - "Hash": "5564500e25cffad9e22244ced1379887" - }, "sass": { "Package": "sass", - "Version": "0.4.8", + "Version": "0.4.9", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -1474,7 +1324,7 @@ "rappdirs", "rlang" ], - "Hash": "168f9353c76d4c4b0a0bbf72e2c2d035" + "Hash": "d53dbfddf695303ea4ad66f86e99b95d" }, "scales": { "Package": "scales", @@ -1498,7 +1348,7 @@ }, "shiny": { "Package": "shiny", - "Version": "1.8.0", + "Version": "1.8.1.1", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -1508,7 +1358,6 @@ "cachem", "commonmark", "crayon", - "ellipsis", "fastmap", "fontawesome", "glue", @@ -1528,13 +1377,13 @@ "withr", "xtable" ], - "Hash": "3a1f41807d648a908e3c7f0334bf85e6" + "Hash": "54b26646816af9960a4c64d8ceec75d6" }, "shinybrowser": { "Package": "shinybrowser", "Version": "1.0.0", "Source": "Repository", - "Repository": "https://packagemanager.rstudio.com/all/latest", + "Repository": "CRAN", "Requirements": [ "R", "shiny" @@ -1556,7 +1405,7 @@ }, "shinytest2": { "Package": "shinytest2", - "Version": "0.3.1", + "Version": "0.3.2", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -1566,7 +1415,6 @@ "chromote", "cpp11", "crayon", - "ellipsis", "fs", "globals", "httr", @@ -1578,7 +1426,7 @@ "testthat", "withr" ], - "Hash": "04e60b31d4afef1d221ede5fafb0c6f6" + "Hash": "a414c1bb2eb6e2a920742d3ebce84962" }, "snakecase": { "Package": "snakecase", @@ -1604,7 +1452,7 @@ }, "stringi": { "Package": "stringi", - "Version": "1.8.3", + "Version": "1.8.4", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -1613,7 +1461,7 @@ "tools", "utils" ], - "Hash": "058aebddea264f4c99401515182e656a" + "Hash": "39e1144fd75428983dc3f63aa53dfa91" }, "stringr": { "Package": "stringr", @@ -1641,18 +1489,19 @@ }, "systemfonts": { "Package": "systemfonts", - "Version": "1.0.6", + "Version": "1.1.0", "Source": "Repository", "Repository": "CRAN", "Requirements": [ "R", - "cpp11" + "cpp11", + "lifecycle" ], - "Hash": "6d538cff441f0f1f36db2209ac7495ac" + "Hash": "213b6b8ed5afbf934843e6c3b090d418" }, "testthat": { "Package": "testthat", - "Version": "3.2.1", + "Version": "3.2.1.1", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -1677,7 +1526,7 @@ "waldo", "withr" ], - "Hash": "4767a686ebe986e6cb01d075b3f09729" + "Hash": "3f6e7e5e2220856ff865e4834766bf2b" }, "tibble": { "Package": "tibble", @@ -1772,22 +1621,18 @@ }, "tinytex": { "Package": "tinytex", - "Version": "0.49", + "Version": "0.51", "Source": "Repository", "Repository": "CRAN", "Requirements": [ "xfun" ], - "Hash": "5ac22900ae0f386e54f1c307eca7d843" + "Hash": "d44e2fcd2e4e076f0aac540208559d1d" }, "treeio": { "Package": "treeio", - "Version": "1.26.0", + "Version": "1.22.0", "Source": "Bioconductor", - "git_url": "https://git.bioconductor.org/packages/treeio", - "git_branch": "RELEASE_3_18", - "git_last_commit": "cce8f0a", - "git_last_commit_date": "2023-10-24", "Requirements": [ "R", "ape", @@ -1796,12 +1641,11 @@ "magrittr", "methods", "rlang", - "stats", "tibble", "tidytree", "utils" ], - "Hash": "a09203806aa0bc49965563ca7016620e" + "Hash": "79eb206300fb5e5feea1f508a8166eba" }, "tzdb": { "Package": "tzdb", @@ -1814,37 +1658,6 @@ ], "Hash": "f561504ec2897f4d46f0c7657e488ae1" }, - "usethis": { - "Package": "usethis", - "Version": "2.2.3", - "Source": "Repository", - "Repository": "CRAN", - "Requirements": [ - "R", - "cli", - "clipr", - "crayon", - "curl", - "desc", - "fs", - "gert", - "gh", - "glue", - "jsonlite", - "lifecycle", - "purrr", - "rappdirs", - "rlang", - "rprojroot", - "rstudioapi", - "stats", - "utils", - "whisker", - "withr", - "yaml" - ], - "Hash": "d524fd42c517035027f866064417d7e6" - }, "utf8": { "Package": "utf8", "Version": "1.2.4", @@ -1946,13 +1759,6 @@ ], "Hash": "76e0d400757e318cca33def29ccebbc2" }, - "whisker": { - "Package": "whisker", - "Version": "0.4.1", - "Source": "Repository", - "Repository": "RSPM", - "Hash": "c6abfa47a46d281a7d5159d0a8891e88" - }, "withr": { "Package": "withr", "Version": "3.0.0", @@ -1967,7 +1773,7 @@ }, "xfun": { "Package": "xfun", - "Version": "0.42", + "Version": "0.44", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -1975,7 +1781,7 @@ "stats", "tools" ], - "Hash": "fd1349170df31f7a10bd98b0189e85af" + "Hash": "317a0538d32f4a009658bcedb7923f4b" }, "xtable": { "Package": "xtable", @@ -2012,13 +1818,6 @@ "utils" ], "Hash": "60ee2aaa179dc282e9fa7367bad76e89" - }, - "zip": { - "Package": "zip", - "Version": "2.3.1", - "Source": "Repository", - "Repository": "CRAN", - "Hash": "fcc4bd8e6da2d2011eb64a5e5cc685ab" } } } From 475fa4dd6a14796739019430d71e00c613024adb Mon Sep 17 00:00:00 2001 From: Russ Hyde Date: Thu, 13 Jun 2024 12:33:33 +0100 Subject: [PATCH 41/68] env(helper-script): hard-code the ggtree dev version used by the script --- scripts/create_browser_data.R | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/scripts/create_browser_data.R b/scripts/create_browser_data.R index 9f07eab..fbbded7 100644 --- a/scripts/create_browser_data.R +++ b/scripts/create_browser_data.R @@ -46,7 +46,7 @@ treeview_args <- list( tfpbrowser_env <- jsonlite::read_json("renv.lock") -required_packages <- c("BiocVersion", "ggplot2", "ggiraph", "ggtree") +required_packages <- c("BiocVersion", "fastmap", "ggplot2", "ggiraph", "ggtree") required_versions <- Map( function(package, pkg_details) { paste0(package, "@", pkg_details[["Version"]]) @@ -62,8 +62,9 @@ renv::use( # ensure that the figure formatting required_versions[["BiocVersion"]], required_versions[["ggplot2"]], + required_versions[["fastmap"]], required_versions[["ggiraph"]], - required_versions[["ggtree"]], + "YuLab-SMU/ggtree@daf3371", # These packages are required implicitly by {tfpscanner}, but not by {tfpbrowser} "svglite@2.1.3", # This is the HEAD of `jumpingrivers:dev-202403` as of 2024-04-15 From 984a5230719c5110f3bf24f298818cc123d19fdc Mon Sep 17 00:00:00 2001 From: Russ Hyde Date: Thu, 8 Aug 2024 15:38:41 +0100 Subject: [PATCH 42/68] env: add {markdown} to dependencies - needed when importing .rds files from tfpscanner (but not used directly by tfpbrowser) --- DESCRIPTION | 1 + renv.lock | 13 +++++++++++++ 2 files changed, 14 insertions(+) diff --git a/DESCRIPTION b/DESCRIPTION index 60aab9c..9a38a22 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -21,6 +21,7 @@ Imports: htmltools, janitor, magrittr, + markdown, purrr, reactable, readr, diff --git a/renv.lock b/renv.lock index 69a1228..a4254fa 100644 --- a/renv.lock +++ b/renv.lock @@ -938,6 +938,19 @@ ], "Hash": "7ce2733a9826b3aeb1775d56fd305472" }, + "markdown": { + "Package": "markdown", + "Version": "1.13", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "commonmark", + "utils", + "xfun" + ], + "Hash": "074efab766a9d6360865ad39512f2a7e" + }, "memoise": { "Package": "memoise", "Version": "2.0.1", From 66bb233cab6ebf1a3e6d48b8cad1db2a2b9a71cb Mon Sep 17 00:00:00 2001 From: Russ Hyde Date: Thu, 15 Aug 2024 12:13:29 +0100 Subject: [PATCH 43/68] doc: installing/cloning tfpbrowser code --- README.md | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 6d688f5..37be3d0 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,30 @@ # {tfpbrowser} -An R package to build a Shiny application to explore {tfpscanner} outputs. The outputs from {tfpscanner} should be stored in the `inst/app/www/data/` folder. +An R package to build a Shiny application to explore {tfpscanner} outputs. +The outputs from {tfpscanner} can be stored in the `inst/app/www/data/` folder and tfpbrowser will +present data in this directory by default. ## Installation +The recommended way to use this application, is to clone the associated `git` repository and work +within that directory. This can be achieved using `git` from the command line: + +```bash +# Using SSH +git clone git@github.com:mrc-ide/tfpbrowser.git +# Or using HTTPS +git clone https://github.com/mrc-ide/tfpbrowser.git ``` -remotes::install_github("mrc-ide/tfpbrowser") -``` + +Or from inside RStudio (`File -> New Project -> Version Control -> Git` then enter the repository +URL "https://github.com/mrc-ide/tfpbrowser.git"). + +To get the latest version of the code, use the `git pull` command (or the `Git -> Pull` workflow in +RStudio). + +Then open an R session in the directory for the git repository. A simple way to do this is to +open RStudio and use the `File -> Open Project` workflow, navigating to the `tfpbrowser.Rproj` file +in the `tfpbrowser` directory. ## Running the Shiny application From 8598fd8c09b0500208d6b9a8d44973b8df37d3b2 Mon Sep 17 00:00:00 2001 From: Russ Hyde Date: Thu, 15 Aug 2024 12:47:45 +0100 Subject: [PATCH 44/68] doc: activating the app's package environment --- README.md | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/README.md b/README.md index 37be3d0..758b6cd 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,43 @@ in the `tfpbrowser` directory. ## Running the Shiny application +Before running the app, we must ensure that the packages it depends upon are available and a dataset +for presentation is in place. + +Note that the bioconductor packages used by `tfpbrowser` are tied to a specific version of R. +As of 2024, you should use R v4.2.x. + +### Activating the environment for the application + +The specific versions of the packages used by the app (the package environment) are declared in an +`renv.lock` file. See the [{renv} documentation](https://rstudio.github.io/renv/) for further +details. `renv` isolates the environment for this app away from the R packages installed elsewhere +on your machine. + +The first time that you open the `tfpbrowser` project in an R session, activating the package +environment may fail. You will need to follow these steps: + +- Install `renv` (`install.packages("renv")`) +- Install the `tfpbrowser` package environment (`renv::restore()`) +- Restart the session (In RStudio `Session -> Restart R`) + +The package environment will be automatically loaded when the project is opened on subsequent +occasions. On successfully loading the environment, `renv` will print out the following comment: + +``` +- Project '~/path/to/tfpbrowser' loaded. [renv 1.0.7] +``` + +The packages defined in the `renv.lock` file may change over time. If you receive a message that +`The project is out-of-sync...` when you load the `tfpbrowser` project, it is likely that the +package environment in `renv.lock` has updated, but your local machine is using an older +environment. Run `renv::restore()` to sync your `tfpbrowser` environment with the current +`renv.lock` file. + +### Directing the app to the dataset + +### Running + ``` tfpbrowser::run_app() ``` From f89f93a5bd9a535ee7a7d20c84462efb588770fc Mon Sep 17 00:00:00 2001 From: Russ Hyde Date: Tue, 3 Sep 2024 22:52:20 +0100 Subject: [PATCH 45/68] doc: creating and configuring a data directory for tfpbrowser --- README.md | 98 ++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 90 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 758b6cd..97e89cb 100644 --- a/README.md +++ b/README.md @@ -28,8 +28,10 @@ in the `tfpbrowser` directory. ## Running the Shiny application -Before running the app, we must ensure that the packages it depends upon are available and a dataset -for presentation is in place. +Before running the app, we must ensure that + +- the packages it depends upon are available; and +- a dataset for presentation is in place. Note that the bioconductor packages used by `tfpbrowser` are tied to a specific version of R. As of 2024, you should use R v4.2.x. @@ -61,24 +63,104 @@ package environment in `renv.lock` has updated, but your local machine is using environment. Run `renv::restore()` to sync your `tfpbrowser` environment with the current `renv.lock` file. -### Directing the app to the dataset +### Directing the app to a dataset + +`tfpbrowser` relies on data preprocessing by [`tfpscanner`](https://github.com/mrc-ide/tfpscanner). +See the section on "Creating a new `tfpbrowser` dataset" + +`tfpscanner` acts upon a directory of data (which must contain a `scanner_output` subdirectory) and +adds `treeview`, `sequences` and `mutations` directories to its input. Content in all four of these +subdirectories is needed for `tfpbrowser` to work. + +So, a dataset for `tfpbrowser` must be structured like this: + +``` +/path/to/my_data +├── mutations +├── scanner_output +├── sequences +└── treeview +``` + +There are two ways to make `tfpbrowser` use such a dataset: + +- Copy the `mutations`, `scanner_output`, `sequences` and `treeview` directories into the + `inst/app/www/data` directory of the `tfpbrowser` repository, then either reinstall `tfpbrowser` + or load the package temporarily in your current session (using + [`pkgload::load_all()`](https://search.r-project.org/CRAN/refmans/pkgload/html/load_all.html)) + +- Configure the app to read data from the dataset directory without moving its contents by setting + the `APP_DATA_DIR` variable to contain the path to that directory. See the section "Configuring + the deployed app". ### Running +The most robust way to run the application is to start an R session inside the repository that +houses the source code for {tfpbrowser}. This will ensure that the environment within which the app +runs is activated before the app is started (see section "Activating the environment for the +application"). + +Once the environment is activated, the app can be run using the following R commands: + +```r +# Load the contents of the {tfpbrowser} package +pkgload::load_all() + +# Optionally define the directory that contains the tfpscanner data for presentation +# - Alternative ways to define the data-path are described in "Configuring the app" +Sys.setenv(APP_DATA_DIR = "/path/to/data") + +# Run the app +run_app() +``` + +An alternative way to run the app is by using the `run_app()` function from the installed +{tfpbrowser} package. However, you may find that the tfpscanner data used is incompatible with +tfpbrowser. As such, we recommend generating tfpscanner output using the `create_browser_data.R` +script and running tfpbrowser within it's defined R environment, as described above. + ``` tfpbrowser::run_app() ``` -## Updating with new data +## Creating a new `tfpbrowser` dataset + +In the repository for {tfpbrowser} there is a script `./scripts/create_browser_data.R`. This can be +used to generate a dataset for presentation by {tfpbrowser}. The script contains detailed +instructions for its use. + +Briefly: + +- "create_browser_data.R" runs the `tfpscanner::create_browser_data()` function +- It takes scanner output, and creates a number of tree-views that can be presented in the + {tfpbrowser} app +- Input: + - The user should modify `create_browser_data.R` to point the script to a directory + containing {tfpscanner} input (`/path/to/tfpscanner_input/`) + - That directory contains a `scanner_output/` subdirectory + (`/path/to/tfpscanner_input/scanner_output/`) + - That subdirectory contains a file containing an R environment object + `scanner-env-YYYY-MM-DD.rds` +- Output: + - `create_browser_data.R` appends some files to the `/path/to/tfpscanner_input/` directory + - After running the script, that directory will contain subdirectories `mutations`, + `scanner_output`, `sequences` and `treeview` + +`create_browser_data.R` _must_ run from the repository for {tfpbrowser} because it uses a similar +mechanism to the {tfpbrowser} app to define the versions of R packages used when it runs. This is +important because the 'treeview' outputs that are generated are binary R objects that the +{tfpbrowser} app will import. The R packages used to generate those objects must match those used +when importing them. By running from the {tfpbrowser} directory we can use the environment +definition for the {tfpbrowser} app to precisely specify the packages needed when {tfpscanner} runs. + +Once the data has been appended by `create_browser_data.R`, it can be used by the {tfpbrowser} app. +To do this either: -* See the notes on using `tfpscanner::create_browser_data()` with tfpbrowser in the README for - {tfpscanner} -* Either: - configure {tfpbrowser} to use the output data directory used in `create_browser_data()` (see the next section); or - copy the contents of that directory into `inst/app/www/data/` and re-install {tfpbrowser} -## Configuring the deployed app +## Configuring the app Data presented by the app can be obtained from an arbitrary directory on the server. To configure the data-directory, use the environment variable `APP_DATA_DIR`. From eaeb8f8c0e85b2869ec7b703c18bdbbaef0b108b Mon Sep 17 00:00:00 2001 From: Russ Hyde Date: Tue, 10 Sep 2024 15:57:57 +0100 Subject: [PATCH 46/68] env: fix conflict between DESCRIPTION and renv re ggtree version --- DESCRIPTION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DESCRIPTION b/DESCRIPTION index 9a38a22..35fa9e8 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -16,7 +16,7 @@ Imports: fs, ggiraph (>= 0.8.4), ggplot2, - ggtree (>= 3.13.0.1), + ggtree, glue, htmltools, janitor, From c2c3a64304d5a5846c83df310acbc1fa7cb7881f Mon Sep 17 00:00:00 2001 From: Russ Hyde Date: Tue, 10 Sep 2024 15:59:03 +0100 Subject: [PATCH 47/68] env: infrastructure for building vignettes --- .gitignore | 1 + DESCRIPTION | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 4040a21..bfbeb5f 100644 --- a/.gitignore +++ b/.gitignore @@ -53,3 +53,4 @@ po/*~ # RStudio Connect folder rsconnect/ +inst/doc diff --git a/DESCRIPTION b/DESCRIPTION index 35fa9e8..936ce61 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -32,6 +32,8 @@ Imports: stringr, tibble Suggests: + knitr, + rmarkdown, shinytest2, testthat, usethis @@ -39,5 +41,6 @@ Encoding: UTF-8 LazyData: true Roxygen: list(markdown = TRUE) RoxygenNote: 7.3.1 -Remotes: +Remotes: YuLab-SMU/ggtree@daf3371 +VignetteBuilder: knitr From 83eb10956611a3a2658f6c1e61d0346606dd4b66 Mon Sep 17 00:00:00 2001 From: Russ Hyde Date: Tue, 10 Sep 2024 15:59:30 +0100 Subject: [PATCH 48/68] doc: vignette explaining deployment workflow --- vignettes/.gitignore | 2 + vignettes/deploy.Rmd | 309 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 311 insertions(+) create mode 100644 vignettes/.gitignore create mode 100644 vignettes/deploy.Rmd diff --git a/vignettes/.gitignore b/vignettes/.gitignore new file mode 100644 index 0000000..097b241 --- /dev/null +++ b/vignettes/.gitignore @@ -0,0 +1,2 @@ +*.html +*.R diff --git a/vignettes/deploy.Rmd b/vignettes/deploy.Rmd new file mode 100644 index 0000000..fb5f18a --- /dev/null +++ b/vignettes/deploy.Rmd @@ -0,0 +1,309 @@ +--- +title: "Deploying tfpbrowser" +output: rmarkdown::html_vignette +vignette: > + %\VignetteIndexEntry{Deploying tfpbrowser} + %\VignetteEngine{knitr::rmarkdown} + %\VignetteEncoding{UTF-8} +--- + +```{r, include = FALSE} +knitr::opts_chunk$set( + collapse = TRUE, + comment = "#>" +) +``` + +## Example + +Here we will + +- run tfpscanner against a set of scanner output, +- configure tfpbrowser to use the newly created tfpscanner output +- deploy the app, along with the new data, to shinyapps.io + +We are following the workflow described in the README for {tfpbrowser}, but with a practical +example. + +In this example, we have: + +- a dataset in `~/temp-data/wcdemo/` and +- the repository for {tfpbrowser} in `~/github/imp/tfpbrowser` +- and are using `r R.version.string` + +```{r} +dirs <- list( + data = "~/temp-data/wcdemo/", + repo = "~/github/imp/tfpbrowser/" +) +``` + +### General workflow issues + +The following must be ran inside RStudio in the {tfpbrowser} repository/project and must be ran +using the R version specified above. There are very precise package-requirements that ensure the +data-processing is compatible with the app, and these can only be controlled from the {tfpbrowser} +project. + +We assume you have cloned the {tfpbrowser} repository to your machine (in this example it is at +`r dirs$repo`). Open RStudio and then open the {tfpbrowser} 'Project' (File -> Open Project; +navigate to the tfpbrowser repo and double click on `tfpbrowser.Rproj`). + +We will use the [{fs}](https://fs.r-lib.org/) package for working with the file system. + +You should see an {renv} environment gets activated on opening the {tfpbrowser} project. This is the +environment within which the app runs (a related, but separate environment is used for data +pre-processing, see below). + +```r +... R preamble ... +Type 'demo()' for some demos, 'help()' for on-line help, or +'help.start()' for an HTML browser interface to help. +Type 'q()' to quit R. + +- Project '~/github/imp/tfpbrowser' loaded. [renv 1.0.7] +``` + +If you receive a message stating that: + +- "there is no package called 'renv'", you will need to install {renv} from CRAN + (install.packages("renv")) and then reopen the {tfpbrowser} project +- the renv environment is out of sync, you may need to restore the package-versions that are defined + in the lock file (`renv::restore()`). + +#### GitHub Personal-Access Token (PAT) + +Some of the packages used by tfpscanner during data pre-processing (`ggtree` and `tfpscanner` +itself) must be installed from github while data processing is underway. To make this possible, you +will need a `GITHUB_PAT` variable to be defined - this is a personal token that you can obtain from +[github](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens). If you have access to the {tfpscanner} repository on GitHub, then you will be able to install +it using your personal access token. + +To make your PAT available to tfpbrowser, add a `.Renviron` file to the tfpbrowser project / +repository with your PAT as the value on the 'GITHUB_PAT' variable line. + +```bash +GITHUB_PAT=ghp_blahBlahBlah... +``` + +Do not commit your `.Renviron` file using git! This file stores variables / secrets that are +required when the app runs. The variables will differ from one deployment to another, and the +secrets should be secret! + +### The scanner dataset + +The contents of the scanner dataset directory are as follows: + +```r +fs::dir_tree(dirs$data, recurse=1) +~/temp-data/wcdemo +└── scanner_output + ├── 1601 + ├── ... + ├── 2194 + ├── scanner-2021-11-27.rds + └── scanner-env-2021-11-27.rds +``` + +The 'scanner-env' file and the contents of the `1601` to `2194` directories are needed for +tfpscanner to generate the files needed by tfpbrowser. + +The directory `r dirs$data` contains ~ 13MB of data before processing by tfpscanner. + +### Processing the scanner dataset + +We use the `./scripts/create_browser_data.R` script inside the {tfpbrowser} repository to +process the scanner data. + +There are three user-configurable parameters in that script (`env_file`, `output_dir`, +`treeview_args`). +We define the location of the `scanner-env-2021-11-27.rds` file and the output directory. + +The output directory must be the parent of the input `scanner_output` directory for now (that is, +`r dirs$data` in this example) because tfpbrowser requires additional files from the +`scanner_output` directory to run. + +We haven't modified the `treeview_args` parameter here, but this can be used to pass additional +arguments to `tfpscanner::treeview()`. + +After modifying the script in-place, the user-parameters section of `create_browser_data.R` looks +like this: + +```r +# User parameters ----------------------------------------------------------------------------- + +# File paths can be specified either relative to the working directory, or as absolute paths +# +# 1) The scanner environment file ("path/to/scanner_output/scanner-env-YYYY-MM-DD.rds") +env_file <- file.path("~/temp-data/wcdemo/scanner_output/scanner-env-2021-11-27.rds") + +# 2) The output directory for the treeviews (typically the parent of the 'scanner_output' directory) +output_dir <- file.path("~/temp-data/wcdemo") + +# 3) Any non-default arguments for the `treeview()` function +treeview_args <- list( + # unmodified +) +``` + +With these changes in place, the `create_browser_data.R` script can be ran. Either use `source("scripts/create_browser_data.R")` or open the script in RStudio and click the "Source" +button above the text editor for the script. + +The script runs in it's own environment and will install packages into a temporary location while +it is running. This process will fail if you haven't defined a `GITHUB_PAT` variable (see above). + +```r +source("~/github/imp/tfpbrowser/scripts/create_browser_data.R") + +#> The following loaded package(s) have been updated: +#> - BiocManager +#> Restart your R session to use the new versions. + +#> The following package(s) will be installed: +#> - ape [5.8] +#> - aplot [0.2.3] +#> - base64enc [0.1-3] +#> ... +#> # ================================================================================ # +#> # To run the "tfpbrowser" app over this dataset, please perform the following from +#> # the "tfpbrowser" home directory in R: + +#> # Start a new session first +#> # - the environment for this script will interfere with that used by the app +#> Sys.setenv(APP_DATA_DIR = "~/temp-data/wcdemo") +#> pkgload::load_all() +#> run_app() +``` + +After running `create_browser_data.R`, the data directory should contain additional entries: + +```r +fs::dir_tree(dirs$data, recurse=1) +~/temp-data/wcdemo/ +├── mutations +│ ├── all_mutations.csv +│ └── defining_mutations.csv +├── scanner_output +│ ├── 1601 +│ ├── ... +│ ├── 2194 +│ ├── scanner-2021-11-27.rds +│ └── scanner-env-2021-11-27.rds +├── sequences +│ └── all_sequences.csv +└── treeview + ├── node_lookup + ├── ... + └── tree-sequences.rds +``` + +The `scanner_output` subdirectory is unmodified by the workflow, but some additional subdirectories + have been added (`mutations`, `sequences`, `treeview`). + +The data directory now contains ~ 33MB. + +Whenever you run the `create_browser_data.R` script, you must restart your R session afterwards. So, +we restarted R from inside RStudio (`Session` -> `Restart R`). + +### Integrating the scanner dataset into tfpbrowser + +We want to deploy the app to shinyapps.io. When you do this a single directory is uploaded to +shinyapps.io and if you want to embed data with the app, that data must be in the directory that +you upload (unless it is accessed via an API, URL or from another R package). + +We will put the contents of the `r dirs$data` directory into the `./inst/app/www/wcdemo-data` +directory of our app and then configure the app to use this directory when it is deployed. + +In a new R session (with the `dirs` variable, above, redefined), we can copy the directory contents +as follows: + +```r +dirs$embedded_data <- file.path(dirs$repo, "inst", "app", "www", "wcdemo-data") + +fs::dir_copy( + path = dirs$data, + new_path = dirs$embedded_data +) +``` + +```r +fs::dir_tree( + dirs$embedded_data, + recurse = 0 +) +``` + +```r +#> ~/github/imp/tfpbrowser//inst/app/www/wcdemo-data +#> ├── mutations +#> ├── scanner_output +#> ├── sequences +#> └── treeview +``` + +### Configuring tfpbrowser + +By default, tfpbrowser presents the scanner data that is found at `./inst/app/www/data/`. But the +files in this directory are hard to update and to keep in-sync with the app's working environment. + +To present a dataset from a different directory, you can configure {tfpbrowser} using an environment +variable. + +In the `.Renviron` file, add a line that defines where the `wcdemo-data` directory is, relative to +the repository root and call this variable `APP_DATA_DIR`. + +```bash +# ./.Renviron +APP_DATA_DIR=./inst/app/www/wcdemo-data +GITHUB_PAT=ghp_..... +``` + +This environment variable is used by tfpbrowser to find the data for presentation. Some of the files +within that directory are also served to the user's browser while the app runs. + +When you change the `.Renviron` file, you need to restart your R session before those changes affect +your R session. So we restarted R (`Session` -> `Restart R`) and then checked that the app runs +locally: + +```r +pkgload::load_all() +run_app() +``` + +The `.Renviron` file will be sent to shinyapps.io during deployment, so the data configuration will +be sent there too. + +### Deploying tfpbrowser + +We deploy the app to shinyapps.io using the {rsconnect} package. That package is not included in the +renv.lock file, so you may need to install it prior to deployment: + +```r +renv::install("rsconnect") +``` + +If you haven't deployed from your machine before, you will need to add some (secrets) from your +shinyapps.io account. Log into shinyapps.io and go to the "Account -> Tokens" page. Click +"Add Token", then "Show" to view the code needed to configure your connection to shinyapps.io from +your local machine. Copy the code revealed. Then run that in your R session (including the secret): + +```r +rsconnect::setAccountInfo( + name='my-user-name', + token='RANDOM123ALPHANUMERIC', + secret='some-secret-value' +) +``` + +Then we deployed the app using the following command: + +```r +rsconnect::deployApp() +``` + +This uploaded all the files in the repository, which is unnecessary... [TODO: continue here] + +```{r setup} +# library(tfpbrowser) +``` + From 0e4a785f56c294c034c774e49de99c326831a100 Mon Sep 17 00:00:00 2001 From: Russ Hyde Date: Tue, 10 Sep 2024 16:00:56 +0100 Subject: [PATCH 49/68] add app.R so that the app can be deployed to shinyapps.io --- app.R | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 app.R diff --git a/app.R b/app.R new file mode 100644 index 0000000..839357d --- /dev/null +++ b/app.R @@ -0,0 +1,3 @@ +pkgload::load_all(helpers = FALSE, export_all = FALSE, attach_testthat = FALSE) + +run_app() From c8f9f9e314e92045e530f995e3f6550c31b614d3 Mon Sep 17 00:00:00 2001 From: Russ Hyde Date: Tue, 10 Sep 2024 16:01:16 +0100 Subject: [PATCH 50/68] env: use bioconductor 3.16 --- renv.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/renv.lock b/renv.lock index a4254fa..5890dfd 100644 --- a/renv.lock +++ b/renv.lock @@ -29,7 +29,7 @@ ] }, "Bioconductor": { - "Version": "3.18" + "Version": "3.16" }, "Packages": { "AsioHeaders": { From 5d617b83242aeb716df9aecb145f50cfa341fe7c Mon Sep 17 00:00:00 2001 From: Russ Hyde Date: Tue, 10 Sep 2024 16:20:17 +0100 Subject: [PATCH 51/68] doc: alternative deployment method using RStudio 'Publish' button --- vignettes/deploy.Rmd | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/vignettes/deploy.Rmd b/vignettes/deploy.Rmd index fb5f18a..4b4edb4 100644 --- a/vignettes/deploy.Rmd +++ b/vignettes/deploy.Rmd @@ -74,10 +74,11 @@ If you receive a message stating that: #### GitHub Personal-Access Token (PAT) Some of the packages used by tfpscanner during data pre-processing (`ggtree` and `tfpscanner` -itself) must be installed from github while data processing is underway. To make this possible, you +itself) must be installed from GitHub while data processing is underway. To make this possible, you will need a `GITHUB_PAT` variable to be defined - this is a personal token that you can obtain from -[github](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens). If you have access to the {tfpscanner} repository on GitHub, then you will be able to install -it using your personal access token. +[github](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens). +If you have access to the {tfpscanner} repository on GitHub, then you will be able to install it +using your personal access token. To make your PAT available to tfpbrowser, add a `.Renviron` file to the tfpbrowser project / repository with your PAT as the value on the 'GITHUB_PAT' variable line. @@ -301,9 +302,21 @@ Then we deployed the app using the following command: rsconnect::deployApp() ``` -This uploaded all the files in the repository, which is unnecessary... [TODO: continue here] +This uploaded all the files in the repository, which is unnecessary. RStudio provides a second +method for deploying a shiny app to shinyapps.io. Assuming your account info and .Renviron file have +been set up (as above) run the {tfpbrowser} app -```{r setup} -# library(tfpbrowser) +```r +pkgload::load_all() +run_app() ``` +Then click on the "Publish" or "Republish" button in the RStudio browser window that opens. +A "Publish to Server" dialog box will open, and within this you can select/deselect which files to +upload to shinyapps.io along with your app. You shouldn't upload any tests, un-needed datasets, +github workflows. + +The minimum files you will need for deployment are (`.Rprofile`, `.Renviron`, `app.R`, +`DESCRIPTION`, `NAMESPACE`, `renv.lock`, and the contents of `inst/` and `R/`). If the data you wish +to deploy with the app is in some other directory, this must also be selected for upload. + From daa1d646bac44917a1bc446761be574ddea2f38f Mon Sep 17 00:00:00 2001 From: Russ Hyde Date: Tue, 10 Sep 2024 16:44:34 +0100 Subject: [PATCH 52/68] doc: store data for deployment outside of inst/ in deployment workflow (since inst already contains inappropriately formatted data) --- vignettes/deploy.Rmd | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/vignettes/deploy.Rmd b/vignettes/deploy.Rmd index 4b4edb4..22936c2 100644 --- a/vignettes/deploy.Rmd +++ b/vignettes/deploy.Rmd @@ -34,7 +34,10 @@ In this example, we have: ```{r} dirs <- list( data = "~/temp-data/wcdemo/", - repo = "~/github/imp/tfpbrowser/" + repo = "~/github/imp/tfpbrowser/", + # A copy of the tfpscanner-processed data will be placed in + # this subdirectory of the tfpbrowser repository + deploy_data = "~/github/imp/tfpbrowser/deploy-data/wcdemo/" ) ``` @@ -199,7 +202,7 @@ fs::dir_tree(dirs$data, recurse=1) ``` The `scanner_output` subdirectory is unmodified by the workflow, but some additional subdirectories - have been added (`mutations`, `sequences`, `treeview`). +have been added (`mutations`, `sequences`, `treeview`). The data directory now contains ~ 33MB. @@ -212,30 +215,28 @@ We want to deploy the app to shinyapps.io. When you do this a single directory i shinyapps.io and if you want to embed data with the app, that data must be in the directory that you upload (unless it is accessed via an API, URL or from another R package). -We will put the contents of the `r dirs$data` directory into the `./inst/app/www/wcdemo-data` +We will put the contents of the `r dirs$data` directory into the `./deploy-data/wcdemo/` directory of our app and then configure the app to use this directory when it is deployed. In a new R session (with the `dirs` variable, above, redefined), we can copy the directory contents as follows: ```r -dirs$embedded_data <- file.path(dirs$repo, "inst", "app", "www", "wcdemo-data") - fs::dir_copy( path = dirs$data, - new_path = dirs$embedded_data + new_path = dirs$deploy_data ) ``` ```r fs::dir_tree( - dirs$embedded_data, + dirs$deploy_data, recurse = 0 ) ``` ```r -#> ~/github/imp/tfpbrowser//inst/app/www/wcdemo-data +#> ~/github/imp/tfpbrowser/deploy-data/wcdemo/ #> ├── mutations #> ├── scanner_output #> ├── sequences @@ -250,12 +251,12 @@ files in this directory are hard to update and to keep in-sync with the app's wo To present a dataset from a different directory, you can configure {tfpbrowser} using an environment variable. -In the `.Renviron` file, add a line that defines where the `wcdemo-data` directory is, relative to -the repository root and call this variable `APP_DATA_DIR`. +In the `.Renviron` file, add a line that defines where the `deploy-data/wcdemo/` directory is, +relative to the repository root and call this variable `APP_DATA_DIR`. ```bash # ./.Renviron -APP_DATA_DIR=./inst/app/www/wcdemo-data +APP_DATA_DIR=./deploy-data/wcdemo/ GITHUB_PAT=ghp_..... ``` @@ -320,3 +321,10 @@ The minimum files you will need for deployment are (`.Rprofile`, `.Renviron`, `a `DESCRIPTION`, `NAMESPACE`, `renv.lock`, and the contents of `inst/` and `R/`). If the data you wish to deploy with the app is in some other directory, this must also be selected for upload. +You may receive an warning message indicating that (file)paths outside of the project are referred +to by some scripts within this project. These arise in `vignettes/deploy.Rmd` and +`scripts/create_browser_data.R` and (provided these are the only files that refer to non-embedded +filepaths) you can safely ignore that warning (`deploy.Rmd` and `create_browser_data.Rmd` needn't +be uploaded to shinyapps.io anyway). + +Deployment may take a long time (around 5 minutes for deployment with the `wcdemo` example data). From 50435c3afcbc54d52528745202a37f717ba5f212 Mon Sep 17 00:00:00 2001 From: Russ Hyde Date: Thu, 12 Sep 2024 09:37:40 +0100 Subject: [PATCH 53/68] git: ignore dir for built vignettes & their index --- .Rbuildignore | 2 ++ .gitignore | 2 ++ 2 files changed, 4 insertions(+) diff --git a/.Rbuildignore b/.Rbuildignore index e48569c..d705a55 100644 --- a/.Rbuildignore +++ b/.Rbuildignore @@ -7,3 +7,5 @@ ^\.github$ ^LICENSE\.md$ _\.new\.png$ +^doc$ +^Meta$ diff --git a/.gitignore b/.gitignore index bfbeb5f..6d102f8 100644 --- a/.gitignore +++ b/.gitignore @@ -54,3 +54,5 @@ po/*~ # RStudio Connect folder rsconnect/ inst/doc +/doc/ +/Meta/ From 3ee45178646abcf7b383b9bea388b6f3c075fe9c Mon Sep 17 00:00:00 2001 From: Russ Hyde Date: Thu, 12 Sep 2024 09:50:23 +0100 Subject: [PATCH 54/68] doc: readme points to deploy vignette for deployment info --- README.md | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 97e89cb..d2557d2 100644 --- a/README.md +++ b/README.md @@ -160,7 +160,7 @@ To do this either: next section); or - copy the contents of that directory into `inst/app/www/data/` and re-install {tfpbrowser} -## Configuring the app +### Configuring the app Data presented by the app can be obtained from an arbitrary directory on the server. To configure the data-directory, use the environment variable `APP_DATA_DIR`. @@ -182,3 +182,22 @@ run_app() An alternative way to specify this data directory is to add the line `APP_DATA_DIR="/home/me/tfpdata/"` to a `.Renviron` file in the project root. + +## Deploying the app + +Please see the vignette `deploy` in {tfpbrowser} which provides a walk-through for deploying to +[shinyapps.io](https://www.shinyapps.io/). This is in `./vignettes/deploy.Rmd` in the {tfpbrowser} +repository. + +If working in the tfpbrowser repository, developers may need to build the vignettes: + +```r +# Build the vignette (Optional, if you haven't installed tfpbrowser) +# In the repository for {tfpbrowser} +devtools::build_vignettes() +pkgload::load_all() + +# View the vignette +vignette("deploy", package = "tfpbrowser") +``` + From 1c4e2d7c0c3e1d1ad5044a4ab5394f82d1783b43 Mon Sep 17 00:00:00 2001 From: Russ Hyde Date: Thu, 12 Sep 2024 10:08:24 +0100 Subject: [PATCH 55/68] fix lint in vignette --- vignettes/deploy.Rmd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vignettes/deploy.Rmd b/vignettes/deploy.Rmd index 22936c2..495d5a6 100644 --- a/vignettes/deploy.Rmd +++ b/vignettes/deploy.Rmd @@ -32,7 +32,7 @@ In this example, we have: - and are using `r R.version.string` ```{r} -dirs <- list( +dirs = list( data = "~/temp-data/wcdemo/", repo = "~/github/imp/tfpbrowser/", # A copy of the tfpscanner-processed data will be placed in From a3f102677f841af5a1ce83a04781a9dd52dabd5b Mon Sep 17 00:00:00 2001 From: Russ Hyde Date: Thu, 12 Sep 2024 10:11:38 +0100 Subject: [PATCH 56/68] fix path in vignette --- vignettes/deploy.Rmd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vignettes/deploy.Rmd b/vignettes/deploy.Rmd index 495d5a6..9b2b9f6 100644 --- a/vignettes/deploy.Rmd +++ b/vignettes/deploy.Rmd @@ -324,7 +324,7 @@ to deploy with the app is in some other directory, this must also be selected fo You may receive an warning message indicating that (file)paths outside of the project are referred to by some scripts within this project. These arise in `vignettes/deploy.Rmd` and `scripts/create_browser_data.R` and (provided these are the only files that refer to non-embedded -filepaths) you can safely ignore that warning (`deploy.Rmd` and `create_browser_data.Rmd` needn't +filepaths) you can safely ignore that warning (`deploy.Rmd` and `create_browser_data.R` needn't be uploaded to shinyapps.io anyway). Deployment may take a long time (around 5 minutes for deployment with the `wcdemo` example data). From b0710b760cd7e80bfb79226f75ec1ce6d776386a Mon Sep 17 00:00:00 2001 From: russHyde Date: Tue, 15 Oct 2024 14:41:58 +0100 Subject: [PATCH 57/68] env(create_browser_data): explicitly install rmarkdown --- scripts/create_browser_data.R | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/scripts/create_browser_data.R b/scripts/create_browser_data.R index fbbded7..e083050 100644 --- a/scripts/create_browser_data.R +++ b/scripts/create_browser_data.R @@ -46,7 +46,9 @@ treeview_args <- list( tfpbrowser_env <- jsonlite::read_json("renv.lock") -required_packages <- c("BiocVersion", "fastmap", "ggplot2", "ggiraph", "ggtree") +required_packages <- c( + "BiocVersion", "fastmap", "ggplot2", "ggiraph", "ggtree", "rmarkdown" +) required_versions <- Map( function(package, pkg_details) { paste0(package, "@", pkg_details[["Version"]]) @@ -59,11 +61,22 @@ required_versions <- Map( renv::use( # The versions of these packages should match those used in the 'renv.lock' for tfpbrowser, to - # ensure that the figure formatting + # ensure that the figure objects created by tfpscanner can be imported into tfpbrowser + # + # - ggtree for Bioconductor 3.16 depends upon a specific (outdated) version of ggplot2; + # later versions of ggtree have been rewritten to use newer ggplot2 versions. So if you ever + # update Bioconductor/R versions, you should start using the ggtree from Bioconductor that uses + # the newer version of ggplot2 + # + # - we force {rmarkdown} installation despite it being a transitive-dependency of tfpscanner. + # Without forcing it's installation, create_browser_data() runs in an env with no rmarkdown + # namespace + required_versions[["BiocVersion"]], required_versions[["ggplot2"]], required_versions[["fastmap"]], required_versions[["ggiraph"]], + required_versions[["rmarkdown"]], "YuLab-SMU/ggtree@daf3371", # These packages are required implicitly by {tfpscanner}, but not by {tfpbrowser} "svglite@2.1.3", From c0a9cbae5123563078cfa38d7b8af95422b93f8c Mon Sep 17 00:00:00 2001 From: russHyde Date: Tue, 15 Oct 2024 14:48:23 +0100 Subject: [PATCH 58/68] env(create_browser_data): ensure packages are installed without lockfiles, to writeable locations --- scripts/create_browser_data.R | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/scripts/create_browser_data.R b/scripts/create_browser_data.R index e083050..6a274c6 100644 --- a/scripts/create_browser_data.R +++ b/scripts/create_browser_data.R @@ -7,6 +7,11 @@ # - or `source("./scripts/create_browser_data.R")` in R # - Once finished, this script will explain how to use the created figures within tfpbrowser. +# Installation options +# - when on Windows, you will need the --no-lock option for installing packages so that any packages +# that require C source compilation are placed into writeable locations +options(INSTALL_opts = "--no-lock") + # User parameters ----------------------------------------------------------------------------- # File paths can be specified either relative to the working directory, or as absolute paths From 65dac85bc20fc72ca54e82064c9aa48d39c13e4d Mon Sep 17 00:00:00 2001 From: russHyde Date: Tue, 15 Oct 2024 14:57:32 +0100 Subject: [PATCH 59/68] doc: how to get MPI/Rmpi installed on a Windows machine (for use in create_browser_data) --- vignettes/deploy.Rmd | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/vignettes/deploy.Rmd b/vignettes/deploy.Rmd index 9b2b9f6..7f76133 100644 --- a/vignettes/deploy.Rmd +++ b/vignettes/deploy.Rmd @@ -94,6 +94,15 @@ Do not commit your `.Renviron` file using git! This file stores variables / secr required when the app runs. The variables will differ from one deployment to another, and the secrets should be secret! +#### MPI + +`create_browser_data.R` calls `{tfpscanner}`, which imports the `{Rmpi}` package. MPI is a code +parallelisation tool and must be installed on your machine before `{Rmpi}` can be installed. So +before running the `create_browser_data` script. + +Instructions for installing {Rmpi} can be found [here](https://www.stats.uwo.ca/faculty/yu/Rmpi/). +MPI for Windows can be obtained from [Microsoft](https://learn.microsoft.com/en-us/message-passing-interface/microsoft-mpi). + ### The scanner dataset The contents of the scanner dataset directory are as follows: From 7a08565c44000328d5ba658e2f31b0bf969981b7 Mon Sep 17 00:00:00 2001 From: Russ Hyde Date: Mon, 11 Mar 2024 15:19:53 +0000 Subject: [PATCH 60/68] refac: move creation of interactive ggiraph graphics into a function --- R/app_server.R | 48 ++++++--------------------------- R/ggiraph.R | 64 ++++++++++++++++++++++++++++++++++++++++++++ man/create_girafe.Rd | 29 ++++++++++++++++++++ 3 files changed, 101 insertions(+), 40 deletions(-) create mode 100644 R/ggiraph.R create mode 100644 man/create_girafe.Rd diff --git a/R/app_server.R b/R/app_server.R index f6c4318..8b6db4d 100644 --- a/R/app_server.R +++ b/R/app_server.R @@ -36,53 +36,21 @@ app_server = function(input, output, session) { # create ggiraph output from saved ggplot2 outputs output$treeview = ggiraph::renderGirafe({ shiny::req(input$widgetChoice) - # define tooltip - tooltip_css = paste0( - "background-color:black;", - "color:grey;", - "padding:14px;", - "border-radius:8px;", - "font-family:\"Courier New\",monospace;" - ) - # set options - if (input$widgetChoice == "tree-mutations.rds") { - girafe_options = list( - ggiraph::opts_selection(css = "fill:red;"), - ggiraph::opts_selection_inv(css = "fill:grey;"), - ggiraph::opts_sizing(rescale = FALSE), - ggiraph::opts_zoom(max = 5), - ggiraph::opts_tooltip( - css = tooltip_css, - use_fill = FALSE - ) - ) - } else { - girafe_options = list( - ggiraph::opts_selection(type = "single"), - ggiraph::opts_sizing(rescale = FALSE), - ggiraph::opts_zoom(max = 5), - ggiraph::opts_tooltip( - css = tooltip_css, - use_fill = FALSE - ) - ) - } + # set size w = shinybrowser::get_width() / 72 h = (1800 - 40) / 72 - # make tree - suppressWarnings( - ggiraph::girafe( - ggobj = imported_ggtree(), - width_svg = w, - height_svg = h, - options = girafe_options - ) + + create_girafe( + ggobj = imported_ggtree(), + widget_choice = input$widgetChoice, + width_svg = w, + height_svg = h, + suppress_warnings = TRUE ) }) %>% shiny::bindCache(input$widgetChoice) - # Mutation colouring ------------------------------------------------------ # disable dropdown unless mutation treeview diff --git a/R/ggiraph.R b/R/ggiraph.R new file mode 100644 index 0000000..0a0f5a2 --- /dev/null +++ b/R/ggiraph.R @@ -0,0 +1,64 @@ +#' Convert a ggplot object into an interactive {ggiraph} object +#' +#' @param ggobj The ggplot2/ggtree object. +#' @param widget_choice Scalar character. Describes the type of plot that is contained in +#' `ggobj`. Typically a file basename that includes the file extension, of the form "tree-XXX.rds" +#' (for `{ggtree}` objects) or "sina-XXX.rds" (for `{ggplot2}` scatter plots). +#' @param width_svg,height_svg Scalar numeric. The width/height of the output plot. +#' @param suppress_warnings Scalar logical. Should warnings from `ggiraph::girafe()` be printed +#' to the console? +create_girafe = function( + ggobj, + widget_choice, + width_svg, + height_svg, + suppress_warnings = FALSE) { + # define tooltip + tooltip_css = paste0( + "background-color:black;", + "color:grey;", + "padding:14px;", + "border-radius:8px;", + "font-family:\"Courier New\",monospace;" + ) + + # set options + if (widget_choice == "tree-mutations.rds") { + girafe_options = list( + ggiraph::opts_selection(css = "fill:red;"), + ggiraph::opts_selection_inv(css = "fill:grey;"), + ggiraph::opts_sizing(rescale = FALSE), + ggiraph::opts_zoom(max = 5), + ggiraph::opts_tooltip( + css = tooltip_css, + use_fill = FALSE + ) + ) + } else { + girafe_options = list( + ggiraph::opts_selection(type = "single"), + ggiraph::opts_sizing(rescale = FALSE), + ggiraph::opts_zoom(max = 5), + ggiraph::opts_tooltip( + css = tooltip_css, + use_fill = FALSE + ) + ) + } + + create_widget = function() { + ggiraph::girafe( + ggobj = ggobj, + width_svg = width_svg, + height_svg = height_svg, + options = girafe_options + ) + } + + # make tree + if (suppress_warnings) { + suppressWarnings(create_widget()) + } else { + create_widget() + } +} diff --git a/man/create_girafe.Rd b/man/create_girafe.Rd new file mode 100644 index 0000000..3776c91 --- /dev/null +++ b/man/create_girafe.Rd @@ -0,0 +1,29 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/ggiraph.R +\name{create_girafe} +\alias{create_girafe} +\title{Convert a ggplot object into an interactive {ggiraph} object} +\usage{ +create_girafe( + ggobj, + widget_choice, + width_svg, + height_svg, + suppress_warnings = FALSE +) +} +\arguments{ +\item{ggobj}{The ggplot2/ggtree object.} + +\item{widget_choice}{Scalar character. Describes the type of plot that is contained in +\code{ggobj}. Typically a file basename that includes the file extension, of the form "tree-XXX.rds" +(for \code{{ggtree}} objects) or "sina-XXX.rds" (for \code{{ggplot2}} scatter plots).} + +\item{width_svg, height_svg}{Scalar numeric. The width/height of the output plot.} + +\item{suppress_warnings}{Scalar logical. Should warnings from \code{ggiraph::girafe()} be printed +to the console?} +} +\description{ +Convert a ggplot object into an interactive {ggiraph} object +} From 9a66a6fe926fbf5c7d0d0b8f89d1012d1ab2f7cf Mon Sep 17 00:00:00 2001 From: Russ Hyde Date: Mon, 11 Mar 2024 15:29:15 +0000 Subject: [PATCH 61/68] refac: reduce some duplicated code for setting girafe options --- R/ggiraph.R | 33 +++++++++++++++------------------ 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/R/ggiraph.R b/R/ggiraph.R index 0a0f5a2..0b49ced 100644 --- a/R/ggiraph.R +++ b/R/ggiraph.R @@ -23,29 +23,26 @@ create_girafe = function( ) # set options - if (widget_choice == "tree-mutations.rds") { - girafe_options = list( + common_options = list( + ggiraph::opts_sizing(rescale = FALSE), + ggiraph::opts_zoom(max = 5), + ggiraph::opts_tooltip( + css = tooltip_css, + use_fill = FALSE + ) + ) + + plot_specific_options = if (widget_choice == "tree-mutations.rds") { + list( ggiraph::opts_selection(css = "fill:red;"), - ggiraph::opts_selection_inv(css = "fill:grey;"), - ggiraph::opts_sizing(rescale = FALSE), - ggiraph::opts_zoom(max = 5), - ggiraph::opts_tooltip( - css = tooltip_css, - use_fill = FALSE - ) + ggiraph::opts_selection_inv(css = "fill:grey;") ) } else { - girafe_options = list( - ggiraph::opts_selection(type = "single"), - ggiraph::opts_sizing(rescale = FALSE), - ggiraph::opts_zoom(max = 5), - ggiraph::opts_tooltip( - css = tooltip_css, - use_fill = FALSE - ) - ) + list(ggiraph::opts_selection(type = "single")) } + girafe_options = c(plot_specific_options, common_options) + create_widget = function() { ggiraph::girafe( ggobj = ggobj, From 3bd7e612cef7192ced26cc1b13952e8554db6deb Mon Sep 17 00:00:00 2001 From: Russ Hyde Date: Thu, 14 Mar 2024 11:31:06 +0000 Subject: [PATCH 62/68] feat: scatterplots are less tall than dendrograms --- R/app_server.R | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/R/app_server.R b/R/app_server.R index 8b6db4d..64f7a78 100644 --- a/R/app_server.R +++ b/R/app_server.R @@ -37,15 +37,20 @@ app_server = function(input, output, session) { output$treeview = ggiraph::renderGirafe({ shiny::req(input$widgetChoice) - # set size - w = shinybrowser::get_width() / 72 - h = (1800 - 40) / 72 + # set the relative height/width of the ggiraph-based graphs + is_dendrogram = grepl("^tree-", x = input$widgetChoice) + width = shinybrowser::get_width() / 72 + height = if (is_dendrogram) { + (1800 - 40) / 72 + } else { + (600 - 40) / 72 + } create_girafe( ggobj = imported_ggtree(), widget_choice = input$widgetChoice, - width_svg = w, - height_svg = h, + width_svg = width, + height_svg = height, suppress_warnings = TRUE ) }) %>% From c5d41db7f32fb1fbf8f46c46d24acfdc1ded7b7b Mon Sep 17 00:00:00 2001 From: russHyde Date: Fri, 18 Oct 2024 07:58:48 +0100 Subject: [PATCH 63/68] env: roll-back {promises} so we can install it on Kieran's computer --- renv.lock | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 57 insertions(+), 4 deletions(-) diff --git a/renv.lock b/renv.lock index 5890dfd..201ef15 100644 --- a/renv.lock +++ b/renv.lock @@ -89,6 +89,17 @@ ], "Hash": "4006dffe49958d2dd591c17e61e60591" }, + "PKI": { + "Package": "PKI", + "Version": "0.1-14", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "base64enc" + ], + "Hash": "f5b9c6b2f62f1fa3dd53fd1ddccbb241" + }, "R6": { "Package": "R6", "Version": "2.5.1", @@ -664,14 +675,14 @@ }, "glue": { "Package": "glue", - "Version": "1.7.0", + "Version": "1.8.0", "Source": "Repository", "Repository": "CRAN", "Requirements": [ "R", "methods" ], - "Hash": "e0b3a53876554bd45879e596cdb10a52" + "Hash": "5899f1eaa825580172bb56c08266f37c" }, "gridGraphics": { "Package": "gridGraphics", @@ -1024,6 +1035,18 @@ ], "Hash": "2bcca3848e4734eb3b16103bc9aa4b8e" }, + "packrat": { + "Package": "packrat", + "Version": "0.9.2", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "tools", + "utils" + ], + "Hash": "55ddd2d4a1959535f18393478b0c14a6" + }, "patchwork": { "Package": "patchwork", "Version": "1.2.0", @@ -1163,7 +1186,7 @@ }, "promises": { "Package": "promises", - "Version": "1.3.0", + "Version": "1.2.1", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -1175,7 +1198,7 @@ "rlang", "stats" ], - "Hash": "434cd5388a3979e74be5c219bcd6e77d" + "Hash": "0d8a15c9d000970ada1ab21405387dee" }, "ps": { "Package": "ps", @@ -1325,6 +1348,36 @@ ], "Hash": "4c8415e0ec1e29f3f4f6fc108bef0144" }, + "rsconnect": { + "Package": "rsconnect", + "Version": "1.3.1", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "PKI", + "R", + "cli", + "curl", + "digest", + "jsonlite", + "lifecycle", + "openssl", + "packrat", + "renv", + "rlang", + "rstudioapi", + "tools", + "yaml" + ], + "Hash": "90dc9ac04cec50f25657b077d4aaca57" + }, + "rstudioapi": { + "Package": "rstudioapi", + "Version": "0.17.0", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "fb9f5fce8f609e9b66f0bea5c783f88a" + }, "sass": { "Package": "sass", "Version": "0.4.9", From 4581cc4ab887e6f01e8c0a45677026449d22a566 Mon Sep 17 00:00:00 2001 From: russHyde Date: Fri, 18 Oct 2024 10:16:28 +0100 Subject: [PATCH 64/68] ensure library for create_browser_data goes into a tempdir --- scripts/create_browser_data.R | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/create_browser_data.R b/scripts/create_browser_data.R index 6a274c6..1560f99 100644 --- a/scripts/create_browser_data.R +++ b/scripts/create_browser_data.R @@ -88,7 +88,8 @@ renv::use( # This is the HEAD of `jumpingrivers:dev-202403` as of 2024-04-15 # If the commit ID is absent, this will use the latest 'master' branch # Including the commit ID allows us to use development-versions of the 'tfpscanner' package - "mrc-ide/tfpscanner@7ee27416d69ec3eaf7e4158f38c31125b3c38c7d" + "mrc-ide/tfpscanner@7ee27416d69ec3eaf7e4158f38c31125b3c38c7d", + library = normalizePath(file.path(tempdir(), "renv", "create_browser_data")) ) # Create the browser data / figures ----------------------------------------------------------- From bc3f17adc6bfbc24c50bfccaeb9d9984cc00ea57 Mon Sep 17 00:00:00 2001 From: Russ Hyde Date: Fri, 25 Oct 2024 19:33:49 +0100 Subject: [PATCH 65/68] create-browser-data: use tfpscanner version that has correct default for heatmap_offset --- scripts/create_browser_data.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/create_browser_data.R b/scripts/create_browser_data.R index 1560f99..2e92e6a 100644 --- a/scripts/create_browser_data.R +++ b/scripts/create_browser_data.R @@ -88,7 +88,7 @@ renv::use( # This is the HEAD of `jumpingrivers:dev-202403` as of 2024-04-15 # If the commit ID is absent, this will use the latest 'master' branch # Including the commit ID allows us to use development-versions of the 'tfpscanner' package - "mrc-ide/tfpscanner@7ee27416d69ec3eaf7e4158f38c31125b3c38c7d", + "mrc-ide/tfpscanner@cff68e483226bebe35436ee527fc61dcb5671951", library = normalizePath(file.path(tempdir(), "renv", "create_browser_data")) ) From f64a32aa6307ea658df4f81ebfd79fadc9466403 Mon Sep 17 00:00:00 2001 From: russHyde Date: Fri, 8 Nov 2024 11:56:43 +0000 Subject: [PATCH 66/68] fix: use server-side selectize for mut/seq selection; allows thousands of choices --- R/app_server.R | 13 +++++++------ R/app_ui.R | 10 ++++------ 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/R/app_server.R b/R/app_server.R index 64f7a78..05e91e3 100644 --- a/R/app_server.R +++ b/R/app_server.R @@ -19,10 +19,11 @@ app_server = function(input, output, session) { shiny::observe({ mutation_set = available_mutations(data_dir = data_dir) - shiny::updateSelectInput( + shiny::updateSelectizeInput( session = session, inputId = "mutationChoice", - choices = mutation_set + choices = mutation_set, + server = TRUE ) }) @@ -73,11 +74,11 @@ app_server = function(input, output, session) { ) # select input for sequences if (choice == "tree-sequences.rds") { - avail_seqs = data.table::as.data.table(available_sequences(data_dir)) - names(avail_seqs) = "Sequences" - shiny::updateSelectInput( + avail_seqs = available_sequences(data_dir) + shiny::updateSelectizeInput( inputId = "sequenceChoice", - choices = avail_seqs + choices = avail_seqs, + server = TRUE ) } }) diff --git a/R/app_ui.R b/R/app_ui.R index f60fae9..988003d 100644 --- a/R/app_ui.R +++ b/R/app_ui.R @@ -54,19 +54,17 @@ app_ui = function(request) { ), # choose type of mutation - shiny::selectInput( + shiny::selectizeInput( inputId = "mutationChoice", label = "Mutation", - choices = character(0), - selectize = FALSE + choices = character(0) ), # choose type of sequence - shiny::selectInput( + shiny::selectizeInput( inputId = "sequenceChoice", label = "Sequence", - choices = NULL, - selectize = FALSE + choices = character(0) ), ), shiny::div( From a8145620d57bef28f9a9e3e0ae0b446a8724ad5e Mon Sep 17 00:00:00 2001 From: russHyde Date: Mon, 12 May 2025 14:02:53 +0100 Subject: [PATCH 67/68] details of how to modify treeview format, the About page, and the pop-ups --- README.md | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/README.md b/README.md index d2557d2..8baf7fc 100644 --- a/README.md +++ b/README.md @@ -201,3 +201,42 @@ pkgload::load_all() vignette("deploy", package = "tfpbrowser") ``` +## Customising formatting and content + +### Treeviews + +The treeviews presented in this app are created by the `create_browser_data()` function in +{tfpscanner}. We recommend using the `scripts/create_browser_data.R` script in {tfpbrowser} +(described above) to run that function. + +`tfpscanner::create_browser_data()` respects all of the formatting arguments respects all of the +formatting arguments for `tfpscanner::treeview()`. See the documentation for +`tfpscanner::treeview()` for up-to-date details of the formatting options. The main options are + +- `dendrogram_colours` - A vector of colour-strings, this controls the branch-colour for the + dendrogram, and ranges (by default) from dark blue to dark red via an intermediate light-grey. +- `heatmap_width` - The width of the heatmap that is presented next to the dendrogram. This is + passed as the `width` argument to `ggtree::gheatmap()`. +- `heatmap_offset` - The distance between the dendrogram and the heatmap. This is passed as the + `offset` argument to `ggtree::gheatmap()`. +- `heatmap_lab_offset` - The offset distance for the genotype labels in the heatmap columns. This is + passed as the `colnames_offset_y` argument to `ggtree::gheatmap()`. +- `heatmap_fill` - A named vector of colours used to indicate the presence and absence of a genotype + in the heatmap. Defaults are FALSE: light-grey (for absence of the genotype), TRUE: dark-grey (for + presence of the genotype). Passed to `ggplot2::scale_fill_manual()` + +Custom values for these arguments can be set by manually editing the `treeview_args` list in +`./scripts/create_browser_data.R` (tfpbrowser), or directly, as arguments to the function +`tfpscanner::create_browser_data()`. + +### Pop-ups + +When a user hovers their mouse over a node in a treeview, a pop-up displaying statistics about that +node is displayed. To modify the information presented in this popup requires modifications to the +source code of {tfpscanner}. See the `tfpscanner::append_interactivity_data()` function. + +### 'About' text + +The text that is presented in the "About" panel of the app can be modified by updating the file +`./inst/app/www/content/about.md` in {tfpbrowser}. This is a markdown document that gets rendered +in HTML by the tfpbrowser application. From 3cf17b158001c9a485d29d2f23ff85b844aed920 Mon Sep 17 00:00:00 2001 From: Russ Hyde Date: Mon, 12 May 2025 14:24:42 +0100 Subject: [PATCH 68/68] ci: drop new explicit-return-linter from linters, since it disagrees with existing code --- .lintr | 1 + 1 file changed, 1 insertion(+) diff --git a/.lintr b/.lintr index 61c3930..79f75a1 100644 --- a/.lintr +++ b/.lintr @@ -2,6 +2,7 @@ linters: linters_with_defaults( assignment_linter = NULL, object_name_linter = NULL, line_length_linter = line_length_linter(120), + return_linter = NULL, undesirable_operator_linter = undesirable_operator_linter( modify_defaults( default_undesirable_operators,