-
-
Notifications
You must be signed in to change notification settings - Fork 42
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Remove library
calls from get_rcode_header
in favour of manual specification
#950
Comments
Questions:
|
I think for all attached. Even though there is
Isn't such warning gonna be presented on an app start? If someone created a code on one environment, but then releases it somewhere else, (s)he will see that he is not able to run the app, or one of the modules will fail?
Is |
I don't think auto-installing is a good idea.
The reproducible code will not be run in an app, it will be taken from the report and run wherever.
Good point. |
Ok, so it's either a decision if we just leave a warning that some packages are missing, or we allow them to be installed, but in both cases we do put a code that checks if needed packages are installed. I'm fine setting up a note, on which packages are missing and pasting a message to be copy-pasted on how to install them. How does that sound? |
I think it's reasonable. |
On the main topic I don't see a reason why we do not allow to specify libraries in |
We do allow that, in fact we recommend it. We modified ALL examples to show that just this month. |
Alrighty, so what's left in here to decide (and potentially implement)?
|
If these both hold true, there will be duplicates. I am for putting the responsibility for I still believe we should check for loaded namespaces and warn if they are not installed. Does anyone have any thoughts on this? |
Currently there is little possibility for duplicate On one hand I'd like to leave this responsibility with the app developer. It's just a matter of moving the library around. However, we would need to change the current inheritance to prevent inheritance of Right? On the other hand, we can also remove duplicates library calls that exist on This would require some regex magic, but it would be doable.
Agree and on it!! Otherwise it may end being frustrating to the user. |
The duplicates are caused by The problem is EDIT: I the app dev decides to attach a package more than once, that's on them.
I would say the opposite: keep the former, remove the latter. The purpose is to recreate the search path and packages that are on the path are not attached again. |
So the end goal here is to stop using
Sure thing, I was considering keeping first occurence while trying to group all libraries together, but filtering out from there will be fine |
I believe so. As far as I know (this was before my time), |
This very much doable, but we will end up with {teal}.* and such in the "required" packages to have installed. By "and such" it will have a bunch of weird dependencies not related with reproducible code (such as AFAIK it's not possible to get the namespaces attached/loaded to a given environment. One way would be to track differences in loadedNamespaces in Q: Do you know of any way of doing this? Toy example of trackingI think this is a bad idea, just showing here for the caveat marked with the orange circle in the comments (🟠) library(teal.data)
#> Loading required package: teal.code
qenv2 <- function() {
q_env <- new.env(parent = emptyenv())
lockEnvironment(q_env, bindings = TRUE)
methods::new("qenv", env = q_env)
}
pkgs <- \() vapply(utils::sessionInfo()$otherPkgs, base::`[[`, character(1L), "Package", USE.NAMES = FALSE)
slot_update <- \(q_slot) {
q_slot$namespace_slot <- union(q_slot$namespace_slot, setdiff(loadedNamespaces(), q_slot$previous_loaded))
q_slot$previous_loaded <- loadedNamespaces() |> sort()
q_slot$attached_slot <- union(q_slot$attached_slot, setdiff(pkgs(), q_slot$previous_attached))
q_slot$previous_attached <- pkgs() |> sort()
q_slot
}
q_slot <- structure(
list(
previous_loaded = loadedNamespaces() |> sort(),
previous_attached = pkgs() |> sort(),
attached_slot = character(0L),
namespace_slot = character(0L)
)#, class = c("q_slot", "list")
)
# 🟠 Initial q_slot has `magrittr`, `rlang` and others that won't be detected in the differences
# even if needed
q_slot
#> $previous_loaded
#> [1] "backports" "base" "checkmate" "cli" "compiler"
#> [6] "datasets" "digest" "evaluate" "fastmap" "fs"
#> [11] "glue" "graphics" "grDevices" "htmltools" "knitr"
#> [16] "lifecycle" "magrittr" "methods" "purrr" "R.cache"
#> [21] "R.methodsS3" "R.oo" "R.utils" "reprex" "rlang"
#> [26] "rmarkdown" "rstudioapi" "stats" "styler" "teal.code"
#> [31] "teal.data" "tools" "utils" "vctrs" "withr"
#> [36] "xfun" "yaml"
#>
#> $previous_attached
#> [1] "teal.code" "teal.data"
#>
#> $attached_slot
#> character(0)
#>
#> $namespace_slot
#> character(0)
q1 <- qenv() |> within({
aa <- 1 + 2
})
q_slot <- slot_update(q_slot)
q_slot
#> $previous_loaded
#> [1] "backports" "base" "checkmate" "cli" "compiler"
#> [6] "datasets" "digest" "evaluate" "fastmap" "fs"
#> [11] "glue" "graphics" "grDevices" "htmltools" "knitr"
#> [16] "lifecycle" "magrittr" "methods" "purrr" "R.cache"
#> [21] "R.methodsS3" "R.oo" "R.utils" "reprex" "rlang"
#> [26] "rmarkdown" "rstudioapi" "stats" "styler" "teal.code"
#> [31] "teal.data" "tools" "utils" "vctrs" "withr"
#> [36] "xfun" "yaml"
#>
#> $previous_attached
#> [1] "teal.code" "teal.data"
#>
#> $attached_slot
#> character(0)
#>
#> $namespace_slot
#> character(0)
q2 <- q1 |> within({
library(ggplot2)
p <- ggplot(data = data.frame(x = 1:10, y = 1:10)) + geom_point(aes(x = x, y = y))
})
q_slot <- slot_update(q_slot)
q_slot
#> $previous_loaded
#> [1] "backports" "base" "checkmate" "cli" "colorspace"
#> [6] "compiler" "datasets" "digest" "dplyr" "evaluate"
#> [11] "fansi" "fastmap" "fs" "generics" "ggplot2"
#> [16] "glue" "graphics" "grDevices" "grid" "gtable"
#> [21] "htmltools" "knitr" "lifecycle" "magrittr" "methods"
#> [26] "munsell" "pillar" "pkgconfig" "purrr" "R.cache"
#> [31] "R.methodsS3" "R.oo" "R.utils" "R6" "reprex"
#> [36] "rlang" "rmarkdown" "rstudioapi" "scales" "stats"
#> [41] "styler" "teal.code" "teal.data" "tibble" "tidyselect"
#> [46] "tools" "utf8" "utils" "vctrs" "withr"
#> [51] "xfun" "yaml"
#>
#> $previous_attached
#> [1] "ggplot2" "teal.code" "teal.data"
#>
#> $attached_slot
#> [1] "ggplot2"
#>
#> $namespace_slot
#> [1] "gtable" "dplyr" "tidyselect" "scales" "ggplot2"
#> [6] "R6" "generics" "tibble" "munsell" "pillar"
#> [11] "utf8" "grid" "fansi" "colorspace" "pkgconfig"
q3 <- q2 |> within({
f <- ggrepel::geom_label_repel
})
q_slot <- slot_update(q_slot)
q_slot
#> $previous_loaded
#> [1] "backports" "base" "checkmate" "cli" "colorspace"
#> [6] "compiler" "datasets" "digest" "dplyr" "evaluate"
#> [11] "fansi" "fastmap" "fs" "generics" "ggplot2"
#> [16] "ggrepel" "glue" "graphics" "grDevices" "grid"
#> [21] "gtable" "htmltools" "knitr" "lifecycle" "magrittr"
#> [26] "methods" "munsell" "pillar" "pkgconfig" "purrr"
#> [31] "R.cache" "R.methodsS3" "R.oo" "R.utils" "R6"
#> [36] "Rcpp" "reprex" "rlang" "rmarkdown" "rstudioapi"
#> [41] "scales" "stats" "styler" "teal.code" "teal.data"
#> [46] "tibble" "tidyselect" "tools" "utf8" "utils"
#> [51] "vctrs" "withr" "xfun" "yaml"
#>
#> $previous_attached
#> [1] "ggplot2" "teal.code" "teal.data"
#>
#> $attached_slot
#> [1] "ggplot2"
#>
#> $namespace_slot
#> [1] "gtable" "dplyr" "tidyselect" "scales" "ggplot2"
#> [6] "R6" "generics" "tibble" "munsell" "pillar"
#> [11] "utf8" "grid" "fansi" "colorspace" "pkgconfig"
#> [16] "Rcpp" "ggrepel" Created on 2023-12-19 with reprex v2.0.2 |
This subject was broached in a different issue. We do not want to automate installation. The usual |
Nonono, There's no installation automation, if you look closely at the screenshot it's At the end is the snippet that I was using. We could use a Calling library for each item in Growth of loadedNamespacesFilter(
function(.x) .x %in% installed.packages(priority = NA_character_)[, "Package"],
c(loadedNamespaces())
)
#> character(0)
suppressMessages(library(teal))
Filter(
function(.x) .x %in% installed.packages(priority = NA_character_)[, "Package"],
c(loadedNamespaces())
)
#> [1] "backports" "digest" "later" "R6"
#> [5] "httpuv" "fastmap" "teal.transform" "magrittr"
#> [9] "teal.data" "glue" "shiny" "htmltools"
#> [13] "logger" "lifecycle" "teal" "teal.code"
#> [17] "promises" "cli" "xtable" "teal.logger"
#> [21] "checkmate" "mime" "ellipsis" "yaml"
#> [25] "Rcpp" "teal.slice" "rlang"
suppressMessages(library(ggplot2))
Filter(
function(.x) .x %in% installed.packages(priority = NA_character_)[, "Package"],
c(loadedNamespaces())
)
#> [1] "gtable" "teal.slice" "dplyr" "promises"
#> [5] "tidyselect" "Rcpp" "later" "scales"
#> [9] "yaml" "fastmap" "mime" "teal.code"
#> [13] "ggplot2" "R6" "generics" "backports"
#> [17] "teal" "checkmate" "tibble" "logger"
#> [21] "munsell" "shiny" "pillar" "rlang"
#> [25] "utf8" "httpuv" "teal.data" "cli"
#> [29] "withr" "magrittr" "digest" "xtable"
#> [33] "lifecycle" "teal.logger" "vctrs" "glue"
#> [37] "fansi" "colorspace" "teal.transform" "pkgconfig"
#> [41] "ellipsis" "htmltools"
Snippet generation# ...
missing_code <- substitute(
missing <- Filter(function(.x) ! .x %in% installed.packages()[, "Package"], pkgs),
list(pkgs = sort(
Filter(
function(.x) .x %in% installed.packages(priority = NA_character_)[, "Package"],
loadedNamespaces()
)
))
)
warning_code <- quote(
if (length(missing))
stop(paste(
"Some of the libraries needed to reproduce the results are not installed:",
paste0(" Please use: install.packages(c(", paste0("'", missing, "'", collapse = ", "), "))"),
sep = "\n"
))
)
# ... Error message (I'm mocking that pkg1 and pkg2 are loaded)Error in eval(warning_code) :
Some of the libraries needed to reproduce the results are not installed:
Please use: install.packages(c('pkg1', 'pkg2'))
|
I know the issue has been abandoned for some time, but maybe work on this one can also bring a solution to this one #593 |
Closing as issue has been addressed. We don't automatically append libraries to the r-code anymore. |
In the preprocessing app developer can add
library(pkg)
calls in theeval_code/within
call. Thanks to this code inqenv/teal_data
will containlibrary
calls, so will be more reproducible.However, when sending data to the module another list of libraries is appended. We need to decide about who should be responsible for listing
libraries
used in a code (app developer) or (teal).::
teal
can add all the libraries according to what is loaded/attached in a sessionWe need to find robust way to do manage this.
The text was updated successfully, but these errors were encountered: