如何在R包中包含和显示图像?

How to include and display images in R package?

我正在尝试打包一个显示带有徽标(png 格式)的模态的闪亮模块。为此,我创建了一个“inst/www”目录来存放徽标文件。目录树看起来像这样:

├─ DESCRIPTION
├─ inst
│   └── www
│       └── logo.png
├── man
│   └── test.Rd
├── NAMESPACE
├── packagetest.Rproj
└── R
    └── test.R

但是,在构建和安装之后,该包似乎无法从我放置“logo.png”的预定义目录中读取。相反,它从我从包中插入函数的主项目中读取。包的testUI()函数是这样的:

testUI <- function(id) {
  ns <- NS(id)

  shiny::showModal(
    modalDialog(
      title = img(src="inst/www/logo.png", style="display:block; margin-left:auto; margin-right:auto;"),
      br(),
      fluidRow(
        column(6, align="center", offset = 3,
               textInput(ns("username"), label = NULL, placeholder = "Username"),
               passwordInput(ns("password"), label = NULL, placeholder = "Password")
        )
      ),
      footer = (
        fluidRow(
          column(6, align="center", offset = 3,
                 actionButton(ns("signin"),"Sign in")
          )
        )
      )
    )
  )
}

从我在其他项目中看到的情况来看,“inst”文件夹似乎是可行的方法,但我对 R 包还是陌生的,所以我真的不知道我在做什么。非常感谢任何帮助,谢谢!

...差不多一年后,我在处理需要包含图像资产的实际包时找到了问题的答案!根据 official R package documentation section on the inst folder:

To find a file in inst/ from code use system.file(). For example, to find inst/extdata/mydata.csv, you’d call system.file("extdata", "mydata.csv", package = "mypackage"). Note that you omit the inst/ directory from the path. This will work if the package is installed, or if it’s been loaded with devtools::load_all().

在这种情况下,假设我的包名为“testpackage”:

testUI <- function(id) {
  ns <- NS(id)

  shiny::showModal(
    modalDialog(
      title = img(
                src=system.file("www/logo.png", package = "testpackage"),
                style="display:block; margin-left:auto; margin-right:auto;"
      ),
      br(),
      fluidRow(
        column(6, align="center", offset = 3,
               textInput(ns("username"), label = NULL, placeholder = "Username"),
               passwordInput(ns("password"), label = NULL, placeholder = "Password")
        )
      ),
      footer = (
        fluidRow(
          column(6, align="center", offset = 3,
                 actionButton(ns("signin"),"Sign in")
          )
        )
      )
    )
  )
}

请注意,我没有使用官方示例中的逗号分隔目录结构,因为我发现输入完整的相对路径更直观,请记住:

When a package is installed, everything in inst/ is copied into the top-level package directory. In some sense inst/ is the opposite of .Rbuildignore - where .Rbuildignore lets you remove arbitrary files and directories from the top level, inst/ lets you add them. You are free to put anything you like in inst/ with one caution: because inst/ is copied into the top-level directory, you should never use a subdirectory with the same name as an existing directory. This means that you should avoid inst/build, inst/data, inst/demo, inst/exec, inst/help, inst/html, inst/inst, inst/libs, inst/Meta, inst/man, inst/po, inst/R, inst/src, inst/tests, inst/tools and inst/vignettes.

希望这对遇到同样问题的其他人有所帮助:)