Christoph
Christoph

Reputation: 7063

Use data.table in functions/packages (With roxygen)

I am quite new to R but it seems, this question is closely related to the following post 1, 2, 3 and a bit different topic 4. Unfortunately, I have not enough reputation to comment right there. My problem is that after going through all the suggestions there, the code still does not work:

  1. I included "Depends" in the description file
  2. I tried the second method including a change of NAMESPACE (Not reproducable)
  3. I created a example package here containing a very small part of the code which showed a bit different error ("J" not found in routes[J(lat1, lng1, lat2, lng2), .I, roll = "nearest", by = .EACHI] instead of 'lat1' not found in routes[order(lat1, lng1, lat2, lng2, time)])
  4. I tested all scripts using the console and R-scripts. There, the code ran without problems.

Thank you very much for your support!

Edit: @Roland

  1. You are right. Roxygen overwrites the namespace. You have to include #' @import data.table to the function. Do you understand, why only inserting Depends: data.table in the DESCRIPTION file does not work? This might be a useful hint in the documentation or did I miss it?
  2. It was missleading that changing to routes <- routes[order("lat1", "lng1", "lat2", "lng2", "time")] helped at least a bit as this line was suddenly no problem any more. Is it correct, that in this case data.frame order is used? I will see how far I get now. I will let you know the final result...

Upvotes: 3

Views: 558

Answers (2)

Christoph
Christoph

Reputation: 7063

This is more in addition to the answers above: I found this to be really useful...

From the docs [Hadley-description](http://r-pkgs.had.co.nz/description.html und)

Imports packages listed here must be present for your package to work. In fact, any time your package is installed, those packages will, if not already present, be installed on your computer (devtools::load_all() also checks that the packages are installed).

Adding a package dependency here ensures that it’ll be installed. However, it does not mean that it will be attached along with your package (i.e., library(x)). The best practice is to explicitly refer to external functions using the syntax package::function(). This makes it very easy to identify which functions live outside of your package. This is especially useful when you read your code in the future.

If you use a lot of functions from other packages this is rather verbose. There’s also a minor performance penalty associated with :: (on the order of 5$\mu$s, so it will only matter if you call the function millions of times).

From the docs Hadley-namespace

NAMESPACE also controls which external functions can be used by your package without having to use ::. It’s confusing that both DESCRIPTION (through the Imports field) and NAMESPACE (through import directives) seem to be involved in imports. This is just an unfortunate choice of names. The Imports field really has nothing to do with functions imported into the namespace: it just makes sure the package is installed when your package is. It doesn’t make functions available. You need to import functions in exactly the same way regardless of whether or not the package is attached.
... this is what I recommend: list the package in DESCRIPTION so that it’s installed, then always refer to it explicitly with pkg::fun(). Unless there is a strong reason not to, it’s better to be explicit. It’s a little more work to write, but a lot easier to read when you come back to the code in the future. The converse is not true. Every package mentioned in NAMESPACE must also be present in the Imports or Depends fields.

Upvotes: 0

jangorecki
jangorecki

Reputation: 16697

Answering your questions (after edit).

  1. Quoting R exts manual:

Almost always packages mentioned in ‘Depends’ should also be imported from in the NAMESPACE file: this ensures that any needed parts of those packages are available when some other package imports the current package.

So you still should have import in NAMESPACE despite the fact if you depends or import data.table.

  1. The order call doesn't seems to be what you expect, try the following:

order("lat1", "lng1", "lat2", "lng2", "time")

library(data.table)
data.table(a=2:1,b=1:2)[order("a","b")]

In case of issues I recommend to start debugging by writing unit test for your expected results. The most basic way to put unit tests in package is just plain R script in tests directory having stopifnot(...) call. Be aware you need to library/require your package at the start of the script.

Upvotes: 4

Related Questions