[英]hiding personal functions in R
我的.Rprofile中有一些便利函數,比如這個用於返回內存中對象大小的方便函數 。 有時我喜歡在不重新啟動的情況下清理我的工作區,並使用rm(list=ls())
此操作,刪除所有用戶創建的對象和我的自定義函數。 我真的很想不吹噓我的自定義功能。
解決這個問題的一種方法似乎是使用我的自定義函數創建一個包,以便我的函數最終在他們自己的命名空間中。 這不是特別難,但有沒有更簡單的方法來確保自定義函數不被rm()殺死?
attach
和sys.source
結合到源環境中並附加該環境。 這里我在文件my_fun.R
有兩個函數:
foo <- function(x) {
mean(x)
}
bar <- function(x) {
sd(x)
}
在加載這些函數之前,顯然找不到它們:
> foo(1:10)
Error: could not find function "foo"
> bar(1:10)
Error: could not find function "bar"
創建環境並將文件導入其中:
> myEnv <- new.env()
> sys.source("my_fun.R", envir = myEnv)
仍然不可見,因為我們沒有附加任何東西
> foo(1:10)
Error: could not find function "foo"
> bar(1:10)
Error: could not find function "bar"
當我們這樣做時,它們是可見的,並且因為我們已經將環境的副本附加到搜索路徑,所以這些函數存在於rm()
ed中:
> attach(myEnv)
> foo(1:10)
[1] 5.5
> bar(1:10)
[1] 3.027650
> rm(list = ls())
> foo(1:10)
[1] 5.5
我仍然認為你自己的個人套餐會更好,但在此期間,上述內容可能就足夠了。 只記得搜索路徑上的副本只是一個副本 。 如果函數是相當穩定的並且你沒有編輯它們,那么上面的內容可能會有用,但如果你正在開發函數並修改它們,它可能比它的價值更麻煩。
第二種選擇是將它們全部命名為.foo
而不是foo
因為ls()
不會返回這樣命名的對象,除非設置了參數all = TRUE
:
> .foo <- function(x) mean(x)
> ls()
character(0)
> ls(all = TRUE)
[1] ".foo" ".Random.seed"
這有兩種方式:
1)讓每個函數名都以點開頭,例如.f
而不是f
。 除非你使用ls(all.names = TRUE)
否則ls
不會列出這些函數,因此它們不會傳遞給你的rm
命令。
要么,
2)把它放在.Rprofile中
attach(list(
f = function(x) x,
g = function(x) x*x
), name = "MyFunctions")
這些函數將在您的搜索列表中顯示為名為"MyFunctions"
的組件,而不是在您的工作區中,它們幾乎可以像在工作區中一樣訪問。 search()
將顯示您的搜索列表, ls("MyFunctions")
將列出您附加的函數的名稱。 由於它們不在您的工作區中,因此您通常使用的rm
命令不會刪除它們。 如果您確實希望刪除它們,請使用detach("MyFunctions")
。
加文的答案很精彩,我只是贊成它。 僅僅為了完整性,讓我再折騰一下:
R> q("no")
其次是
M-x R
創建一個新的會話---重新讀取.Rprofile
。 簡單,快速,便宜。
除此之外,私人套餐是我書中的方式。
另一種選擇:將函數保存在一個單獨的文件中,該文件來自.RProfile
。 您可以在閑暇時直接從R內重新獲取內容。
我發現在創建或調試函數時,我的R環境經常會被各種對象弄得亂七八糟。 我想要一種在保留個人功能的同時有效保持環境免受這些對象影響的方法。
以下簡單的功能是我的解決方案。 它做了兩件事:1)刪除所有不以大寫字母開頭的非功能對象然后2)將環境保存為RData文件
(需要R.oo包)
cleanup=function(filename="C:/mymainR.RData"){
library(R.oo)
# create a dataframe listing all personal objects
everything=ll(envir=1)
#get the objects that are not functions
nonfunction=as.vector(everything[everything$data.class!="function",1])
#nonfunction objects that do not begin with a capital letter should be deleted
trash=nonfunction[grep('[[:lower:]]{1}',nonfunction)]
remove(list=trash,pos=1)
#save the R environment
save.image(filename)
print(paste("New, CLEAN R environment saved in",filename))
}
為了使用此功能,必須始終保留3個規則:
1)將所有數據保存在R外部。
2)對於我希望永久保持可用的非功能對象,使用以大寫字母開頭的名稱。
3)必須使用rm手動刪除過時的功能。
顯然,這不是每個人的一般解決方案......如果你沒有遵守規則#1和#2,可能會帶來災難性的后果。 但它確實有很多優點:a)擔心我的數據被清理所困擾()讓我遵守使用R作為處理器而不是數據庫的規定,b)我的主要R環境太小我可以備份為電子郵件附件,c)自動保存新功能(我不必手動管理個人功能列表)和d)保留對預先存在的功能的所有修改。 當然最好的優勢是最明顯的一個......我不必花時間做ls()並查看對象來決定是否應該使用它們。
即使你不關心我的系統的細節,R.oo中的“ll”函數對於這種事情非常有用。 它可用於實現適合您個人編程風格的任何清理規則集。
帕特里克莫爾
第n個快速且臟的選項是在使用rm()
時使用lsf.str()
來獲取當前工作空間中的所有函數。 ...並讓您根據需要命名功能。
pattern <- paste0('*',lsf.str(), '$', collapse = "|")
rm(list = ls()[-grep(pattern, ls())])
我同意,這可能不是最好的做法,但它完成了工作! (無論如何我必須選擇性地清理自己...)
與Gavin的回答類似,下面加載一個函數文件,但不會留下額外的環境對象:
if('my_namespace' %in% search()) detach('my_namespace'); source('my_functions.R', attach(NULL, name='my_namespace'))
這將刪除舊版本的命名空間(如果它已附加(對開發很有用)),然后附加一個名為my_namespace
的空新環境並將my_functions.R
源化為它。 如果不刪除舊版本,則會構建多個同名的附加環境。
如果您想查看已加載哪些功能,請查看輸出
ls('my_namespace')
要卸載,請使用
detach('my_namespace')
這些附加函數(如包)不會被rm(list=ls())
刪除。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.