[R] Fwd: Dynamic regex/sub changes to function

Bert Gunter gunter.berton at gene.com
Tue Sep 23 02:18:01 CEST 2014


(failed to cc the list)

Daniel:

Do you understand what a parse tree is?

Try this:

 f <- function(x){
+ y <- x^2
+ z <- sin(y+2)
+ }

> body(f)
{
    y <- x^2
    z <- sin(y + 2)
}

> as.list(body(f))
[[1]]
`{`

[[2]]
y <- x^2

[[3]]
z <- sin(y + 2)

> body(f)[[c(3,3,1)]]
sin

> class(body(f))
[1] "{"


You should listen to your elders (Bill and Duncan) and **don't do this. **

Cheers,
Bert

Bert Gunter
Genentech Nonclinical Biostatistics
(650) 467-7374

"Data is not information. Information is not knowledge. And knowledge
is certainly not wisdom."
Clifford Stoll




On Mon, Sep 22, 2014 at 4:38 PM, Daniel Fuka <drf28 at cornell.edu> wrote:
> Thanks everyone for the help. I need to step back and refresh my
> memory on expressions as I am still unclear as to why I can not
> directly edit:
> body(nsong)[[2]]
> # Which can be located from a grep:
> body(nsong)[[grep("fuka",body(nsong))]]
> # though I believe
> class(body(nsong)[[2]])
> [1] "="
> # is trying to give me a pretty blatant hint... {: -)
>
> On Mon, Sep 22, 2014 at 1:24 PM, Duncan Murdoch
> <murdoch.duncan at gmail.com> wrote:
>> On 22/09/2014 11:34 AM, Daniel Fuka wrote:
>>>
>>> Howdy Duncan,
>>>
>>> Thanks for the quick reply!  I must be missing something
>>> simple/obvious. I need to have the "sub()" not return quoted and
>>> escaped characters to "just edit the language expression". In my
>>> problem, there is a function that is supported from a different
>>> package. So I always want to use the supported function as my base...
>>> but a url in the supported function needs to be changed dynamically
>>> for my application, which is easiest using "sub()".
>>>
>>> I am trying to do what you correctly indicate I would need to do:
>>> "just edit the language expression that body(fsong) gives you, and
>>> assign it back"
>>> BUT, using sub, I get back a quoted string in my example if I just use
>>> sed:
>>>
>>> > fsong
>>> function(x){
>>>   song=paste("my name is fuka,",x)
>>>   return(song)
>>> }
>>> # Using "sub()" becomes:
>>> > nsong
>>> function (x)
>>> {
>>>      "song = paste(\"my name is muka,\", x)"
>>>      return(song)
>>> }
>>
>>
>> You didn't do it right :-).   With fsong as above, the string to edit is
>> body(fsong)[[c(2,3,2)]].  (Why c(2,3,2)?  Because that's where the string is
>> in the parse tree.  Try looking at variations on body(fsong)[[c(2,3,2)]] to
>> figure it out, e.g.
>> body(fsong)[[c(2,3)]], or body(fsong)[[c(2,3,3)]], etc.)
>>
>> So this code would work:
>>
>> orig <- body(fsong)[[c(2,3,2)]]
>> new <- sub("fuka", "muka", orig)
>>
>> # Now put it back in nsong:
>> nsong <- fsong
>> body(nsong)[[c(2,3,2)]] <- new
>>
>> But as Bill said, this is a really bad idea.  If you just *think* about
>> changing that fsong function, it will break.
>>
>> Duncan Murdoch
>>
>>>
>>> Thanks again for the quick reply and help you are giving me!
>>> dan
>>>
>>> On Mon, Sep 22, 2014 at 10:37 AM, Duncan Murdoch
>>> <murdoch.duncan at gmail.com> wrote:
>>> > On 22/09/2014 9:16 AM, Daniel Fuka wrote:
>>> >>
>>> >> Howdy,
>>> >>
>>> >> I have searched the lists and can not seem to find a solution to my
>>> >> problem. I need to be able to dynamically modify a string inside a
>>> >> function to build a new function. "sub" replaces with a quoted
>>> >> string... and "parse" of "sub" returns expression... How can I get an
>>> >> unquoted string from a regex to stick into a "body" of a function?
>>> >
>>> >
>>> > It's possible to do what you want, though you don't want to be using
>>> > parse(), you can just edit the language expression that body(fsong)
>>> > gives
>>> > you, and assign it back.  But that's a messy way to solve your problem.
>>> >
>>> > Why not create a new function containing the new string?  e.g.
>>> >
>>> > makefsong <- function(name = "fuka") {
>>> >   line1 <- paste("my name is", name)
>>> >   function(x) {
>>> >     song <- paste(line1, x)
>>> >     return(song)
>>> >   }
>>> > }
>>> >
>>> > f1 <- makefsong()
>>> > f1("I live on the second floor")
>>> > f2 <- makefsong("muka")
>>> > f2("I live on the second floor")
>>> >
>>> > Duncan Murdoch
>>> >
>>> >>
>>> >> Thanks for your help!
>>> >> dan
>>> >>
>>> >> # Original Function
>>> >> fsong=function(x){
>>> >>   song=paste("my name is fuka,",x)
>>> >>   return(song)
>>> >> }
>>> >> fsong("I live on the second floor")
>>> >> #
>>> >> # Copy and modify using "sub" returns quoted string with escaped quotes
>>> >> #   internally... as expected.. which can not be evaluated.
>>> >> nsong=fsong
>>> >> body(nsong)[[grep("fuka",body(nsong))]]=
>>> >>     sub("fuka","muka",list(body(fsong)[[grep("fuka",body(fsong))]]))
>>> >>
>>> >> nsong("I live on the second floor") # broken
>>> >>
>>> >> #
>>> >> # Copy and modify with "parse" of  "sub",  returns expression.. but
>>> >> without quotes,
>>> >> # o getting closer.
>>> >> #
>>> >> nsong=fsong
>>> >> body(nsong)[[grep("fuka",body(nsong))]]=
>>> >>
>>> >>
>>> >> parse(text=sub("fuka","muka",list(body(fsong)[[grep("fuka",body(fsong))]])))
>>> >>
>>> >> ______________________________________________
>>> >> R-help at r-project.org 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.
>>> >
>>> >
>>
>>
>
> ______________________________________________
> R-help at r-project.org 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.



More information about the R-help mailing list