Skip to content

Commit 87101ea

Browse files
committed
port in named map builder and lambda
1 parent 34a3ae0 commit 87101ea

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+1165
-40
lines changed

DESCRIPTION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ Package: wrapr
22
Type: Package
33
Title: Wrap R Functions for Debugging and Parametric Programming
44
Version: 0.4.1
5-
Date: 2017-07-29
5+
Date: 2017-08-24
66
Authors@R: c(
77
person("John", "Mount", email = "[email protected]", role = c("aut", "cre")),
88
person("Nina", "Zumel", email = "[email protected]", role = c("aut")),

NAMESPACE

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
# Generated by roxygen2: do not edit by hand
22

3+
S3method(":=",character)
4+
S3method(":=",formula)
5+
S3method(":=",list)
36
export("%.>%")
7+
export(":=")
48
export(DebugFn)
59
export(DebugFnE)
610
export(DebugFnW)
@@ -11,6 +15,9 @@ export(add_name_column)
1115
export(ateval)
1216
export(beval)
1317
export(buildNameCallback)
18+
export(lambda)
1419
export(let)
20+
export(makeFunction_se)
21+
export(named_map_builder)
1522
export(restrictToNameAssignments)
1623
export(seval)

NEWS.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11

2-
# wrapr 0.4.1 2017-07-29
2+
# wrapr 0.4.1 2017-08-24
33

44
* Do not insist let-mapping be invertible.
5+
* Migrate named map builder and lambda from seplyr.de
56

67
# wrapr 0.4.0 2017-07-22
78

R/lambda.R

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
2+
3+
#' Build an anonymous function.
4+
#'
5+
#' Developed from:
6+
#' \url{http://www.win-vector.com/blog/2016/12/the-case-for-using-in-r/comment-page-1/#comment-66399},
7+
#' \url{https://github.com/klmr/functional#a-concise-lambda-syntax},
8+
#' \url{https://github.com/klmr/functional/blob/master/lambda.r}
9+
#' Called from \code{:=} operator.
10+
#'
11+
#' @param params formal parameters of function, unbound names.
12+
#' @param body subsituted body of function to map arguments into (braces required for ":=" notation).
13+
#' @param env environment to work in.
14+
#' @return user defined function.
15+
#'
16+
#' @examples
17+
#'
18+
#' f <- makeFunction_se(as.name('x'), substitute({x*x}))
19+
#' f(7)
20+
#'
21+
#' f <- x := { x*x }
22+
#' f(7)
23+
#'
24+
#' g <- makeFunction_se(c(as.name('x'), as.name('y')), substitute({ x + 3*y }))
25+
#' g(1,100)
26+
#'
27+
#' g <- c(x,y) := { x + 3*y }
28+
#' g(1,100)
29+
#'
30+
#' @export
31+
#'
32+
makeFunction_se <- function(params, body, env = parent.frame()) {
33+
vars <- as.character(params)
34+
formals <- replicate(length(vars), quote(expr = ))
35+
names(formals) <- vars
36+
eval(call('function', as.pairlist(formals), body), env)
37+
}
38+
39+
40+
41+
#' Build an anonymous function.
42+
#'
43+
#' Mostly just a place-holder so lambda-symbol form has somewhere safe to hang its help entry.
44+
#'
45+
#' @param ... formal parameters of function, unbound names, followed by function body (code/language).
46+
#' @param env environment to work in
47+
#' @return user defined function.
48+
#'
49+
#' @examples
50+
#'
51+
#' #lambda-syntax: lambda(arg [, arg]*, body [, env=env])
52+
#' # also works with lambda character as function name
53+
#' # print(intToUtf8(0x03BB))
54+
#'
55+
#' # example: square numbers
56+
#' sapply(1:4, lambda(x, x^2))
57+
#'
58+
#' # example more than one argumnet
59+
#' f <- lambda(x, y, x+y)
60+
#' f(2,4)
61+
#'
62+
#' # formula interface syntax: [~arg|arg(~arg)+] := body
63+
#' f <- x~y := x + 3 * y
64+
#' f(5, 47)
65+
#'
66+
#' @export
67+
#'
68+
lambda <- function(..., env = parent.frame()) {
69+
args <- substitute(list(...))
70+
body <- args[[length(args)]]
71+
args <- args[-length(args)]
72+
params <- lapply(args[-1], as.name)
73+
makeFunction_se(params, body, env)
74+
}
75+
76+
#' @export
77+
`:=.formula` <- function(args, values) {
78+
env = parent.frame()
79+
params <- setdiff(as.character(all.vars(substitute(args))),
80+
'~')
81+
body <- substitute(values)
82+
makeFunction_se(params, body, env)
83+
}

R/namedMapBuilder.R

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
2+
3+
#' Named map builder.
4+
#'
5+
#' Set names of right-argument to be left-argument, and return right argument.
6+
#' Has a special case for length-1 name sets.
7+
#' Called from \code{:=} operator.
8+
#'
9+
#' @param names names to set.
10+
#' @param values values to assign names to (and return).
11+
#' @return values with names set.
12+
#'
13+
#' @examples
14+
#'
15+
#'
16+
#' c('a' := '4', 'b' := '5')
17+
#' # equivalent to: c(a = '4', b = '5')
18+
#'
19+
#' c('a', 'b') := c('1', '2')
20+
#' # equivalent to: c(a = '1', b = '2')
21+
#'
22+
#' # the important example
23+
#' name <- 'a'
24+
#' name := '5'
25+
#' # equivalent to: c('a' = '5')
26+
#'
27+
#' # fn version, see makeFunction_se
28+
#' g <- c(x,y) := { x + 3*y }
29+
#' g(1,100)
30+
#'
31+
#' @export
32+
named_map_builder <- function(names, values) {
33+
# sepcial case 'a' := c('b', 'c') -> a := 'bc'
34+
if((length(values)>1)&&(length(names)==1)) {
35+
values <- do.call(paste0, as.list(values))
36+
}
37+
# main case
38+
names(values) <- as.character(names)
39+
values
40+
}
41+
42+
#' @rdname named_map_builder
43+
#' @export
44+
`:=` <- function(names, values) {
45+
# check if this was a lambda assignment
46+
# only consider so if LHS is variables and RHS has {}
47+
nv <- substitute(names)
48+
vl <- substitute(values)
49+
isVarArray <- is.call(vl) &&
50+
(as.character(vl[[1]])=='{') &&
51+
is.language(nv) &&
52+
all(vapply(nv, is.name, logical(1))) &&
53+
(length(nv<=1) ||
54+
((!any(vapply(nv, is.call, logical(1)))) &&
55+
as.character(nv[[1]])=='c'))
56+
if(isVarArray) {
57+
return(makeFunction_se(all.vars(nv), vl, parent.frame()))
58+
}
59+
# use standard S3 dispatch
60+
rm(list= c('nv', 'vl'))
61+
UseMethod(":=")
62+
}
63+
64+
# override as few S3 types as we reasonably need.
65+
# deliberaterly leave default alone
66+
# as a "good citizen".
67+
68+
# #' @export
69+
# `:=.default` <- named_map_builder
70+
71+
#' @export
72+
`:=.character` <- named_map_builder
73+
74+
#' @export
75+
`:=.list` <- named_map_builder
76+
77+
#' #' @export
78+
#' `:=.name` <- named_map_builder
79+
80+

R/zzz.R

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
2+
# https://stackoverflow.com/questions/20223601/r-how-to-run-some-code-on-load-of-package
3+
.onLoad <- function(libname, pkgname){
4+
# write lambda into package namespace
5+
do.call('<<-', list(intToUtf8(0x03BB), lambda))
6+
}

cran-comments.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,18 @@
66
* using R version 3.4.1 (2017-06-30)
77
* win-builder (devel and release)
88

9-
## R CMD check --as-cran wrapr_0.4.0.tar.gz
9+
## R CMD check --as-cran wrapr_0.4.1.tar.gz
1010

1111
* using R version 3.4.1 (2017-06-30)
1212
* using platform: x86_64-apple-darwin15.6.0 (64-bit)
1313
* using session charset: UTF-8
1414
* using option ‘--as-cran’
1515
* checking for file ‘wrapr/DESCRIPTION’ ... OK
1616
* checking extension type ... Package
17-
* this is package ‘wrapr’ version ‘0.4.0
17+
* this is package ‘wrapr’ version ‘0.4.1
1818
* package encoding: UTF-8
1919

20+
2021
* checking CRAN incoming feasibility ... Note_to_CRAN_maintainers
2122
Maintainer: ‘John Mount <[email protected]>
2223

docs/LICENSE.html

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/articles/CornerCases.html

Lines changed: 4 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/articles/DebugFnW.html

Lines changed: 5 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)