[R] Calling external file

William Dunlap wdunlap at tibco.com
Sun Oct 4 18:22:41 CEST 2015


Does the following pattern resemble what you have?

Here are a couple of functions that use the same code for finding the
location of the minimum of a function fn:
   f1 <- function(x) {
       fn <- function(beta) {
           sum((x-beta)^2)
       }
       argMinFn <- function() {
           beta <- seq(0, 1, len=129)
           beta[which.min(vapply(beta, fn, 0))]
       }
       argMinFn()
   }
   f2 <- function(x) {
       fn <- function(beta) {
           sum(abs(x-beta))
       }
       argMinFn <- function() {
           beta <- seq(0, 1, len=129)
           beta[which.min(vapply(beta, fn, 0))]
       }
       argMinFn()
   }
used as
   > f1(1/(1:10)) # approx. mean of 1/(1:10)
   [1] 0.2890625
   > f2(1/(1:10)) # approx median of 1/(1:10)
   [1] 0.171875

I think you are trying to avoid copying that argMinFn into every
function of this sort
so you move it out of the f1 and f2 functions:
       argMinFn.bad <- function() {
           beta <- seq(0, 1, len=129)
           beta[which.min(vapply(beta, fn, 0))]
       }
and omit it from f1 and f2
     f1a.bad <- function(x) {
       fn <- function(beta) {
           sum((x-beta)^2)
       }
       argMinFn.bad()
   }
Then you get the sort of error you describe
  > f1a.bad(1/(1:10))
  Error in match.fun(FUN) : object 'fn' not found
The problem is that a function first looks for objects defined in its own
environment, then in the environment in which the function was created,
then the parent of that environment, etc.  The stand-along argMinFn
was defined in the global environment so it does not look in the environment
of f1a.bad for fn.

The fix is to make fn an argument to the stand-along argMinFn and have
f1a.good pass fn into the environment of argMinFn via the argument list.
     argMinFn.good <- function(fn) {
         beta <- seq(0, 1, len=129)
         beta[which.min(vapply(beta, fn, 0))]
     }
     f1a.good <- function(x)
     {
        fn <- function(beta) {
          sum((x-beta)^2)
        }
        argMinFn.good(fn)
     }
e.g
    > f1a.good(1/(1:10))
    [1] 0.2890625

How functions look up variables is called 'scoping' and R's method is
called 'lexical scoping'.  You can find lots more information on this with
google.
Bill Dunlap
TIBCO Software
wdunlap tibco.com


On Sat, Oct 3, 2015 at 3:56 PM, Steven Yen <syen04 at gmail.com> wrote:
> Thanks Bill. Simplified content of max.calls.R (with repeated calls to
> maxLik removed) are shown below in the message. No, fn does not exist in
> the environment. I call a routine (say probit.R compiled into a library) to
> use maxLik. Inside this routine,
> 1. In probit.R. likelihood function is defined yet in another nested
> routine;
> 2. Function "max.calls" is also nested in that  probit.R;
> Then, a call to max.calls works.
>
> What I am trying to accomplish is, instead of inserting the identical
> function (or set of lines) in every routine like probit.R, I like to either
> compile max.calls.R or source it from inside probit.R. Thanks.
>
>
> On Sat, Oct 3, 2015 at 4:47 AM, Steven Yen <syen04 at gmail.com> wrote:
>
>> Hi
>> I collect a list of calls to a package in a function (routine) so that I
>> do not need to repeat the same sets of codes from program to program. In
>> the following, inserting the function into each program works. Then, I
>> place the function elsewhere in a PC folder, and include in with a 'source'
>> command. This does not work; it complains about a function (fn below) not
>> defined.
>> Compiling the function into a library file does not work either (with all
>> sorts of error messages saying this and that not defined).
>> Steven Yen
>>
>> fn <- function(beta){
>>   f<-... (define f in this routine)
>> return(f)
>> }
>>
>> max.calls<-function(method){
>> # *******************************************************
>> # Call maxLike with alternative algorithms
>> # *******************************************************
>>   many<-c("NR","BFGS","BFGSR","BHHH","SANN","CG","NM")
>>   if (method %in% many){
>>     ML<-maxLik(logLik=fn,grad=NULL,hess=NULL,start,
>>                method,print.level,constraints=NULL, ...)}
>> return(ML)
>> }
>> # This works:
>> ML<-max.calls(method)
>>
>> # Does not work:
>> source("z:\\R\\yenlib\\lib\\max.calls.R")
>> ML<-max.calls(method)
>>
>> Error: object 'fn' not found
>>
>>
>
>         [[alternative HTML version deleted]]
>
> ______________________________________________
> R-help at r-project.org mailing list -- To UNSUBSCRIBE and more, see
> 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