How to use files in inst/extdata? R Package check prevent to use system.file() in R 3.6
Asked Answered
M

1

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.

Mealie answered 21/8, 2020 at 21:47 Comment(3)
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?Shamefaced
@Shamefaced 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.Mealie
Without some sort of reproducible example, it will be difficult to provide any help. According to this you should still be able to use system.file as long as it's not at the top level of your code.Shamefaced
L
4

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) {
    ns = topenv()
    ns$datafile = system.file("extdata", "file.csv", package = "mypackage")
}

(More details can be found in a related answer.)

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 fine.

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.

Loyceloyd answered 23/5, 2021 at 22:23 Comment(2)
How does this work when loading a binary package? According to this the .onLoad method might fail in that case, but I'm not sure why.Ishii
@Ishii 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.Loyceloyd

© 2022 - 2024 — McMap. All rights reserved.