0

This is some sample code:

a<-c(1,2); 
f1<-function(dataset){
        cat("a=",a,"\n");
        b<-rev(a);
        cat("b=",b,"\n");
        f2("b");}
f2<-function(dataset){ 
        print(exists(dataset));
        print(dataset); # do analysis on dataset b
}

Output:

> f1(a)
a= 1 2 
b= 2 1 
[1] FALSE
[1] "b"

How do I make the intermediate variable b be available in function f2 (without changing function f2 which belongs to some package)?

Thanks.

fishtank
  • 3,718
  • 1
  • 14
  • 16

2 Answers2

0

I do get

> f1(a)
a= 1 2 
b= 2 1 
[1] TRUE
[1] "b"

however in this situations I use the envir paramenter of exists ( even if belong to some package you can still change it)

f2<-function(dataset){ 
  print(exists(dataset, envir=envir=parent.frame()))
  print(dataset) # do analysis on dataset b
}

If you really cannot modify f2 you have to "improve" f1...

a<-c(1,2)
f1<-function(dataset){
  f2<-function(dataset){ 
    print(exists(dataset, envir=parent.frame()))
    print(dataset) # do analysis on dataset b
  }
  cat("a=",a,"\n")
  b<-rev(a)
  cat("b=",b,"\n")
  f2("b")
}

> f1(a)
a= 1 2 
b= 2 1 
[1] TRUE
[1] "b"

the issue is, R looks for objects named "b" in the current environment (which the function b itself) then, if no object b is found, goes into the "upper" level...

this upper level is the parent environment inside which b is defined ( in your case the .GlobalEnv), and b is not there but inside f1.

Defining f2 inside f1 makes R going to look for b in f1 before going into the .GlabalEnv. My first solution made use of parent.frame, which explicitly asksR to look for the object into the environment where f2 was invoked, which is a different concept than parent environment.

Michele
  • 8,563
  • 6
  • 45
  • 72
  • Is it possible to do it without editing f2 which exists in some package? make b available in scope of f2. – fishtank Jul 01 '13 at 20:54
  • @user2540309 yes and no... the only way would be defining `f2` inside `f1`. see the edit – Michele Jul 01 '13 at 22:56
  • 1
    @user2540309 It really sounds like you're trying to do something that you shouldn't be doing. Maybe you could explain your actual situation? It's possible you're trying to find a solution to a problem that shouldn't exist because you're going about it the wrong way? – Dason Jul 01 '13 at 23:09
  • @user2540309 you may want to read [this](http://stackoverflow.com/questions/7439110/what-is-the-difference-between-parent-frame-and-parent-env-in-r-how-do-they) as well – Michele Jul 01 '13 at 23:13
  • the situation is function f2 exists in a package which I would prefer to leave untouched. f1 is just a wrapper to do a transformation on the data before passing it to f2 to crunch. I know one way is use b<<-rev(a) but this leaves b in the global environment at the end so I was wondering if there are alternatives... – fishtank Jul 01 '13 at 23:37
  • Now it sounds more like `f2` is doing something it shouldn't be doing. Can you post the actual code of `f2`? It shouldn't need to use anything like `exists`. – Hong Ooi Jul 02 '13 at 00:57
  • function f2 is the comproc function from the roc suite: http://labs.fhcrc.org/pepe/dabs/rocbasic.html. E.g. `comproc(dataset="nnhs2", d="d", markers=c("y1","y2"))`, inside comproc, it checks `if(exists(dataset))`. I didn't write the code but it seems legitimate to me. All I want to do is call comproc within my function that sets up a transform version of dataset as the simple example shows. any suggestions? – fishtank Jul 02 '13 at 04:40
  • @user2540309 I tried to simulate `f2` being in a package defining it in a `new.env` and assigning `b` in that environment (in your case you can assign `b` inside the package of `comproc`) – Michele Jul 02 '13 at 05:34
0

I think you have variable "b" in function2, however it doesn't exist in the global space.

"exist("b")" show FALSE, but in the region of f2, b has the value and can be worked on.

a<-c(1,2);
f2<-function(dataset){ 
        print(dataset); # do analysis on dataset b
        return(dataset+1)
}

f1<-function(dataset){
        cat("a=",a,"\n");
        b<-rev(a);
        cat("b=",b,"\n");
        c <- f2(b);
        cat("c=",c,"\n");  
      }

f1(a)
default locale
  • 13,035
  • 13
  • 56
  • 62
casper
  • 1