[R] Multivariate function from univariate functions

Petr Savicky savicky at cs.cas.cz
Sun Mar 25 20:14:44 CEST 2012


On Sat, Mar 24, 2012 at 08:04:49PM -0700, physicistintheory wrote:
> I'm relatively new to R and I'm stuck.
> 
> I'm trying to construct a surface to optimize from a multivariate dataset. 
> The dataset contains the response of a system to various stimuli.  I am
> trying to optimize the mix of stimuli to maximize the response.  To do so,
> I've interpolated the various datasets of type response vs. stimuli and I
> now have an array of functions "interps" whose length is the length of the
> array of the names of the various stimuli.  I've also created a vector
> containing names for the stimuli, vars = x.1, x.2, x.3...
> 
> Anyway, each of the functions in interps depends only on one variable
> (obviously).  I would like to construct a function, call it, "surface" which
> is essentially: surface(vars) = interps[[1]]vars[[1]] +
> interps[[2]]vars[[2]]+...
> 
> I've tried constructing surface recursively in a for loop:  
> surface <- function(vars){0}
> for(i in 1:length(vars)){
> surface <- function(vars){surface(vars) + interps[[i]](vars[[i]])}
> }

Hi.

Is the following close to what you are asking for?

  f1 <- function(x) 3*x^2 + x
  f2 <- function(x) 2*x^2 + 2*x
  f3 <- function(x) x^2 + 3*x
  lstf <- list(f1, f2, f3)
  args <- c("x2", "x4", "x5")

  # input as a matrix or data frame
  surface <- function(dat)
  {
      y <- rep(0, times=nrow(dat))
      for (i in seq.int(along=lstf)) {
          y <- y + lstf[[i]](dat[, args[i]])
      }
      y
  }

  dat <- matrix(1:35, ncol=5)
  colnames(dat) <- paste("x", 1:5, sep="")

  surface(dat)

  [1] 2140 2346 2564 2794 3036 3290 3556

  # compare with an explicit formula
  f1(dat[, "x2"]) + f2(dat[, "x4"]) + f3(dat[, "x5"])

  [1] 2140 2346 2564 2794 3036 3290 3556

  # input as a named vector
  surface1 <- function(x)
  {
      y <- 0
      for (i in seq.int(along=lstf)) {
          y <- y + lstf[[i]](x[args[i]])
      }
      unname(y)
  }

  vdat <- 1:5
  names(vdat) <- paste("x", 1:5, sep="")

  surface1(vdat) 

  [1] 94

  # compare again
  unname(f1(vdat["x2"]) + f2(vdat["x4"]) + f3(vdat["x5"]))

  [1] 94

Hope this helps.

Petr Savicky.



More information about the R-help mailing list