【问题标题】:How do I assign variables to be available when an R package is loaded?加载 R 包时,如何分配可用的变量?
【发布时间】:2023-03-08 03:08:01
【问题描述】:

我想出了如何制作一个包含一些我经常使用的调色板的包。我修改了this 博客文章中的代码以使其正常工作。以下代码可重现。

我的具体问题是,这仅在我运行下面的函数 create_palette()create_palette_list() 时才有效。这些函数,目前的结构是为了使两个对象必须可用于函数scale_color_mine()scale_fill_mine() 才能工作。所以,我的问题是如何修改包wlucolors 中的代码,以便在加载包wlucolors 的那一刻使这些对象可用。

我认为这与使全局变量可用于其他一些函数有关,并且可能将某些内容分配给全局环境,但我真的不确定。

感谢您提供任何见解。

remotes::install_github("sjkiss/wlucolors")
library(wlucolors)

library(tidyverse)
create_palette()
create_palette_list()
data("mtcars")
ggplot(mtcars, aes(x = hp, y = mpg, col = cyl)) +
  geom_point() +
  scale_color_mine(palette = "federal", discrete = F)
df <- data.frame(party = c("lib", "con", "bq", "ndp", "green"),
  voteshare = c(12, 15, 15, 16, 18))
ggplot(df, aes(x = party, y = voteshare, fill = party)) +
  geom_col() +
  scale_fill_mine(palette = "federal", discrete = T)
df <- data.frame(party = c("lib", "con", "bq", "ndp", "green"),
  voteshare = c(12, 15, 15, 16, 18))
ggplot(df, aes(x = party, y = voteshare, fill = party)) +
  geom_col() +
  scale_fill_mine(palette = "federal", discrete = T)

【问题讨论】:

  • 你在找.onLoadhere吗?

标签: r ggplot2


【解决方案1】:

虽然.onLoad是一种选择,但我认为这不是推荐的方法(我们可以阅读here了解.onLoad的主要用途)。

问题是,您希望my_colors 可供用户使用吗?或者您只是希望它可用作您的函数的内部数据。通过查看您的 github 存储库,我认为是后者,但让我们通过这两个选项。它们都在@Waldi 的回答中在上面的链接中进行了解释。

  1. 将颜色和调色板作为external data 提供给用户。您可以使用usethis::use_data(my_colors) 执行此操作,然后您只需要记录数据,但不要在文档中使用@export。在描述文件中,您可以设置LazyData: true,这样数据只会在实际使用时才加载到内存中。在这种情况下,您的函数可以使用这些数据,但它也可供用户使用。

  2. 或者,您可以将颜色和调色板作为internal data 用于您的功能。这可以使用 {usethis} 中的相同函数来完成,唯一的区别是我们将 internal 参数设置为 TRUEusethis::use_data(my_colors, internal = TRUE)。现在您可以在函数内部引用数据my_palettes,函数参数可用于子集my_palettes

例如:

scale_color_mine(palette = "federal")

会在内部做:

scale_color_mine  <- function(palette) {
# do stuff here
cur_palette <- my_palettes[[palette]]
# do stuff here
}

在这种情况下,用户将无法访问数据,但好在my_colorsmy_palettes 不会填充命名空间。

【讨论】:

  • 这是一个非常巧妙的方法。另一种选择是将调色板存储在函数内的向量中,RColorBrewer::brewer.pal 也是如此。这是允许在scale_..._brewer 中选择不同调色板的底层函数——它使用switch()。 @spindoctor 。我还要检查 ggplot2 如何处理这个调色板。这很复杂。
  • @tjebo:这实际上可能是最好的选择,一个内部数据生成函数。我通常在闪亮的应用程序中使用它们,但对于这个问题,它可能是最合适的。请建议它作为答案。
  • 在查看了源代码之后,我认为 OP 的问题更多的是其他更基本的性质。请参阅我的建议答案。
  • 谢谢。这一切都非常有用。我学到了很多!我根本不会把这个提交给 CRAN,最多只是和同事分享这个包。
【解决方案2】:

如果您想使my_colors 向量可用,而无需按照cmets 中的建议使用.onLoad 将其写入当前环境,您可以在包的/R 目录中为其创建一个my_colors.R 文件, see:

my_colors <- c(
  `liberal`        = "darkred",
  `conservative`   = "darkblue",
  `ndp`            = "orange",
  `bq`             = "cyan",
  `green`          = "darkgreen",
  `laurier1`       = "darkorchid",
  `laurier2`       = "gold")

#' My colors
#'
#' available colors vector
#'
#' @format a vector with the colors I need
#' @export

"my_colors"

【讨论】:

    【解决方案3】:

    您尚未将任何函数导出到命名空间。我认为您已经在那里,但是您不能“看到”该对象,这没关系。包裹将能够看到它。它被保存在内部。

    你真的应该检查how to document packages。 - 即使不是针对 CRAN(这完全是另一回事),您也需要为自己正确记录这些功能。我个人使用 roxygen2 作为文档,可能大多数人都这样做。查看 Hadley 的精彩书籍,我也学到了很多 from Karl Broman's blog。我个人还将#' @keywords internals标签添加到函数中,这样它就不会出现在您应该将其上传到CRAN时生成的pdf手册中。

    如果您希望在加载命名空间时用户(可以只是您自己)可以使用对象,请使用#' @export。如果您不希望它可用,请不要使用该标签,但您的包仍然可以使用这些功能。 (您可以通过键入 wlucolors:::create_palette 来检查,这应该会在安装(甚至不加载)您的包后显示您的功能。

    另外注意,请确保您始终正确引用其他函数,例如,discrete_scale 变为 ggplot2::discrete_scale,然后您还需要在标题中告知您是从 ggplot2 导入的。如果您为 CRAN 编写包,则尤其如此。 (如果您不这样做,您的包裹将不会被接受)。

    另外 - 不要进行全局分配 - 这是非常糟糕的做法。 Check R inferno圈6

    【讨论】:

      猜你喜欢
      • 2014-03-02
      • 1970-01-01
      • 1970-01-01
      • 2021-01-04
      • 1970-01-01
      • 2011-12-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多