Learn R Programming

⚠️There's a newer version (2.1.0) of this package.Take me there.

wrapr, is an R package that supplies powerful tools for writing and debugging R code.

Introduction

Primary wrapr services include:

  • let() (let block)
  • %.>% (dot arrow pipe)
  • := (named map builder)
  • () (anonymous function builder)
  • DebugFnW() (function debug wrappers)

let()

let() allows execution of arbitrary code with substituted variable names (note this is subtly different than binding values for names as with base::substitute() or base::with()).

The function is simple and powerful. It treats strings as variable names and re-writes expressions as if you had used the denoted variables. For example the following block of code is equivalent to having written "a + a".

library("wrapr")

a <- 7

let(
  c(VAR = 'a'),
  
  VAR + VAR
)
 #  [1] 14

This is useful in re-adapting non-standard evaluation interfaces (NSE interfaces) so one can script or program over them.

We are trying to make let() self teaching and self documenting (to the extent that makes sense). For example try the arguments "eval=FALSE" prevent execution and see what would have been executed, or debug=TRUE to have the replaced code printed in addition to being executed:

let(
  c(VAR = 'a'),
  eval = FALSE,
  {
    VAR + VAR
  }
)
 #  {
 #      a + a
 #  }

let(
  c(VAR = 'a'),
  debugPrint = TRUE,
  {
    VAR + VAR
  }
)
 #  $VAR
 #  [1] "a"
 #  
 #  {
 #      a + a
 #  }
 #  [1] 14

Please see vignette('let', package='wrapr') for more examples. Some formal documentation can be found here. For working with dplyr 0.7.* we suggest also taking a look at an alternate approach called seplyr.

%.>% (dot arrow pipe)

%.>% dot arrow pipe is a strict pipe with intended semantics:

"a %.>% b" is to be treated as if the user had written "{ . <- a; b };" with "%.>%" being treated as left-associative.

That is: %.>% does not alter any function arguments that are not explicitly named. %.>% is designed to be explicit and simple.

The effect looks is show below.

The following two expressions should be equivalent:

cos(exp(sin(4)))
 #  [1] 0.8919465

4 %.>% sin(.) %.>% exp(.) %.>% cos(.)
 #  [1] 0.8919465

The notation is quite powerful as it treats pipe stages as expression parameterized over the variable ".". This means you do not need to introduce functions to express stages. The following is a valid dot-pipe:

1:4 %.>% .^2 
 #  [1]  1  4  9 16

The notation is also very regular as we show below.

1:4 %.>% sin
 #  [1]  0.8414710  0.9092974  0.1411200 -0.7568025
1:4 %.>% sin(.)
 #  [1]  0.8414710  0.9092974  0.1411200 -0.7568025
1:4 %.>% base::sin
 #  [1]  0.8414710  0.9092974  0.1411200 -0.7568025
1:4 %.>% base::sin(.)
 #  [1]  0.8414710  0.9092974  0.1411200 -0.7568025

1:4 %.>% function(x) { x + 1 }
 #  [1] 2 3 4 5
1:4 %.>% (function(x) { x + 1 })
 #  [1] 2 3 4 5

1:4 %.>% { .^2 } 
 #  [1]  1  4  9 16
1:4 %.>% ( .^2 )
 #  [1]  1  4  9 16

Regularity can be a big advantage in teaching and comprehension. Please see "In Praise of Syntactic Sugar" for more details. Some formal documentation can be found here.

There are some checks and accommodations to help make things appear regular, and a few exceptions.

:= is the "named map builder". It allows code such as the following:

'a' := 'x'
 #    a 
 #  "x"

The important property of named map builder is it accepts values on the left-hand side allowing the following:

name <- 'variableNameFromElsewhere'
name := 'newBinding'
 #  variableNameFromElsewhere 
 #               "newBinding"

A nice property is := commutes (in the sense of algebra or category theory) with R's concatenation function c(). That is the following two statements are equivalent:

c('a', 'b') := c('x', 'y')
 #    a   b 
 #  "x" "y"

c('a' := 'x', 'b' := 'y')
 #    a   b 
 #  "x" "y"

The named map builder is used to make seplyr notation much more manageable.

λ() (anonymous function builder)

λ() is a concise abstract function creator or "lambda abstraction". It is a placeholder that allows the use of the -character for very concise function abstraction.

Example:

# Make sure lambda function builder is in our enironment.
wrapr::defineLambda()

# square numbers 1 through 4
sapply(1:4, λ(x, x^2))
 #  [1]  1  4  9 16

DebugFnW()

DebugFnW() wraps a function for debugging. If the function throws an exception the execution context (function arguments, function name, and more) is captured and stored for the user. The function call can then be reconstituted, inspected and even re-run with a step-debugger. Please see our free debugging video series and vignette('DebugFnW', package='wrapr') for examples.

Installing

Install with either:

install.packages("wrapr")

or

# install.packages("devtools")
devtools::install_github("WinVector/wrapr")

More Information

More details on wrapr capabilities can be found in the following two technical articles:

Note: wrapr is meant only for "tame names", that is: variables and column names that are also valid simple (without quotes) R variables names.

Copy Link

Version

Install

install.packages('wrapr')

Monthly Downloads

2,731

Version

1.4.0

License

GPL-3

Issues

Pull Requests

Stars

Forks

Maintainer

John Mount

Last Published

April 3rd, 2018

Functions in wrapr (1.4.0)

qae

Quote assignment expressions (name = expr, and name := expr).
mk_tmp_name_source

Produce a temp name generator with a given prefix.
named_map_builder

Named map builder.
wrapr_function

Wrapr function.
wrapr_function.default

Wrapr function.
grepdf

Grep for column names from a data.frame
match_order

Match one order to another.
mapsyms

Map symbol names to referenced values if those values are string scalars (else throw).
restrictToNameAssignments

Restrict an alias mapping list to things that look like name assignments
qs

Quote a string.
qchar_frame

Build a (non-empty) quoted data.frame.
pipe_step

Pipe step operator
pipe_step.default

Pipe step operator
qc

Quoting version of c() array concatinator.
qe

Quote expressions.
stop_if_dot_args

Stop with message if dot_args is a non-trivial list.
wrapr

wrapr: Wrap R Functions for Debugging and Parametric Programming
DebugFn

Capture arguments of exception throwing function call for later debugging.
DebugPrintFnE

Capture arguments and environment of exception throwing function call for later debugging.
defineLambda

Define lambda function building function.
DebugFnWE

Wrap function to capture arguments and environment of exception throwing function call for later debugging.
build_frame

Build a (non-empty) data.frame.
DebugPrintFn

Capture arguments of exception throwing function call for later debugging.
buildNameCallback

Build a custom writeback function that writes state into a user named variable.
DebugFnE

Capture arguments and environment of exception throwing function call for later debugging.
add_name_column

Add list name as a column to a list of data.frames.
DebugFnW

Wrap a function for debugging.
let

Execute expr with name substitutions specified in alias.
map_to_char

format a map.
invert_perm

Invert a permuation.
%.>%

Pipe operator ("dot arrow").
draw_frame

Render a data.frame in build_frame format.
lambda

Build an anonymous function.
map_upper

Map up-cased symbol names to referenced values if those values are string scalars (else throw).
%>.%

Pipe operator ("to dot").
makeFunction_se

Build an anonymous function.