… oh yes. Can I really be trusted with the power to alter default settings???? Only time will tell, I suppose. Okay here goes!

What is my use case for this?

It has always annoyed me that functions like mean do not remove missing data by default. I know this makes me a bad person: after all, it’s often not safe to ignore NA values, which is why we have whole classes of imputation models for handling them. So it does make a lot of sense that the mean function sets na.rm = FALSE by default. Removing NA values genuinely should be a choice that the analyst is forced to actively make, rather than one that the software makes for them.

Yes, yes but… I get so tiiiiiirred of typing na.rm = TRUE over and over again within a single analysis. Okay, sure, I agree that it’s on me make the active choice to ignore missing data, but is it really necessary for me to keep typing in my decision, using my fingers like a sucker?

So I can imagine a workflow that goes like this

Think about what I want to do

Set my defaults for this analysis

Do the analysis

Reset the defaults to their original values

That seems sensible to me, and it might even produce cleaner code, because I would have one section at the top where I make my assumptions explicit via the “defaults”, but then during the analysis itself the code doesn’t get cluttered by having to reassert my assumptions every single time I call mean or lm or whatever. So that might be quite nice!

What does worry me is the thought of taking a “set and forget” approach to defaults. I could easily imagine myself ending up in a situation where I change my defaults, forget that I have done so, and then getting confused that my analyses don’t look the same as someone else’s. That sounds like a nightmare

Working on the assumption that I would have the discipline to always reset my defaults, let’s have a go at playing around with defaults

Taking it for a spin…

Right, so my first attempt to set a default didn’t work:

default(fun = mean) <- list(na.rm = TRUE)

## Error: 'na.rm' is not an argument of this function

Say what? na.rm is absolutely is an argument to the mean function what the … oh, right mean is a generic S3 function. Sigh. So presumably I need to set the default for the, um, default method, mean.default.

Yep, the mean function is now ignoring NA values by default. Next, let’s make sure I can reset the defaults:

mean.default <- reset_default(mean.default)
mean(x)
mean(y)

## [1] 4.5
## [1] NA

It works! 🎉

Tidy code for histograms

A really nice application I can see myself relying on a lot is specifying the default styling for my plots within a single analysis. By using the default function to do this, I can push the “ancillary” code specifying the visual style for the plots into the header of my script, leaving the functional code for the analysis looking nice and tidy. I imagine there are better ways to do this using ggplot but honestly I find there are a lot of situations (especially when computational modelling is involved) where ggplot isn’t really all that appropriate, and base graphics is still the best tool for the job. So it’s nice to be able to work with base graphics using clean code!

In this situation, when I come back to look at this analysis several months (years) later I can just look at it and just “see” what it’s doing without having to sort through many many arguments to work out which things are “substantive” and which are not. Here’s the output: