{"id":18612360,"url":"https://github.com/winvector/wrapr","last_synced_at":"2025-04-05T23:08:54.351Z","repository":{"id":56934176,"uuid":"81586672","full_name":"WinVector/wrapr","owner":"WinVector","description":"Wrap R for Sweet R Code","archived":false,"fork":false,"pushed_at":"2023-08-19T17:10:47.000Z","size":13488,"stargazers_count":137,"open_issues_count":1,"forks_count":11,"subscribers_count":8,"default_branch":"main","last_synced_at":"2025-03-29T22:06:00.405Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://winvector.github.io/wrapr/","language":"R","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/WinVector.png","metadata":{"files":{"readme":"README.Rmd","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2017-02-10T16:59:32.000Z","updated_at":"2025-01-02T20:50:35.000Z","dependencies_parsed_at":"2024-02-09T01:57:03.750Z","dependency_job_id":"21aae6f9-a24b-408d-a9c0-ccf975b2c1cb","html_url":"https://github.com/WinVector/wrapr","commit_stats":{"total_commits":1083,"total_committers":3,"mean_commits":361.0,"dds":0.005540166204986097,"last_synced_commit":"4f360edf333206d7fc8da13b2b729d3e5b6dcd64"},"previous_names":[],"tags_count":49,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/WinVector%2Fwrapr","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/WinVector%2Fwrapr/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/WinVector%2Fwrapr/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/WinVector%2Fwrapr/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/WinVector","download_url":"https://codeload.github.com/WinVector/wrapr/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247411234,"owners_count":20934653,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-07T03:16:49.165Z","updated_at":"2025-04-05T23:08:54.311Z","avatar_url":"https://github.com/WinVector.png","language":"R","readme":"---\noutput: github_document\n---\n\n[![CRAN_Status_Badge](https://www.r-pkg.org/badges/version/wrapr)](https://cran.r-project.org/package=wrapr)\n[![status](https://tinyverse.netlify.com/badge/wrapr)](https://CRAN.R-project.org/package=wrapr)\n\n\u003c!-- README.md is generated from README.Rmd. Please edit that file --\u003e\n\n\n\n```{r, echo = FALSE}\nknitr::opts_chunk$set(\n  collapse = TRUE,\n  comment = \" # \",\n  fig.path = \"tools/README-\"\n)\noptions(width =100)\n```\n\n\n\n\n[`wrapr`](https://winvector.github.io/wrapr/) is an [`R`](https://cran.r-project.org) package that supplies powerful tools for writing and debugging `R` code.\n\n![](https://github.com/WinVector/wrapr/raw/master/tools/wraprs.png)\n\n\n## Introduction\n\n\nPrimary `wrapr` services include:\n\n * [`%.\u003e%`](https://winvector.github.io/wrapr/reference/dot_arrow.html) (dot arrow pipe)\n * [`unpack`](https://winvector.github.io/wrapr/reference/unpack.html)/[`to`](https://winvector.github.io/wrapr/reference/to.html) (assign to multiple values)\n * [`as_named_list`](https://winvector.github.io/wrapr/reference/as_named_list.html) (build up a named list quickly)\n * [`build_frame()`](https://winvector.github.io/wrapr/reference/build_frame.html) / [`draw_frame()`](https://winvector.github.io/wrapr/reference/draw_frame.html) ( `data.frame` builders and formatters )\n * [`bc()`](https://win-vector.com/2021/02/05/introducing-wraprbc/) (blank concatenate)\n * [`qc()`](https://winvector.github.io/wrapr/reference/qc.html) (quoting concatenate)\n * [`:=`](https://winvector.github.io/wrapr/reference/named_map_builder.html) (named map builder)\n * [`%?%`](https://winvector.github.io/wrapr/reference/coalesce.html) (coalesce)\n * [`%.|%`](https://winvector.github.io/wrapr/reference/reduceexpand.html) (reduce/expand args)\n * [`uniques()`](https://winvector.github.io/wrapr/reference/uniques.html) (safe `unique()` replacement)\n * [`partition_tables()`](https://winvector.github.io/wrapr/reference/partition_tables.html) / [`execute_parallel()`](https://winvector.github.io/wrapr/reference/execute_parallel.html)\n * [`DebugFnW()`](https://winvector.github.io/wrapr/reference/DebugFnW.html) (function debug wrappers)\n * [`λ()`](https://winvector.github.io/wrapr/reference/defineLambda.html) (anonymous function builder)\n * [`let()`](https://winvector.github.io/wrapr/reference/let.html) (let block)\n * [`evalb()`/`si()`](https://winvector.github.io/wrapr/articles/bquote.html) (evaluate with `bquote` / string interpolation)\n * [`sortv()`](https://winvector.github.io/wrapr/reference/sortv.html) (sort a data.frame by a set of columns).\n * [`stop_if_dot_args()`](https://win-vector.com/2018/02/22/r-tip-force-named-arguments/) (check for unexpected arguments)\n\n```{r}\nlibrary(wrapr)\npackageVersion(\"wrapr\")\ndate()\n```\n\n## [`%.\u003e%` (dot pipe or dot arrow)](https://winvector.github.io/wrapr/articles/dot_pipe.html)\n\n`%.\u003e%` dot arrow pipe is a pipe with intended semantics:\n\n\n\u003e  \"`a %.\u003e% b`\" is to be treated *approximately*\n\u003e  as if the user had written \"`{ . \u003c- a; b };`\"\n\u003e  with \"`%.\u003e%`\" being treated as left-associative.\n\nOther `R` pipes include [`magrittr`](https://CRAN.R-project.org/package=magrittr) and [`pipeR`](https://CRAN.R-project.org/package=pipeR).\n\nThe following two expressions should be equivalent:\n\n```{r pipe1s}\ncos(exp(sin(4)))\n\n4 %.\u003e% sin(.) %.\u003e% exp(.) %.\u003e% cos(.)\n```\n\nThe notation is quite powerful as it treats pipe stages as expression parameterized over the variable \n\"`.`\".  This means you do not need to introduce functions to express stages.  The following is \na valid dot-pipe:\n\n```{r pipe1}\n1:4 %.\u003e% .^2 \n```\n\nThe notation is also very regular as we show below.\n\n```{r pipe2}\n1:4 %.\u003e% sin\n1:4 %.\u003e% sin(.)\n1:4 %.\u003e% base::sin\n1:4 %.\u003e% base::sin(.)\n\n1:4 %.\u003e% function(x) { x + 1 }\n1:4 %.\u003e% (function(x) { x + 1 })\n\n1:4 %.\u003e% { .^2 } \n1:4 %.\u003e% ( .^2 )\n```\n\nRegularity can be a *big* advantage in teaching and comprehension. Please see [\"In Praise of Syntactic Sugar\"](https://win-vector.com/2017/07/07/in-praise-of-syntactic-sugar/) for more details.\nSome formal documentation can be found [here](https://github.com/WinVector/wrapr/blob/master/extras/wrapr_pipe.pdf).\n\n\u003cul\u003e\n\u003cli\u003eSome obvious \"dot-free\"\" right-hand sides are rejected.  Pipelines are meant to move values through a sequence of transforms, and not just for side-effects. Example: `5 %.\u003e% 6` deliberately stops as `6` is a right-hand side that obviously does not use its incoming value.  This check is only applied to values, not functions on the right-hand side.\u003c/li\u003e\n\u003cli\u003eTrying to pipe into a an \"zero argument function evaluation expression\" such as `sin()` is prohibited as it looks too much like the user declaring `sin()` takes no arguments.  One must pipe into either a function, function name, or an non-trivial expression (such as `sin(.)`).  A useful error message is returned to the user: `wrapr::pipe does not allow direct piping into a no-argument function call expression (such as \"sin()\" please use sin(.))`.\u003c/li\u003e\n\u003cli\u003eSome reserved words can not be piped into.  One example is `5 %.\u003e% return(.)` is prohibited as the obvious pipe implementation would not actually escape from user functions as users may intend.\u003c/li\u003e\n\u003cli\u003eObvious de-references (such as `$`, `::`, `@`, and a few more) on the right-hand side\nare treated performed (example: `5 %.\u003e% base::sin(.)`).\u003c/li\u003e\n\u003cli\u003eOuter parenthesis on the right-hand side are removed (example: `5 %.\u003e% (sin(.))`).\u003c/li\u003e\n\u003cli\u003eAnonymous function constructions are evaluated so the function can be applied (example: `5 %.\u003e% function(x) {x+1}` returns 6, just as `5 %.\u003e% (function(x) {x+1})(.)` does).\u003c/li\u003e\n\u003cli\u003eChecks and transforms are not performed on items inside braces (example: `5 %.\u003e% { function(x) {x+1} }` returns `function(x) {x+1}`, not 6).\u003c/li\u003e\n\u003cli\u003eThe dot arrow pipe has S3/S4 dispatch (please see \\url{https://journal.r-project.org/archive/2018/RJ-2018-042/index.html}).\nHowever as the right-hand side of the pipe is normally held unevaluated, we don't know the type except in special\ncases (such as the rigth-hand side being referred to by a name or variable).  To force the evaluation of a pipe term,\nsimply wrap it in `.()`.\u003c/li\u003e\n\u003c/ul\u003e\n\nThe dot pipe is also user configurable through standard `S3`/`S4` methods.\n\nThe dot pipe has been [formally written up in the R Journal](https://journal.r-project.org/archive/2018/RJ-2018-042/index.html).\n\n```\n@article{RJ-2018-042,\n  author = {John Mount and Nina Zumel},\n  title = {{Dot-Pipe: an S3 Extensible Pipe for R}},\n  year = {2018},\n  journal = {{The R Journal}},\n  url = {https://journal.r-project.org/archive/2018/RJ-2018-042/index.html}\n}\n```\n\n\n## [`unpack`](https://winvector.github.io/wrapr/reference/unpack.html)/[`to`](https://winvector.github.io/wrapr/reference/to.html) multiple assignments\n\nUnpack a named list into the current environment by name (for a positional based multiple assignment operator please see [`zeallot`](https://CRAN.R-project.org/package=zeallot), for another named base multiple assigment please see [`vadr::bind`](https://github.com/crowding/vadr/blob/master/R/bind.R)).\n\n```{r unpack}\nd \u003c- data.frame(\n  x = 1:9,\n  group = c('train', 'calibrate', 'test'),\n  stringsAsFactors = FALSE)\n\nunpack[\n  train_data = train,\n  calibrate_data = calibrate,\n  test_data = test\n  ] := split(d, d$group)\n\nknitr::kable(train_data)\n```\n\n## [`as_named_list`](https://winvector.github.io/wrapr/reference/as_named_list.html)\n\nBuild up named lists.  [Very convenient for managing workspaces when used with used with `unpack`/`to`.](https://win-vector.com/2020/01/21/using-unpack-to-manage-your-r-environment/)\n\n```{r as_named_list}\nas_named_list(train_data, calibrate_data, test_data)\n```\n\n\n\n## [`build_frame()`](https://winvector.github.io/wrapr/reference/build_frame.html)  / [`draw_frame()`](https://winvector.github.io/wrapr/reference/draw_frame.html)\n\n[`build_frame()`](https://winvector.github.io/wrapr/reference/build_frame.html) is a convenient way to type in a small example `data.frame` in\nnatural row order.  This can be very legible and saves having to perform a transpose\nin one's head.  [`draw_frame()`](https://winvector.github.io/wrapr/reference/draw_frame.html) is the complimentary function that formats a \ngiven `data.frame` (and is a great way to produce neatened examples).\n\n```{r drawbuild}\nx \u003c- build_frame(\n   \"measure\"                   , \"training\", \"validation\" |\n   \"minus binary cross entropy\", 5         , -7           |\n   \"accuracy\"                  , 0.8       , 0.6          )\nprint(x)\nstr(x)\ncat(draw_frame(x))\n```\n\n\n## [`qc()` (quoting concatenate)](https://winvector.github.io/wrapr/reference/qc.html)\n\n`qc()` is a quoting variation on `R`'s concatenate operator `c()`.  This code such as the following:\n\n```{r qc}\nqc(a = x, b = y)\n\nqc(one, two, three)\n```\n\n`qc()` also allows `bquote()` driven `.()`-style argument escaping.\n\n```{r qc3}\naname \u003c- \"I_am_a\"\nyvalue \u003c- \"six\"\n\nqc(.(aname) := x, b = .(yvalue))\n```\n\nNotice the `:=` notation is required for syntacitic reasons.\n\n\n## [`:=` (named map builder)](https://winvector.github.io/seplyr/articles/named_map_builder.html)\n\n`:=` is the \"named map builder\".  It allows code such as the following:\n\n```{r nmb0}\n'a' := 'x'\n```\n\nThe important property of named map builder is it accepts values on the left-hand side allowing the following:\n  \n```{r nmb2}\nname \u003c- 'variableNameFromElsewhere'\nname := 'newBinding'\n```\n\nA nice property is `:=` commutes (in the sense of algebra or category theory) with\n`R`'s concatenation function `c()`.  That is the following two statements are equivalent:\n\n```{r nmv1}\nc('a', 'b') := c('x', 'y')\n\nc('a' := 'x', 'b' := 'y')\n```\n\nThe named map builder is [designed to synergize with `seplyr`](https://winvector.github.io/seplyr/articles/named_map_builder.html).\n\n##  [`%?%` (coalesce)](https://winvector.github.io/wrapr/reference/coalesce.html)\n\nThe coalesce operator tries to replace elements of its first argument with elements from its second argument.  In particular `%?%` replaces NULL vectors and NULL/NA entries of vectors and lists.\n\nExample:\n\n```{r coalesce}\nc(1, NA) %?% list(NA, 20)\n```\n\n## [`%.|%` (reduce/expand args)](https://winvector.github.io/wrapr/reference/reduceexpand.html)\n\n`x %.|% f` stands for `f(x[[1]], x[[2]], ..., x[[length(x)]])`.\n`v %|.% x` also stands for `f(x[[1]], x[[2]], ..., x[[length(x)]])`.\nThe two operators are the same, the variation just allowing the user to choose the order they write things.\nThe mnemonic is: \"data goes on the dot-side of the operator.\"\n\n```{r reduceargs}\nargs \u003c- list('prefix_', c(1:3), '_suffix')\n\nargs %.|% paste0\n# prefix_1_suffix\" \"prefix_2_suffix\" \"prefix_3_suffix\"\n\npaste0 %|.% args\n# prefix_1_suffix\" \"prefix_2_suffix\" \"prefix_3_suffix\"\n```\n\n\n## [`DebugFnW()`](https://winvector.github.io/wrapr/articles/DebugFnW.html)\n\n`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](https://youtu.be/-P9UzQuJSH8?list=PLAKBwakacHbQT51nPHex1on3YNCCmggZA) and `vignette('DebugFnW', package='wrapr')` for examples.\n\n\n## [`λ()` (anonymous function builder)](https://winvector.github.io/wrapr/articles/lambda.html)\n\n`λ()` is a concise abstract function creator or \"[lambda abstraction](https://en.wikipedia.org/wiki/Lambda_calculus)\".  It is a placeholder \nthat allows the use of the -character for very concise function \nabstraction.\n\nExample:\n\n```{r lambda1}\n# Make sure lambda function builder is in our enironment.\nwrapr::defineLambda()\n\n# square numbers 1 through 4\nsapply(1:4, λ(x, x^2))\n```\n \n## [`let()`](https://winvector.github.io/wrapr/articles/let.html)\n\n`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()`). \n\nThe 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\".\n\n```{r exw}\na \u003c- 7\n\nlet(\n  c(VAR = 'a'),\n  \n  VAR + VAR\n)\n```\n\nThis is useful in re-adapting non-standard evaluation interfaces (NSE interfaces) so one can script or program over them.\n\nWe 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:\n\n```{r exwp}\nlet(\n  c(VAR = 'a'),\n  eval = FALSE,\n  {\n    VAR + VAR\n  }\n)\n\nlet(\n  c(VAR = 'a'),\n  debugPrint = TRUE,\n  {\n    VAR + VAR\n  }\n)\n```\n\nPlease see `vignette('let', package='wrapr')` for more examples. \nSome formal documentation can be found [here](https://github.com/WinVector/wrapr/blob/master/extras/wrapr_let.pdf).\n`wrapr::let()` was inspired by `gtools::strmacro()` and `base::bquote()`, please\nsee [here](https://github.com/WinVector/wrapr/blob/master/extras/bquote.md) for some notes on macro methods in `R`.\n\n#  [`evalb()`/`si()`](https://winvector.github.io/wrapr/articles/bquote.html) (evaluate with `bquote` / string interpolation)\n\n`wrapr` supplies unified notation for quasi-quotation and string interpolation.\n\n```{r}\nangle = 1:10\nvariable \u003c- \"angle\"\n\n# # execute code\n# evalb(\n#   plot(x = .(-variable), y = sin(.(-variable)))\n# )\n\n# alter string\nsi(\"plot(x = .(variable), y = .(variable))\")\n```\n\nThe extra `.(-x)` form is a shortcut for `.(as.name(x))`.\n\n# [`sortv()`](https://winvector.github.io/wrapr/reference/sortv.html) (sort a data.frame by a set of columns)\n\nThis is the sort command that is missing from `R`: sort a `data.frame` by a chosen set of columns specified in a variable.\n\n```{r}\nd \u003c- data.frame(\n  x = c(2, 2, 3, 3, 1, 1), \n  y = 6:1,\n  z = 1:6)\norder_cols \u003c- c('x', 'y')\n\nsortv(d, order_cols)\n```\n\n\n\n## Installation\n\nInstall with:\n\n```{r inst1, eval=FALSE}\ninstall.packages(\"wrapr\")\n```\n\n\n## More Information\n\nMore details on `wrapr` capabilities can be found in the following two technical articles:\n\n  * [let](https://github.com/WinVector/wrapr/blob/master/extras/wrapr_let.pdf)\n  * [R Journal \"Dot-Pipe: an S3 Extensible Pipe for R\"\"](https://journal.r-project.org/archive/2018/RJ-2018-042/index.html)\n\n## Note\n\nNote: `wrapr` is meant only for \"tame names\", that is: variables and column names that are also valid *simple* (without quotes) `R` variables names.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwinvector%2Fwrapr","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwinvector%2Fwrapr","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwinvector%2Fwrapr/lists"}