Skip to content

[R-pkg-devel] A function in one of my package is now a method in base R

6 messages · Shu Fai Cheung, Duncan Murdoch, Deepayan Sarkar +1 more

#
Hi All,

I have a function (not a method), sort_by(), in one of my packages. A
new method with the same name was introduced in the recent versions of
R (4.4.0 or 4.4.1, I forgot which one), resulting in potential
conflict in users' code.

Certainly, users can simply use pkg_name::function_name() to solve the
conflict. However, I would like to be consistent with base R and so I
am thinking about converting my function to a method for the class for
which my function is intended to work on (e.g, est_table).

However, my function has arguments different from those in the base R sort_by():

Base R:

sort_by(x, y, ...)

My function:

sort_by(
  object,
  by = c("op", "lhs", "rhs"),
  op_priority = c("=~", "~", "~~", ":=", "~1", "|", "~*~"),
  number_rows = TRUE
)

If I write the function sort_by.est_table(), I would need to match the
argument names of the base R sort_by(). However, I think it is a bad
idea to rename the arguments in my function and it will break existing
code.

Any suggestions on how I should proceed? Is keeping my function as-is
a better option? Name conflict is not unusual across packages and so
users need to learn how to solve this problem anyway. Nevertheless, if
possible, I would like to solve the conflict internally such that
users do not need to do anything.

Regards,
Shu Fai Cheung
#
On 2024-08-02 10:35 a.m., Shu Fai Cheung wrote:
I think it's impossible to avoid some inconvenience to your users.

Here's what I'd suggest:

- Create a method for base::sort_by(), as you suggested you could.  Use 
the generic's variable names for compatibility, but also add your extra 
variable names as additional arguments, e.g.

  sort_by.est_table <- function(x, y, object,
    by = c("op", "lhs", "rhs"),
    op_priority = c("=~", "~", "~~", ":=", "~1", "|", "~*~"),
    number_rows = TRUE, ...) {

   # This test seems unlikely:  how would we have dispatch here if we 
specified object explicitly?

   if (!missing(object) {
     if (!missing(x))
       stop("both x and object specified!")
     x <- object
   }

   # This one is more likely to do something:

   if (!missing(by)) {
     if (!missing(y))
       stop("both y and by specified!")
     y <- by
   }

   # Now proceed using x and y

   ...
}

- Create a separate function, e.g. sort_by_old() which is exactly 
compatible with your old sort_by().  For users where the above doesn't 
just work, they can switch to sort_by_old().

Duncan Murdoch
#
I haven't thought about this carefully, but shouldn't this mostly work?

  sort_by.est_table <- function(x, y = c("op", "lhs", "rhs"),
    object = x,
    by = y,
    op_priority = c("=~", "~", "~~", ":=", "~1", "|", "~*~"),
    number_rows = TRUE, ...) {

<code unchanged>

}

-Deepayan

On Sat, 3 Aug 2024 at 00:13, Duncan Murdoch <murdoch.duncan at gmail.com>
wrote:

  
  
#
Thanks a lot for both suggestions! I haven't thought about these
approaches, They may solve my problem without breaking existing code.
I may just keep the original arguments for backward compatibility.
Coincidentally, "object" and "by" have the same meanings as "x" and
"y" in base::sort_by() and so the matching makes sense.

Regards,
Shu Fai Cheung

On Sat, Aug 3, 2024 at 7:13?PM Deepayan Sarkar
<deepayan.sarkar at gmail.com> wrote:
#
The problem with that is a call like

   sort_by( object = foo, by = bar )

wouldn't be dispatched to the est_table method when foo is an est_table 
object, it would give a "argument 'x' is missing" kind of error.  It 
would be fine for

  sort_by( foo, bar )

but would also mess up on

  sort_by( foo, bar, priority )

Duncan Murdoch
On 2024-08-03 7:13 a.m., Deepayan Sarkar wrote:
#
Since the main problem is that in base-R's function your 'object' is called  'x',  you could consider issuing an intermediate version of the package, where you strongly advise users not to name the first argument and to always name the remaining arguments. Also, make sure that your examples follow this advice.

If the function is used by package authors, you could send them emails, telling them exactly what to change.

After a year or so you could make the method following Duncan's advice.

Since sort_by is in package 'base', packages that use your package will no longer need to import sort_by from your package. There are some further subtleties here that could be discussed if packages that import explicitly sort_by from your package exist.


Georgi Boshnakov



Sent from Outlook for Android<https://aka.ms/AAb9ysg>