From 026f5880ca3d8376e78ee53f03304ff1692ac13b Mon Sep 17 00:00:00 2001 From: Michael Haupt <michael.haupt@oracle.com> Date: Tue, 11 Nov 2014 15:41:54 +0100 Subject: [PATCH] several R functions, for completeness (tests pending) --- .../r/nodes/builtin/base/R/interaction.R | 63 +++++++++ .../truffle/r/nodes/builtin/base/R/tapply.R | 56 ++++++++ .../truffle/r/nodes/builtin/stats/R/approx.R | 122 ++++++++++++++++++ 3 files changed, 241 insertions(+) create mode 100644 com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/R/interaction.R create mode 100644 com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/R/tapply.R create mode 100644 com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/stats/R/approx.R diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/R/interaction.R b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/R/interaction.R new file mode 100644 index 0000000000..0aec057324 --- /dev/null +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/R/interaction.R @@ -0,0 +1,63 @@ +# File src/library/base/R/interaction.R +# Part of the R package, http://www.R-project.org +# +# Copyright (C) 1995-2012 The R Core Team +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# A copy of the GNU General Public License is available at +# http://www.r-project.org/Licenses/ + +### This is almost like the Primitive ":" for factors +### but with drop=TRUE, used in reshape +interaction <- function(..., drop = FALSE, sep = ".", lex.order = FALSE) +{ + args <- list(...) + narg <- length(args) + if (narg == 1L && is.list(args[[1L]])) { + args <- args[[1L]] + narg <- length(args) + } + for(i in narg:1L) { + f <- as.factor(args[[i]])[, drop = drop] + l <- levels(f) + if1 <- as.integer(f) - 1L + if(i == narg) { + ans <- if1 + lvs <- l + } else { + if(lex.order) { + ll <- length(lvs) + ans <- ans + ll * if1 + lvs <- paste(rep(l, each = ll), rep(lvs, length(l)), sep=sep) + } else { + ans <- ans * length(l) + if1 + lvs <- paste(rep(l, length(lvs)), + rep(lvs, each = length(l)), sep=sep) + } + if(anyDuplicated(lvs)) { ## fix them up + ulvs <- unique(lvs) + while((i <- anyDuplicated(flv <- match(lvs, ulvs)))) { + lvs <- lvs[-i] + ans[ans+1L == i] <- match(flv[i], flv[1:(i-1)]) - 1L + ans[ans+1L > i] <- ans[ans+1L > i] - 1L + } + lvs <- ulvs + } + if(drop) { + olvs <- lvs + lvs <- lvs[sort(unique(ans+1L))] + ans <- match(olvs[ans+1L], lvs) - 1L + } + } + } + structure(as.integer(ans+1L), levels=lvs, class = "factor") +} diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/R/tapply.R b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/R/tapply.R new file mode 100644 index 0000000000..2b0fb66e67 --- /dev/null +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/R/tapply.R @@ -0,0 +1,56 @@ +# File src/library/base/R/tapply.R +# Part of the R package, http://www.R-project.org +# +# Copyright (C) 1995-2012 The R Core Team +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# A copy of the GNU General Public License is available at +# http://www.r-project.org/Licenses/ + +tapply <- function (X, INDEX, FUN = NULL, ..., simplify = TRUE) +{ + FUN <- if (!is.null(FUN)) match.fun(FUN) + if (!is.list(INDEX)) INDEX <- list(INDEX) + nI <- length(INDEX) + if (!nI) stop("'INDEX' is of length zero") + namelist <- vector("list", nI) + names(namelist) <- names(INDEX) + extent <- integer(nI) + nx <- length(X) + one <- 1L + group <- rep.int(one, nx) #- to contain the splitting vector + ngroup <- one + for (i in seq_along(INDEX)) { + index <- as.factor(INDEX[[i]]) + if (length(index) != nx) + stop("arguments must have same length") + namelist[[i]] <- levels(index)#- all of them, yes ! + extent[i] <- nlevels(index) + group <- group + ngroup * (as.integer(index) - one) + ngroup <- ngroup * nlevels(index) + } + if (is.null(FUN)) return(group) + ans <- lapply(X = split(X, group), FUN = FUN, ...) + index <- as.integer(names(ans)) + if (simplify && all(unlist(lapply(ans, length)) == 1L)) { + ansmat <- array(dim = extent, dimnames = namelist) + ans <- unlist(ans, recursive = FALSE) + } else { + ansmat <- array(vector("list", prod(extent)), + dim = extent, dimnames = namelist) + } + if(length(index)) { + names(ans) <- NULL + ansmat[index] <- ans + } + ansmat +} diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/stats/R/approx.R b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/stats/R/approx.R new file mode 100644 index 0000000000..f03230b028 --- /dev/null +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/stats/R/approx.R @@ -0,0 +1,122 @@ +# File src/library/stats/R/approx.R +# Part of the R package, http://www.R-project.org +# +# Copyright (C) 1995-2012 The R Core Team +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# A copy of the GNU General Public License is available at +# http://www.r-project.org/Licenses/ + +### approx() and approxfun() are *very similar* -- keep in sync! + +## This function is used in approx, approxfun, spline, and splinefun +## to massage the input (x,y) pairs into standard form: +## x values unique and increasing, y values collapsed to match +## (except if ties=="ordered", then not unique) + +regularize.values <- function(x, y, ties) { + x <- xy.coords(x, y) # -> (x,y) numeric of same length + y <- x$y + x <- x$x + if(any(na <- is.na(x) | is.na(y))) { + ok <- !na + x <- x[ok] + y <- y[ok] + } + nx <- length(x) + if (!identical(ties, "ordered")) { + o <- order(x) + x <- x[o] + y <- y[o] + if (length(ux <- unique(x)) < nx) { + if (missing(ties)) + warning("collapsing to unique 'x' values") + # tapply bases its uniqueness judgement on character representations; + # we want to use values (PR#14377) + y <- as.vector(tapply(y,match(x,x),ties))# as.v: drop dim & dimn. + x <- ux + stopifnot(length(y) == length(x))# (did happen in 2.9.0-2.11.x) + } + } + list(x=x, y=y) +} + +#approx <- function(x, y = NULL, xout, method = "linear", n = 50, +# yleft, yright, rule = 1, f = 0, ties = mean) +#{ +# method <- pmatch(method, c("linear", "constant")) +# if (is.na(method)) stop("invalid interpolation method") +# stopifnot(is.numeric(rule), (lenR <- length(rule)) >= 1L, lenR <= 2L) +# if(lenR == 1) rule <- rule[c(1,1)] +# x <- regularize.values(x, y, ties) # -> (x,y) numeric of same length +# y <- x$y +# x <- x$x +# nx <- as.integer(length(x)) +# if (is.na(nx)) stop("invalid length(x)") +# if (nx <= 1) { +# if(method == 1)# linear +# stop("need at least two non-NA values to interpolate") +# if(nx == 0) stop("zero non-NA points") +# } +# +# if (missing(yleft)) +# yleft <- if (rule[1L] == 1) NA else y[1L] +# if (missing(yright)) +# yright <- if (rule[2L] == 1) NA else y[length(y)] +# stopifnot(length(yleft) == 1L, length(yright) == 1L, length(f) == 1L) +# if (missing(xout)) { +# if (n <= 0) stop("'approx' requires n >= 1") +# xout <- seq.int(x[1L], x[nx], length.out = n) +# } +# x <- as.double(x); y <- as.double(y) +# .Call(C_ApproxTest, x, y, method, f) +# yout <- .Call(C_Approx, x, y, xout, method, yleft, yright, f) +# list(x = xout, y = yout) +#} +# +#approxfun <- function(x, y = NULL, method = "linear", +# yleft, yright, rule = 1, f = 0, ties = mean) +#{ +# method <- pmatch(method, c("linear", "constant")) +# if (is.na(method)) stop("invalid interpolation method") +# stopifnot(is.numeric(rule), (lenR <- length(rule)) >= 1L, lenR <= 2L) +# if(lenR == 1) rule <- rule[c(1,1)] +# x <- regularize.values(x, y, ties) # -> (x,y) numeric of same length +# y <- x$y +# x <- x$x +# n <- as.integer(length(x)) +# if (is.na(n)) stop("invalid length(x)") +# +# if (n <= 1) { +# if(method == 1)# linear +# stop("need at least two non-NA values to interpolate") +# if(n == 0) stop("zero non-NA points") +# } +# if (missing(yleft)) +# yleft <- if (rule[1L] == 1) NA else y[1L] +# if (missing(yright)) +# yright <- if (rule[2L] == 1) NA else y[length(y)] +# force(f) +# stopifnot(length(yleft) == 1L, length(yright) == 1L, length(f) == 1L) +# rm(rule, ties, lenR, n) # we do not need n, but summary.stepfun did. +# +# ## 1. Test input consistency once +# x <- as.double(x); y <- as.double(y) +# .Call(C_ApproxTest, x, y, method, f) +# +# ## 2. Create and return function that does not test input validity... +# function(v) .approxfun(x, y, v, method, yleft, yright, f) +#} +# +## avoid capturing internal calls +#.approxfun <- function(x, y, v, method, yleft, yright, f) +# .Call(C_Approx, x, y, v, method, yleft, yright, f) -- GitLab