15

Commonly, I use the same function settings. I'm wondering if there is a method, other than having a new object in the path that is essentially a wrapper for the function, to set default arguments. For example:

paste() has it's sep argument set to a space =" ", I'm tired of writing ,sep="" over and over. So is there a way to "temporarily" replace the function with my chosen defaults?

paste(...,sep="") 

Can I accomplish this through packaging? I've sometimes noticed that, some packages force other equally named functions to be masked in the global environment.

Ideally, I'd like something that can be set on a project by project basis in (load.r or some other such workflow startpoint)

smci
  • 32,567
  • 20
  • 113
  • 146
Brandon Bertelsen
  • 43,807
  • 34
  • 160
  • 255
  • 2
    For this specific example, see `paste0` introduced in R-devel. – Martin Morgan Jan 31 '12 at 06:46
  • 2
    Again, in this specific case, `ggplot2` has `ps` which wraps `paste` with `sep = ""` and `collapse = ""`. Though I've long thought that having a dependency on `ggplot2` is a bit much for just that utility function. – Richie Cotton Jan 31 '12 at 10:25
  • `formals()` is in base R and will let you set defaults without creating a new function. See https://stackoverflow.com/a/30416943/697473. – user697473 Sep 14 '20 at 15:31

2 Answers2

18

I'd personally be very hesitant to change the default behavior of any commonly used functions --- especially base R functions. For one thing, it will immediately decrease the portability of any scripts or code snippets in which you use the redefined functions. Worse, other R users reading your scripts will likely be either: (a) unaware of your private meanings for well-known language elements or (b) frustrated at having to rewire their own expectations for the functions. For me, it would also feel like an added mental burden to attach different meanings to the same symbol in different settings.

I think a much better solution is to create similarly named functions implementing your preferred defaults. A slightly modified name will effectively flag that this isn't the familiar base function, without burdening you with much or any extra typing. A good example are the paste0() and cat0() functions that are included in the gsubfn package. (Clearly you and I aren't the only two to find ourselves (frequently) annoyed by the paste()'s default sep setting!):

library(gsubfn)

paste0
# function (..., sep = "") 
# paste(..., sep = sep)
# <environment: namespace:gsubfn>

cat0
# function (..., sep = "") 
# cat(..., sep = sep)
# <environment: namespace:gsubfn>

You can then either collect a number of these functions in a text file, sourcing them early in your script, or (better) package them up and load them via a call to library().

Josh O'Brien
  • 159,210
  • 26
  • 366
  • 455
  • A very valid consideration. This is why I'm looking for something that's portable. It's incredibly rare that anyone else uses my code. But still. – Brandon Bertelsen Jan 31 '12 at 04:39
  • I think any reasonable solution you find is going to require at least *one* additional line of code in your script. IMHO, it might as well be `source("BBFuns.R")` or `load(BBFuns)`, where either the script file or the package contain the functions you want to use. Hard to beat that for succinctness *and portability*. And then is there *any* downside to calling your revised function, e.g., `paste0` rather than `paste`? – Josh O'Brien Jan 31 '12 at 06:11
  • +1 This is how I do it, both for defaults and for sufficiently complex commands that I can't recall. One other advantage is that if you have your own wrapper / helper function, you can easily change the behavior of *all* instances in code by changing it in one place. You can also incorporate functionality for different versions, e.g. `myPaste(..., ver = 2)`, `myPaste(..., ver = 3)`. – Iterator Feb 01 '12 at 02:40
  • 5
    `functional::Curry` is very helpful for making new functions with different defaults. – Ari B. Friedman Aug 24 '12 at 15:24
12

The Defaults package used to do that; retired in 2014.

smci
  • 32,567
  • 20
  • 113
  • 146
Vincent Zoonekynd
  • 31,893
  • 5
  • 69
  • 78
  • 4
    At the moment there is a bug that makes `setDefaults(paste, sep = "")` go into an infinite recursion. Jeff is now on the case fixing it. – Richie Cotton Jan 31 '12 at 16:31
  • *Defaults* package was retired in 2014; not updated since R 3.0.x – smci May 29 '15 at 06:29