[R] Function that works within a package and not when copied in global environment. Why?

Bert Gunter bgunter.4567 at gmail.com
Thu Feb 2 17:48:52 CET 2017


OK.

Try:  nlWaldTest:::vectorize.args  (3 colons)

Your error message said it was *not* exported, so you need 3 colons
(which, in general, is a bad idea.It's usually not exported for a
reason).

I presume vectorize.args is is in the environment of the function
copied from the name space, because functions are actually closures
that include (pointers to) their environments; whereas it is certainly
not part of the (global) environment, the environment of the manually
created function by copy-paste of the code.

If I am wrong about this, I would appreciate a correction by someone
with better understanding of such subtleties than I.

-- Bert


Bert Gunter

"The trouble with having an open mind is that people keep coming along
and sticking things into it."
-- Opus (aka Berkeley Breathed in his "Bloom County" comic strip )


On Thu, Feb 2, 2017 at 8:34 AM, Marc Girondot <marc_grt at yahoo.fr> wrote:
> Thanks Bert for the explanation about identical.
>
> For the vectorize.args, note that vectorize.args is not a function but an
> variable that is unknown in the namespace nlWaldTest.
>
>> nlWaldTest::vectorize.args
> Erreur : 'vectorize.args' n'est pas un objet exporté depuis
> 'namespace:nlWaldTest'
>
>
> Furthermore, if the function is created from a copy of the original one:
>
> smartsub <- getFromNamespace(".smartsub", ns="nlWaldTest")
>
> or if it is created manually: by copy-paste of the code:
>
> smartsub2 <- function (pat, repl, x)
>  {
>      args <- lapply(as.list(match.call())[-1L], eval, parent.frame())
>      names <- if (is.null(names(args)))
>          character(length(args))
>      else names(args)
>      dovec <- names %in% vectorize.args
>      do.call("mapply", c(FUN = FUN, args[dovec], MoreArgs =
> list(args[!dovec]),
>                          SIMPLIFY = SIMPLIFY, USE.NAMES = USE.NAMES))
>  }
>
> Both are defined in the global env, but the first one works and not the
> second one.
>
> I am surprised and don't understand how it is possible.
>
> Sincerely
>
> Marc Girondot
>
>> 2. You need to review how namespaces work. From the "Writing R
>> extensions" manual:
>>
>> "The namespace controls the search strategy for variables used by
>> **functions in the package**. If not found locally, R searches the
>> package namespace first, then the imports, then the base namespace and
>> then the normal search path."
>>
>> So if vectorize.args() is among the package functions, it will be
>> found by package functions but not by those you write unless
>> specifically qualified by :: or ::: depending on whether it is
>> exported.
>>
>> Cheers,
>> Bert
>>
>>
>>
>> Bert Gunter
>>
>> "The trouble with having an open mind is that people keep coming along
>> and sticking things into it."
>> -- Opus (aka Berkeley Breathed in his "Bloom County" comic strip )
>>
>>
>> On Thu, Feb 2, 2017 at 6:30 AM, Marc Girondot via R-help
>> <r-help at r-project.org> wrote:
>>>
>>> Dear experts,
>>>
>>> In the package nlWaldTest, there is an hidden function : .smartsub
>>>
>>> I can use it, for example:
>>>
>>>> getFromNamespace(".smartsub", ns="nlWaldTest")(pat="x", repl="b" ,
>>>
>>> x="essai(b[1], b[2], x[1])")
>>> [1] "essai(b[1], b[2], b[1])"
>>>
>>> Now I try to create this function in my global environment:
>>> smartsub <- getFromNamespace(".smartsub", ns="nlWaldTest")
>>>
>>> It works also:
>>>>
>>>> smartsub(pat="x", repl="b" , x="essai(b[1], b[2], x[1])")
>>>
>>> [1] "essai(b[1], b[2], b[1])"
>>>
>>> But if I create the function manually:
>>>>
>>>> smartsub2 <- function (pat, repl, x)
>>>
>>>   {
>>>       args <- lapply(as.list(match.call())[-1L], eval, parent.frame())
>>>       names <- if (is.null(names(args)))
>>>           character(length(args))
>>>       else names(args)
>>>       dovec <- names %in% vectorize.args
>>>       do.call("mapply", c(FUN = FUN, args[dovec], MoreArgs =
>>> list(args[!dovec]),
>>>                           SIMPLIFY = SIMPLIFY, USE.NAMES = USE.NAMES))
>>>   }
>>>>
>>>> smartsub2(pat="x", repl="b" , x="essai(b[1], b[2], x[1])")
>>>
>>> Error in names %in% vectorize.args : objet 'vectorize.args' introuvable
>>>
>>> It fails because vectorize.args is unknown
>>>
>>> Indeed smartsub2 is different from smartsub.
>>>>
>>>> identical(smartsub, smartsub2)
>>>
>>> [1] FALSE
>>>
>>> 1/ Why are they different? They are just a copy of each other.
>>>
>>> 2/ Second question, vectorize.args is indeed not defined before to be
>>> used
>>> in the function. Why no error is produced in original function?
>>>
>>> Thanks a lot
>>>
>>> Marc
>>>
>>>
>>> --
>>>
>>> __________________________________________________________
>>> Marc Girondot, Pr
>>>
>>> Laboratoire Ecologie, Systématique et Evolution
>>> Equipe de Conservation des Populations et des Communautés
>>> CNRS, AgroParisTech et Université Paris-Sud 11 , UMR 8079
>>> Bâtiment 362
>>> 91405 Orsay Cedex, France
>>>
>>> Tel:  33 1 (0)1.69.15.72.30   Fax: 33 1 (0)1.69.15.73.53
>>> e-mail: marc.girondot at u-psud.fr
>>> Web: http://www.ese.u-psud.fr/epc/conservation/Marc.html
>>> Skype: girondot
>>>
>>> ______________________________________________
>>> 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