Utility functions to be used across packages #13
dhersz
started this conversation in
Show and tell
Replies: 1 comment
-
Thanks @dhersz, another brilliant development. The separation of check and assert functions is particularly clever and useful. |
Beta Was this translation helpful? Give feedback.
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
Hello all.
I also included in
{gtfsio}
a few functions that I think can be very useful for our packages.Let's say, for example, that a function you wrote requires that the GTFS object has a
shapes
element inside it. You can useassert_files_exist()
:If you don't want an error to be raised, and just need a logical instead, you can use
check_files_exist()
:I already implemented this function in
{gtfstools}
, but I figured out it might be useful for all of us.gtfstools::get_trip_speed()
, for example, requires that thestop_times
table is present, otherwise it won't work (I use{checkmate}
over there, but I changed the implementation on{gtfsio}
to not require an additional dependency).Use
assert_fields_exist
andcheck_fields_exist
for a similar check, but now more specific - if a given column of a table exist (which is in fact the one used in the function I linked to above):Even more detailed: is this field formatted as I need? What if I need it to be a character, but it's numeric? Use
assert_fields_types()
andcheck_fields_types()
:Why is this relevant?
If the fields/files we need are not present in a given GTFS, then our functions may not behave like expected. Even worse, if we don't check for these cases then it might very well not be clear to the final user why the function is not behaving properly (let's say that a function requires an id to be a character - it can be a pain to diagnose that we're not able to run it because our ids are formatted as, let's say, integers).
Second, and even cooler, these functions are great for package interoperability. All packages that currently represent GTFS text files as
data.table
s, for example, could simply add some calls to them before proceeding with an operation. What do I mean?For example,
{gtfsrouter}
requires atransfers
table (AFAIK) to work properly. Well, then before proceeding with any operations it could add a call toassert_files_exist("transfers")
. But what's so cool about it? Because then{gtfsrouter}
could very well use a GTFS object created bygtfstools::read_gtfs()
orgtfs2gps::read_gtfs()
, as long as it has a transfers table (and any other required files/fields as well). So we don't need 3 classes for 3 different packages, we just need 1 class and some basic checks!The interoperability between
{tidytransit}
and the others might still be a bit more problematic, because{data.table}
syntax include some operators that don't work withtibble
s. But, as far as I know, you can still use{dplyr}
syntax to manipulatedata.table
s (I know for a fact that at least some basic operation withmutate
,select
and similar functions work, not sure if more complex operations do), so{tidytransit}
could still work with objects created bydata.table
-dependent packages. Again, as long as the appropriate columns are present, and formatted correctly.Do you have any suggestions of other utility functions that might be useful to all of our packages?
Cheers!
Beta Was this translation helpful? Give feedback.
All reactions