[R] selectively importing functions etc. from files

Charles C. Berry cberry at tajo.ucsd.edu
Sun Nov 30 23:36:18 CET 2008


On Sun, 30 Nov 2008, Faheem Mitha wrote:

>
> Hi Charles,
>
> Thanks for the reply.
>
> On Sun, 30 Nov 2008, Charles C. Berry wrote:
>
>>  On Sat, 29 Nov 2008, Faheem Mitha wrote:
>> 
>> > 
>> >  Hi,
>> > 
>> >  If I want to import the contents of a R file into another one, I can do
>> > 
>> >  source("foo.R")
>> > 
>> >  However, this imports everything from foo.R, including all functions and 
>> >  global variables. Is there a way of selectively importing individual 
>> >  functions etc., in a similar fashion to Python's
>> > 
>> >  from foo import bar
>> 
>>
>>  There are probably a lot of ways to skin this cat.
>>
>>  But you might want to explain why you want to do this in the first place.
>
>>  It may turn out that the problem you wish to solve is better addressed by
>>  placing your objects in a package that is attached far down the search
>>  list.
>
> Well, I just want to be able to selectively import specific functions from 
> files, so I can control what has been imported. One minor advantage of this 
> (there are many) is that it makes it difficult to accidentally overwrite 
> objects of the same name with each other. This is quite standard practice 
> across languages to avoid polluting the global namespace. And of course, I'd 
> like to do this as simply as possible.

Right. And if you put all the objects in a package and do this:

## if you want to mask as little as possible, use
library(mypkg, pos = "package:base")

you will achieve this. You can also set

 	LazyLoad: yes

in the DESCRIPTION file. Then if you want to 'promote' functions to 
the .GlobalEnv, you can do

 	foo <- mypkg:::foo

Come to think of it, if the functions are all made local to the mypkg 
namespace, then they will only mask funcitons further down the search() 
list if they are called by other functions in mypkg.

>
>>  A simple way to do what you say you want:
>>
>>  Use
>>
>>   source("foo.R", local=TRUE)
>>
>>  from within a function. Then either assign( ..., envir=.GlobalEnv )
>>  selected objects or attach( list( ) ) them.
>
> Not sure I follow this. I want to import into the global namespace. Why would 
> I import from within a function? You mean first import locally into some 
> function and then selectively export to the global namespace?

Exactly. The objects that are not assign()ed or attach()ed will 
'disappear'.

>
>>  Another way is to use parse, as.character.srcref, and friends to avoid
>>  evaluating each of the objects, then eval() selected expressions in the
>>  desired environment.
>
> And this one even less. Can you give a simple example?

OK. parse a file with two functions in it. Find one of the function 
expressions and evaluate it:

> cat("foo <- function(x) x+1;bar <- function(x) x*2",file="foobar.R")
> foobar.expr <- parse("foobar.R")
> ls()
[1] "foobar.expr"
> grep("foo <-",sapply(attr(foobar.expr,'srcref'),function(x) as.character(x)))
[1] 1
> eval(foobar.expr[[ 1 ]]) 
> ls()
[1] "foo"         "foobar.expr"
> foo
function(x) x+1

---

Another way to achieve what you want is to put source of each function in 
its own file in a single directory. Then

 	source(file.path("pkgpath","foo.R"))

will load the single function in pkgpath/foo.R

HTH,

Chuck

>
>                                                          Regards, Faheem.
>
> ______________________________________________
> 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.
>
>

Charles C. Berry                            (858) 534-2098
                                             Dept of Family/Preventive Medicine
E mailto:cberry at tajo.ucsd.edu	            UC San Diego
http://famprevmed.ucsd.edu/faculty/cberry/  La Jolla, San Diego 92093-0901



More information about the R-help mailing list