Основная функция, которую вы хотите использовать, — это sys.source(), которая будет загружать ваши функции/переменные в пространство имен («окружение» в R), отличное от глобального. Еще одна фантастическая вещь, которую вы можете сделать в R, — это присоединить пространства имен к вашему пути search(), чтобы вам не нужно было напрямую ссылаться на пространство имен. То есть, если «namespace1» находится на вашем пути поиска, функция внутри него, скажем, «fun1», должна вызываться не как namespace1.fun1(), как в Python, а как fun1(). [Порядок разрешения методов:] Если имеется много функций с одинаковыми именами, будет вызвана та из них, которая стоит первой в списке search(). Для явного вызова функции в конкретном пространстве имен одним из многих возможных синтаксисов, хотя и немного уродливым, является get("fun1","namespace1")(...), где ... — аргументы fun1(). Это также должно работать с переменными, используя синтаксис get("var1","namespace1"). Я делаю это постоянно (обычно я загружаю только функции, но разница между функциями и переменными в R невелика), поэтому я написал несколько удобных функций, которые загружаются из моего ~/.Rprofile.
name.to.env <- function(env.name)
## returns named environment on search() path
pos.to.env(grep(env.name,search()))
attach.env <- function(env.name)
## creates and attaches environment to search path if it doesn't already exist
if( all(regexpr(env.name,search())<0) ) attach(NULL,name=env.name,pos=2)
populate.env <- function(env.name,path,...) {
## populates environment with functions in file or directory
## creates and attaches named environment to search() path
## if it doesn't already exist
attach.env(env.name)
if( file.info(path[1])$isdir )
lapply(list.files(path,full.names=TRUE,...),
sys.source,name.to.env(env.name)) else
lapply(path,sys.source,name.to.env(env.name))
invisible()
}
Пример использования:
populate.env("fun1","pathtofile/functions1.R")
populate.env("fun2","pathtofile/functions2.R")
и так далее, что создаст два отдельных пространства имен: "fun1" и "fun2", которые присоединены к пути search() (в этом случае "fun2" будет выше в списке search()). Это похоже на выполнение чего-то вроде
attach(NULL,name="fun1")
sys.source("pathtofile/functions1.R",pos.to.env(2))
вручную для каждого файла ("2" — позиция по умолчанию на пути search()). То, как записывается populate.env(), если каталог, скажем, «functions/», содержит много файлов R без конфликтующих имен функций, вы можете назвать его как
populate.env("myfunctions","functions/")
для загрузки всех функций (и переменных) в единое пространство имен. С name.to.env() вы также можете сделать что-то вроде
with(name.to.env("fun1"), doStuff(var1))
or
evalq(doStuff(var1), name.to.env("fun1"))
Конечно, если ваш проект разрастается и у вас много-много функций (и переменных), написание пакета — это то, что вам нужно.
person
hatmatrix
schedule
14.04.2010
package.skeletonнесложно, и в долгосрочной перспективе это принесет много преимуществ. - person Shane   schedule 14.04.2010