suppressPackageStartupMessages({
  library(dplyr)
  library(ggplot2)

  library(grrr)
})

knitr::opts_chunk$set(
  collapse  = TRUE,
  comment   = "#>",
  fig.path  = "man/figures/README-",
  out.width = "100%"
)

options(width = 90)
# Quick logo generation. Borrowed heavily from Nick Tierney's Syn logo process
library(magick)
library(showtext)
font_add_google("Special Elite", "gf")
img <- image_read("~/Desktop/dog.png") %>%
  image_transparent(color = "#f9fafb", fuzz = 10) %>%
  image_trim() %>%
  image_threshold()


res <- hexSticker::sticker(subplot  = img,
                    s_x      = 1,
                    s_y      = 0.7,
                    s_width  = 1.05,
                    s_height = 0.65,
                    package  = "grrr",
                    p_x      = 1,
                    p_y      = 1.3,
                    p_color  = "#000000",
                    p_family = "gf",
                    p_size   = 12,
                    h_size   = 1.2,
                    h_fill   = "#ffffff",
                    # h_color  = "#adb5bd",
                    h_color  = "#000000",
                    filename = "man/figures/grrr.png")

image_read("man/figures/grrr.png")

grrr: A package for modifying default arguments

Travis build status AppVeyor build status

Things that make you go "grrr!".

R has some default arguments that can make programming frustrating and error-prone - stringsAsFactors = TRUE immediately springs to mind.

This package offers a way to modify default arguments to functions and is a tool for exploring:

Features

The package offers three main functions:

Warning

Use grrr at your own risk!

Changing default arguments for functions is fraught with danger and will causes problems if you aren't extremely careful.

Installation

# install.packages("devtools")
devtools::install_github("coolbutuseless/grrr")

Putting default args into the global environment

default_args_to_global_env() copies all of the default arguments for a function into the global environment.

I find this handy when I'm debugging a function with a lot of default arguments that I don't want to manually copy/define in order to run bits of code line-by-line in a function.

ls()

myfun <- function(a = 1, b = 2, c = 3, d = 4, e = 5) {
  sum(c(a, b, c, d, e))
}

grrr::default_args_to_global_env(function_name = 'myfun')

ls()

a

Change the value of a default argument to a function

update_function_arguments() will change the default values for an argument to any function in the current environment, or within a package.

E.g. in the following code, we change the builtin rnorm() function to have mean = 100 rather than the default of mean = 0

set.seed(1); stats::rnorm(5)

# Change the default value for `mean` from `0` to `100`
grrr::update_function_arguments(function_name = 'rnorm', package_name = 'stats', mean = 100)

set.seed(1); stats::rnorm(5)

We can also remove the default for mean altogether so that it has to be specified every time the function is called

# Remove the default value for `mean` 
grrr::update_function_arguments(function_name = 'rnorm', package_name = 'stats', mean =)

set.seed(1); stats::rnorm(5)
Error in stats::rnorm(5) : 
  argument "mean" is missing, with no default

You are strongly advised against doing this.

Debug usage: Print warnings and callstack when defaults are used

The best(?) usage for grrr will come from using it for debugging in such a way that the default arguments are still used, but you can discover where they are being used.

set_sentinel_on_default_arg() is a wrapper around update_function_arguments() that will rewrite the default argument so that it prints a message and call-stack whenever the function is called and the default argument has not been specified by the user.

E.g. to make data.frame() noisy so that the user is notified whenever an attempt was made to use the function without explicitly setting stringsAsFactors. The function will still use the default value - it will just be noisier when it does.

grrr::set_sentinel_on_default_arg('data.frame', 'stringsAsFactors', package_name = 'base')

data.frame(x = 1:3, y = c('a', 'b', 'c'))
Using default argument for 'stringsAsFactors' in function 'data.frame':
    >>  data.frame(x = 1:3, y = c("a", "b", "c"))

  x y
1 1 a
2 2 b
3 3 c

Another Warning for People Who Didn't Read the First Warning

This package uses unlockBinding() and assignInNamespace() and can mess with the internals of other packages. This is generally frowned upon.

Furthermore, assignInNamespace() actually has some checks to prevent what this package tries to do! This is why grrr includes sudo_assignInNamespace() which drops some sanity checks and and allows us to stomp all over other packages and namespaces.

Because of these devilish things the package has to do, grrr will never appear on CRAN.



coolbutuseless/grrr documentation built on May 16, 2019, 7:15 p.m.