Hello everyone,
I often create some local "libraries" of functions (.R files with only
functions in them) that I latter call. In scripts that call a function
from such library, I would like to be able to test whether the
function is already known in the namespace and, only if it is not,
source the library file. I.e. what `require` does for packages, I want
to do with my local functions.
Example:
lib.R
foo <- function(x) { x*2 }
script.R
require.local(foo,"lib.R")
# that searches for function "foo" and, if not found, executes
source("lib.R")
foo(2)
Obviously, I want the test to be quite efficient otherwise I might as
well source the local library every time. I am aware that it would
probably not be able to check for changes in lib.R (i.e. do
complicated things such as re-source lib.R if foo in the namespace and
foo in lib.R are different), but that I can handle manually.
This seems like a common enough workflow but I cannot find a pre-
existing solution. Does anyone have pointers?
Otherwise I tried to put that together:
require.local <- function(fun, lib)
#
# Searches for function "fun" and sources "lib" in
# case it is not found
#
{
if (! (deparse(substitute(fun)) %in% ls(".GlobalEnv") && class(fun)
== "function") ) {
cat("Sourcing", lib,"...\n")
source(lib)
}
}
but I am really not confident with all those deparse/substitute things
and the environment manipulation, so I guess there should be a better
way.
JiHO
---
http://jo.irisson.free.fr/
'require' equivalent for local functions
6 messages · Gabor Grothendieck, Wacek Kusnierczyk, Duncan Murdoch +2 more
Try this:
if (!exists("myfun", mode = "function")) source("myfile.R")
Also check the other arguments of exists in case you want to
restrict the search.
On Sun, Mar 22, 2009 at 5:05 PM, JiHO <jo.lists at gmail.com> wrote:
Hello everyone,
I often create some local "libraries" of functions (.R files with only
functions in them) that I latter call. In scripts that call a function from
such library, I would like to be able to test whether the function is
already known in the namespace and, only if it is not, source the library
file. I.e. what `require` does for packages, I want to do with my local
functions.
Example:
lib.R
? ? ? ?foo <- function(x) { x*2 }
script.R
? ? ? ?require.local(foo,"lib.R")
? ? ? ?# that searches for function "foo" and, if not found, executes
source("lib.R")
? ? ? ?foo(2)
Obviously, I want the test to be quite efficient otherwise I might as well
source the local library every time. I am aware that it would probably not
be able to check for changes in lib.R (i.e. do complicated things such as
re-source lib.R if foo in the namespace and foo in lib.R are different), but
that I can handle manually.
This seems like a common enough workflow but I cannot find a pre-existing
solution. Does anyone have pointers?
Otherwise I tried to put that together:
require.local <- function(fun, lib)
#
# ? ? ? Searches for function "fun" and sources "lib" in
# ? ? ? case it is not found
#
{
? ? ? ?if (! (deparse(substitute(fun)) %in% ls(".GlobalEnv") && class(fun)
== "function") ) {
? ? ? ? ? ? ? ?cat("Sourcing", lib,"...\n")
? ? ? ? ? ? ? ?source(lib)
? ? ? ?}
}
but I am really not confident with all those deparse/substitute things and
the environment manipulation, so I guess there should be a better way.
JiHO
---
http://jo.irisson.free.fr/
______________________________________________ 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.
JiHO wrote:
Hello everyone,
I often create some local "libraries" of functions (.R files with only
functions in them) that I latter call. In scripts that call a function
from such library, I would like to be able to test whether the
function is already known in the namespace and, only if it is not,
source the library file. I.e. what `require` does for packages, I want
to do with my local functions.
Example:
lib.R
foo <- function(x) { x*2 }
script.R
require.local(foo,"lib.R")
# that searches for function "foo" and, if not found, executes
source("lib.R")
foo(2)
Obviously, I want the test to be quite efficient otherwise I might as
well source the local library every time. I am aware that it would
probably not be able to check for changes in lib.R (i.e. do
complicated things such as re-source lib.R if foo in the namespace and
foo in lib.R are different), but that I can handle manually.
This seems like a common enough workflow but I cannot find a
pre-existing solution. Does anyone have pointers?
Otherwise I tried to put that together:
require.local <- function(fun, lib)
#
# Searches for function "fun" and sources "lib" in
# case it is not found
#
{
if (! (deparse(substitute(fun)) %in% ls(".GlobalEnv") &&
class(fun) == "function") ) {
perhaps
find(deparse(substitute(fun)), mode='function')
but note that this will *not* tell you whether *the* function you want
to import is already known, but rather whether *some* function with the
specified name is already known.
vQ
On 22/03/2009 5:05 PM, JiHO wrote:
Hello everyone, I often create some local "libraries" of functions (.R files with only functions in them) that I latter call. In scripts that call a function from such library, I would like to be able to test whether the function is already known in the namespace and, only if it is not, source the library file. I.e. what `require` does for packages, I want to do with my local functions.
That's pretty hard to make bulletproof. Why not just put those functions in a package, and use that package? If the functions are all written in R, creating the package is very easy: see package.skeleton. (And if you have a perfect memory and don't plan to distribute the package to anyone, you can skip documenting the functions: then it's almost no work at all.) Duncan Murdoch
Example:
lib.R
foo <- function(x) { x*2 }
script.R
require.local(foo,"lib.R")
# that searches for function "foo" and, if not found, executes
source("lib.R")
foo(2)
Obviously, I want the test to be quite efficient otherwise I might as
well source the local library every time. I am aware that it would
probably not be able to check for changes in lib.R (i.e. do
complicated things such as re-source lib.R if foo in the namespace and
foo in lib.R are different), but that I can handle manually.
This seems like a common enough workflow but I cannot find a pre-
existing solution. Does anyone have pointers?
Otherwise I tried to put that together:
require.local <- function(fun, lib)
#
# Searches for function "fun" and sources "lib" in
# case it is not found
#
{
if (! (deparse(substitute(fun)) %in% ls(".GlobalEnv") && class(fun)
== "function") ) {
cat("Sourcing", lib,"...\n")
source(lib)
}
}
but I am really not confident with all those deparse/substitute things
and the environment manipulation, so I guess there should be a better
way.
JiHO
---
http://jo.irisson.free.fr/
______________________________________________ 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.
I agree with Duncan. I used to do exactly what you did - source()ing data files inside a wrapper not unlike C #define wrappers, but it became a headache with more files and the files began looking more cluttered. It has taken me several days to learn about how create a package properly, along with package RUnit for unit-testing, and with documentation. The "R Extensions" file is often a good source of information. Be sure you find information about Rcmd install and Rcmd check, which are also very useful. prompt() can help you build your .Rd (help files). Alternatively, you may use Rdoc$compile() (from package R.oo) if you intend to embed your Rdoc-style comments inside your R code, as I do. I also use R.oo as a more traditional object-oriented alternative to S3/S4. Once set-up, you can automagically generate .pdf files and .chm (windows-based help) for your package. Help for my own package has helped me keep my code consistent, clean, and re-factorable. Best of all, you can use put require( my.package ) or data( my.data) and voila. It has been a bit of a learning curve, but the packaging facilities in R are actually very well developed. Once set-up, maintenance becomes less of a chore. Good luck.
Duncan Murdoch-2 wrote:
On 22/03/2009 5:05 PM, JiHO wrote:
Hello everyone, I often create some local "libraries" of functions (.R files with only functions in them) that I latter call. In scripts that call a function from such library, I would like to be able to test whether the function is already known in the namespace and, only if it is not, source the library file. I.e. what `require` does for packages, I want to do with my local functions.
That's pretty hard to make bulletproof. Why not just put those functions in a package, and use that package? If the functions are all written in R, creating the package is very easy: see package.skeleton. (And if you have a perfect memory and don't plan to distribute the package to anyone, you can skip documenting the functions: then it's almost no work at all.)
View this message in context: http://www.nabble.com/%27require%27-equivalent-for-local-functions-tp22650626p22653884.html Sent from the R help mailing list archive at Nabble.com.
Thanks very much to everyone. I think I will use a combination of both techniques.
On 2009-March-22 , at 20:08 , Duncan Murdoch wrote:
That's pretty hard to make bulletproof. Why not just put those functions in a package, and use that package?
I know it will be impossible to make bullet proof and efficient at the same time. However, my functions are pretty specific to each project, have long names and do not collide with variable names (because I use dots in function names but camel case in variable names) so just looking for the name should be OK. Plus I have a simple keyboard shortcut in my text editor to source the current file in the currently R session, so it will be easy to re-source some files after I modify them. On the other hand I have a bundle of general enough functions that I import in many projects (http://github.com/jiho/r-utils/ for those that might be interested in netCDF data handling, 2D arrow fields and ggplot2 stuff) and this one is a good candidate to be turned into a package. So thanks again to everyone. Sincerely, JiHO --- http://jo.irisson.free.fr/