4

I am writing the R package and trying to use external files. I placed it in inst/extdata and use system.file("extdata", "file.csv", package = "mypackage") to load the file in my function. The official manuals describe only this way to get data from inst/extdata.

But during building I got the error ERROR: hard-coded installation path: please report to the package maintainer and use '--no-staged-install'

Forums said that system.file() is bad practice, but how I should use row data in my package?

This problem is occurred after updates in 2018. I found that I can use StagedInstall: no in DESCRIPTION file, but this is cheating, isn't it?

I want to use raw files inside functions (as precalculated static tables) and in examples as input files. My R version is 3.6.2.

  • Is this package on github or is there somewhere we can look at it and try it ourselves? Are you saving the result of the `system.file()` call somewhere? Or how are you using it? – MrFlick Aug 21 '20 at 22:03
  • @MrFlick No, it just local package now. Yes, I load the table using the path from `system.file()` inside my function. But now I can't pass the CMD check. – Marina Chepeleva Aug 22 '20 at 11:20
  • Without some sort of reproducible example, it will be difficult to provide any help. According to [this](https://developer.r-project.org/Blog/public/2019/02/14/staged-install/) you should still be able to use `system.file` as long as it's not at the top level of your code. – MrFlick Aug 22 '20 at 19:04

1 Answers1

3

The error occurs because the package source code is executed at installation time, not when the package is loaded. Furthermore, starting with R 3.6, packages are installed inside a temporary path, not at their actual, final installation location.

As a consequence, system.file will return a bogus path when called directly inside a package at file scope (i.e. not inside a function). This is what the error message you’re getting is trying to convey.

Once you know this, the solution is rather straightforward: don’t call system.file during package building. Instead, call it during package loading; that is, inside .onLoad:

.onLoad = function (libname, pkgname) {
    datafile = system.file("extdata", "file.csv", package = "mypackage")
    assign('datafile', datafile, envir = topenv())
}

This causes the variable datafile to be created inside your package namespace, and you can now access it from elsewhere.

Forums said that system.file() is bad practice

No, using system.file is definitely not bad practice; on the contrary, it is required to access your package extdata. What’s bad practice is calling the function at file scope. But calling it inside a function is file.

I found that I can use StagedInstall: no in DESCRIPTION file, but this is cheating, isn't it?

Indeed, that’s “cheating” and definitely not recommended as a proper solution.

Konrad Rudolph
  • 530,221
  • 131
  • 937
  • 1,214
  • How does this work when loading a binary package? According to [this](https://developer.r-project.org/Blog/public/2019/02/14/staged-install/) the `.onLoad` method might fail in that case, but I'm not sure why. – jerome Oct 12 '21 at 20:33
  • @jerome You’re misunderstanding the article. It works the same for binary packages. The error mentioned by the article is in third party tools (no idea which though), not in the package. – Konrad Rudolph Oct 12 '21 at 22:32