ЯтомизоnoR

R, Statistics

Control the Function Scope by the R Package Namescope

An attractive feature of the package is the namespace.  The R language cannot write a function that has a limited scope.  But converting the same script to a package brings a scope by the namespace.  Because every package with namespace is loaded in a separated environment, functions are protected from overwriting.

aa.R

# for package a
c <- function() 'Hello from package a!'
a <- function() paste('A+', c())
b <- a

bb.R

# for package b
c <- function() 'Hello from package b!'
b <- function() paste('B+', c())

source

First, I want to show the case of non-packaged simple scripts.

After loading aa.R, the built-in function c() of base R is lost.  Because the base is also a package, the built-in c() is still available by calling base::c().

> ls()
character(0)
> source("aa.R")
> a()
[1] "A+ Hello from package a!"
> b()
[1] "A+ Hello from package a!"
> c()
[1] "Hello from package a!"
> base::c()
NULL
> ls()
[1] "a" "b" "c"

Then what happens after loading bb.R?

The b() and c() are overwritten and completely lost.  Moreover, a() shows an unexpected string, because it depends the lost c() function defined in the aa.R.

> source("bb.R")
> a()
[1] "A+ Hello from package b!"
> b()
[1] "B+ Hello from package b!"
> c()
[1] "Hello from package b!"

library

Now, build packages aa and bb for each of aa.R and bb.R.  Two reasons for me to use this package names.

  1. the package name must have 2 characters at minimum.
  2. using the same name of function and the package is not recommended, because it conflicts the name of help document aliases.

I chose to hide the function c() using a file NAMESPACE.

# NAMESPACE for package aa
export(a, b)

# NAMESPACE for package bb
export(b)

Remove sourced scripts, and then library packages from the temporary locations.

> remove(a,b,c)
> ls()
character(0)
> library(package=aa, lib.loc='/tmp/aa.Rcheck/')
> a()
[1] "A+ Hello from package a!"
> b()
[1] "A+ Hello from package a!"
> c()
NULL
> ls()
character(0)

The base::c() is not overwritten, while the a() and b() calls the aa::c() in the package.

> library(package=bb, lib.loc='/tmp/bb.Rcheck/')
The following object(s) are masked from ‘package:aa’:
b
> a()
[1] "A+ Hello from package a!"
> b()
[1] "B+ Hello from package b!"
> c()
NULL
> aa::b()
[1] "A+ Hello from package a!"
> search()
 [1] ".GlobalEnv"        "package:bb"        "package:aa"       
 [4] "tools:RGUI"        "package:stats"     "package:graphics" 
 [7] "package:grDevices" "package:utils"     "package:datasets" 
[10] "package:methods"   "Autoloads"         "package:base"

The b() function is overwritten.  But a() works correctly.  And aa:b() can access to the b() function in the package aa.

Usually, a complicated function have many private functions to help calculations.  These helper functions should be hidden in a limited scope, because these names may conflict to the global environment.  The advantage of packaging is to control the scope with the namespace.

Advertisements

One comment on “Control the Function Scope by the R Package Namescope

  1. Pingback: Making of elliplot package | ЯтомизоnoR

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Information

This entry was posted on September 16, 2013 by and tagged , , .
The stupidest thing...

Statistics, genetics, programming, academics

ЯтомизоnoR

R, Statistics

%d bloggers like this: