[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