funprog package:base R Documentation _C_o_m_m_o_n _H_i_g_h_e_r-_O_r_d_e_r _F_u_n_c_t_i_o_n_s _i_n _F_u_n_c_t_i_o_n_a_l _P_r_o_g_r_a_m_m_i_n_g _L_a_n_g_u_a_g_e_s _D_e_s_c_r_i_p_t_i_o_n: 'Reduce' uses a binary function to successively combine the elements of a given vector and a possibly given initial value. 'Filter' extracts the elements of a vector for which a predicate (logical) function gives true. 'Find' and 'Position' give the first or last such element and its position in the vector, respectively. 'Map' applies a function to the corresponding elements of given vectors. 'Negate' creates the negation of a given function. _U_s_a_g_e: Reduce(f, x, init, right = FALSE, accumulate = FALSE) Filter(f, x) Find(f, x, right = FALSE, nomatch = NULL) Map(f, ...) Negate(f) Position(f, x, right = FALSE, nomatch = NA_integer_) _A_r_g_u_m_e_n_t_s: f: a function of the appropriate arity (binary for 'Reduce', unary for 'Filter', 'Find' and 'Position', k-ary for 'Map' if this is called with k arguments). An arbitrary predicate function for 'Negate'. x: a vector. init: an R object of the same kind as the elements of 'x'. right: a logical indicating whether to proceed from left to right (default) or from right to left. accumulate: a logical indicating whether the successive reduce combinations should be accumulated. By default, only the final combination is used. nomatch: the value to be returned in the case when "no match" (no element satisfying the predicate) is found. ...: vectors. _D_e_t_a_i_l_s: If 'init' is given, 'Reduce' logically adds it to the start (when proceeding left to right) or the end of 'x', respectively. If this possibly augmented vector v has n > 1 elements, 'Reduce' successively applies f to the elements of v from left to right or right to left, respectively. I.e., a left reduce computes l_1 = f(v_1, v_2), l_2 = f(l_1, v_3), etc., and returns l_{n-1} = f(l_{n-2}, v_n), and a right reduce does r_{n-1} = f(v_{n-1}, v_n), r_{n-2} = f(v_{n-2}, r_{n-1}) and returns r_1 = f(v_1, r_2). (E.g., if v is the sequence (2, 3, 4) and f is division, left and right reduce give (2 / 3) / 4 = 1/6 and 2 / (3 / 4) = 8/3, respectively.) If v has only a single element, this is returned; if there are no elements, 'NULL' is returned. Thus, it is ensured that 'f' is always called with 2 arguments. The current implementation is non-recursive to ensure stability and scalability. 'Reduce' is patterned after Common Lisp's 'reduce'. A reduce is also known as a fold (e.g., in Haskell) or an accumulate (e.g., in the C++ Standard Template Library). The accumulative version corresponds to Haskell's scan functions. 'Filter' applies the unary predicate function 'f' to each element of 'x', coercing to logical if necessary, and returns the subset of 'x' for which this gives true. Note that possible 'NA' values are currently always taken as false; control over 'NA' handling may be added in the future. 'Filter' corresponds to 'filter' in Haskell or 'remove-if-not' in Common Lisp. 'Find' and 'Position' are patterned after Common Lisp's 'find-if' and 'position-if', respectively. If there is an element for which the predicate function gives true, then the first or last such element or its position is returned depending on whether 'right' is false (default) or true, respectively. If there is no such element, the value specified by 'nomatch' is returned. The current implementation is not optimized for performance. 'Map' is a simple wrapper to 'mapply' which does not attempt to simplify the result, similar to Common Lisp's 'mapcar' (with arguments being recycled, however). Future versions may allow some control of the result type. 'Negate' corresponds to Common Lisp's 'complement'. Given a (predicate) function 'f', it creates a function which returns the logical negation of what 'f' returns. _E_x_a_m_p_l_e_s: ## A general-purpose adder: add <- function(x) Reduce("+", x) add(list(1, 2, 3)) ## Like sum(), but can also used for adding matrices etc., as it will ## use the appropriate '+' method in each reduction step. ## More generally, many generics meant to work on arbitrarily many ## arguments can be defined via reduction: FOO <- function(...) Reduce(FOO2, list(...)) FOO2 <- function(x, y) UseMethod("FOO2") ## FOO() methods can then be provided via FOO2() methods. ## A general-purpose cumulative adder: cadd <- function(x) Reduce("+", x, accumulate = TRUE) cadd(seq_len(7)) ## A simple function to compute continued fractions: cfrac <- function(x) Reduce(function(u, v) u + 1 / v, x, right = TRUE) ## Continued fraction approximation for pi: cfrac(c(3, 7, 15, 1, 292)) ## Continued fraction approximation for Euler's number (e): cfrac(c(2, 1, 2, 1, 1, 4, 1, 1, 6, 1, 1, 8)) ## Iterative function application: Funcall <- function(f, ...) f(...) ## Compute log(exp(acos(cos(0)) Reduce(Funcall, list(log, exp, acos, cos), 0, right = TRUE) ## n-fold iterate of a function, functional style: Iterate <- function(f, n = 1) function(x) Reduce(Funcall, rep.int(list(f), n), x, right = TRUE) ## Continued fraction approximation to the golden ratio: Iterate(function(x) 1 + 1 / x, 30)(1) ## which is the same as cfrac(rep.int(1, 31)) ## Computing square root approximations for x as fixed points of the ## function t |-> (t + x / t) / 2, as a function of the initial value: asqrt <- function(x, n) Iterate(function(t) (t + x / t) / 2, n) asqrt(2, 30)(10) # Starting from a positive value => +sqrt(2) asqrt(2, 30)(-1) # Starting from a negative value => -sqrt(2) ## A list of all functions in the base environment: funs <- Filter(is.function, sapply(ls(baseenv()), get, baseenv())) ## Functions in base with more than 10 arguments: names(Filter(function(f) length(formals(args(f))) > 10, funs)) ## Number of functions in base with a '...' argument: length(Filter(function(f) any(names(formals(args(f))) %in% "..."), funs)) ## Find all objects in the base environment which are *not* functions: Filter(Negate(is.function), sapply(ls(baseenv()), get, baseenv()))