[R] functions and strings

Rich FitzJohn rich.fitzjohn at gmail.com
Wed Sep 13 11:54:51 CEST 2006


Hi,

Perhaps try this (based on 'bquote'):

rewrite.expression <- function(expr, to, dep) {
  f <- function(expr) {
    if ( length(expr) == 1 )
      if ( expr == as.name(dep) )
        as.name(to)
      else
        expr
    else
      as.call(lapply(expr, f))
  }
  f(expr)
}

rewrite <- function(expr, to, dep='x') {
  rewrite.expression(substitute(expr), to, dep)
}

> rewrite(1 + sin(cos(x)) + exp(x^2), 'xyz')
1 + sin(cos(xyz)) + exp(xyz^2)
> rewrite(sin(x)+exp(x), 'xyz')
sin(xyz) + exp(xyz)
> rewrite(sin(i) + cos(sin(i^2)), 'tti', 'i')
sin(tti) + cos(sin(tti^2))
## Or, closer to your example, using the name of the argument and body
## of the function:
f <- function(r)
  2*r/sin(r) - b

> rewrite.expression(body(f), 'foo', names(formals(f)))
2 * foo/sin(foo) - b

Hope that helps,
Rich

On 9/13/06, Robin Hankin <r.hankin at noc.soton.ac.uk> wrote:
> Hello everyone
>
> I know it looks like I'm making heavy weather of this, but
> I don't think I communicated my problem properly.  I really
> appreciate you guys' help here.
>
> I am writing a wrapper for a mathematical library to
> which I want to send character strings that it can execute,
> and then pass the answer back to R.
>
> Now, I want a user to be able to type _any_ function
> and _any_ string.  For example:
>
> f <- function(i){sin(i) + cos(sin(i^2))}
> string <- "tti"
>
> and then I want a function do() such that do(f,string) will return
>
> "sin(tti) + cos(sin(tti^2))"
>
> without worrying about whether f()'s arguments include or
> do not include a particular letter, and without insisting that "i"
> always appears as "(i)" .
>
> Although thinking about it, it's not
> actually that bad to require the user to use some otherwise
> rare sequence of letters, say "XxX" as
> an argument, and then Dmitris's first method would work.
>
> Having said that, this is not an ideal solution
> and it would be nicer to have some method that could detect
> what the argument to f() is, where it is in the body, and substitute
> those occurences for "string".
>
> I want a method  that is perfectly general; I posted my
> example of abcd...z(), not to be annoying and pedantic
> but to illustrate that a simple gsub approach wouldn't work:
> one has to know in advance which letters can and cannot
> be used, and this information isn't available.
>
> I don't have a function so named (yet ;-).
>
>
> best wishes
>
> rksh
>
> >
> > Hi Dmitris, Thierry,
> >
> > I'm getting there but it's still not quite right if f() includes
> > something like x^2:
> >
> > f <- function(x){exp(x^2)}
> >>>
> >
> > gsub("(x)", "(xyz)", deparse(body(f))[2], fixed = TRUE)
> >
> >
> > [1] "    x^2"
> >
> > [I don't care about the spaces]
> >
> >
> >
> > also,
> >
> >   I can't quite see how to implement Thierry's suggestion about
> > changing the letter "x" into a letter that does not occur in f(),
> > because of the
> > following example:
> >
> >   f <- function(x){abcdefghijklmnopqrstuvwxyz(x^2)}
> >
> >
> >
> >
> > On 13 Sep 2006, at 09:08, Dimitris Rizopoulos wrote:
> >
> >> yes you're right, maybe this is better
> >>
> >>> f <- function(x){sin(x)+exp(x)}
> >>> strng <- gsub("(x)", "(xyz)", deparse(body(f))[2], fixed = TRUE)
> >>> sub('^[[:space:]]+', '', strng)
> >> [1] "sin(xyz) + exp(xyz)"
> >>
> >>
> >> Best,
> >> Dimitris
> >>
> >
>
> --
> Robin Hankin
> Uncertainty Analyst
> National Oceanography Centre, Southampton
> European Way, Southampton SO14 3ZH, UK
>   tel  023-8059-7743
>
> ______________________________________________
> R-help at stat.math.ethz.ch mailing list
> https://stat.ethz.ch/mailman/listinfo/r-help
> PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
> and provide commented, minimal, self-contained, reproducible code.
>


-- 
Rich FitzJohn
rich.fitzjohn <at> gmail.com



More information about the R-help mailing list