R語言中assign函數和get函數的用法
assign函數在循環時候,給變量賦值,算是比較方便
1、給變量賦值
for (i in 1:(length(rowSeq)-1)){ assign(paste("nginx_server_fields7_", i, sep = ""), nginx_server_fields7[(rowSeq[(i-1)+1]):(rowSeq[i+1]), ]) }
2、通過for循環給變量a1、a2、a3賦值
for (i in 1:3){ assign(paste("a", i, sep = ""), i:10) } ls() [1] "a1" "a2" "a3" "i" > a1 [1] 1 2 3 4 5 6 7 8 9 10 > a2 [1] 2 3 4 5 6 7 8 9 10
3、get和assign聯合用法
rm(list = ls()) #這個命令千萬慎重使用 for(i in 1:3){ assign(paste("p", i, sep=""), i) tmp <- get(paste("p", i, sep="")) print(tmp) } [1] 1 [1] 2 [1] 3 ls() [1] "i" "p1" "p2" "p3" "tmp"
補充:R語言函數的簡單理解
R語言結合瞭面向對象編程語言和函數式編程語言的特性,由於擁有函數式編程的特性,R的每一個運算符,實際上也是函數,同樣,面向對象的特性決定瞭你接觸到的R中所有東西(從數字到字符串到矩陣等)都是對象。
這些綜合的特質決定瞭R這門語言的特殊性,最大的特點就是開源,R中有許多用戶無私貢獻的包,通過這些包,可以實現強大的功能,因此,在在的統計處理或者數據挖掘等數據處理相關工作中,R常常作為數據預處理和建立初步模型的強大工具,但作為一門解釋型語言,R的運行效率比不上同等下的C等編譯型語言,特別是在高性能計算中。
因此,個人認為未來或者是現在將流行這樣一種數據處理方式:用R對數據進行預處理,同時通過R建立初步的數據處理模型,待對模型進行評估並確定如何實施之後通過更高效的語言(C語言等)來實現。
R中變量作用域的層次結構同C語言類似,但最大的不同在於,在R函數中可以創建新的函數,這樣會增加新的層次。
R擁有函數式編程的特性,基於函數式編程語言的特征,函數不會修改非局部變量,在R中,函數幾乎沒有副作用,簡單的理解為,函數的一般代碼可以讀但是不能寫非全局變量(當然通過特定函數是可以修改全局變量的)。
一般代碼表面上可以給全局變量重新賦值,但實際上這些操作隻會修改全局變量在特定層次中的備份,而全局變量本身不會發生變化。如下面例子所示:
i <- 1 test <- function(){ i <- 2 print(sprintf("the value from test(): %i", i)) } test() print(sprintf("the value from global:%i", i))
執行以上代碼,結果如下所示:
在以上代碼中,i是全局變量,順序執行test()函數,在test中給i賦值為2,此時打印的結果是局部變量中的值。test()函數執行完之後再打印i的值,結果卻仍然是1,說明test中的賦值並沒有修改全局變量i。
一般情況下,使用R中的函數不會有副作用,可以有以下幾點理解:
1)隻引用而不改變全局變量,局部變量與全局變量共享內存空間,此時的值必然相同;
2)一旦函數對全局變量重新賦值,系統將會創建一個與全局變量同名的新變量,並為這個變量分配新的內存空間,但這個新變量隻處在宿主函數這個層次中,根據變量的引用關系,優先引用離自己較近的本層或者上層環境中變量,所以在該函數中基本上隻會用全局變量的同名局部變量瞭;
3)隨著函數調用結束,系統會釋放函數中的局部變量,新創建的全局變量的同名局部變量也將銷毀,而全局變量的值並沒有因為在函數中使用而發生變化。
當然,R中也提供瞭特定的函數來對函數的上級層次進行寫操作,那就是<<-和assign()。
1.超賦值運算符<<-的機理為:使用<<-進行賦值操作
系統會從第一個上級層次開始,由低到高逐層進行查找,直到在某個層次中找到該變量,如果找不到該變量,系統會在頂層環境中創建一個新的變量。註意,超賦值運算符<<-隻查上級,不會對本級進行查找。
如下例所示:
A)
i <- 1 testA <- function() { i <<- 2 print(sprintf("the value from testA(): %i", i)) } testA() print(sprintf("the value from global:%i", i))
B)
testB<-function() { i<<-2 print(sprintf("the value from testB(): %i", i)) } testB() print(sprintf("the value from global:%i", i))
結果如下:
A)
B)
兩次運行的結果相同,在A)中,<<-修改瞭全局變量值i,在testA函數中引用瞭修改後的值,結果為2,在B)中,<<-向上查找,沒有找到名為i的全局變量,但是系統在全局環境中創建瞭名為i的全局變量並為其賦值為2。
2.使用assign()函數來對非局部變量進行寫操作
該函數的特性為:向指定層次(本級或上級)中的某個變量賦值,有則修改,無則創建。
如下代碼所示:
test <-function() { i <- 1 innertest<-function(x) { i<-3 assign("i",2*x,pos=.GlobalEnv) print(sprintf("the value from innertest(): %i",i)) } innertest(5) print(sprintf("the value from test(): %i", i)) } test() print(sprintf("the value from global:%i", i))
結果為:
由結果可知,在test()和innertest()中的i值都沒有發生變化,而在最頂層的全局層次中沒有定義i的值,結果顯示該值為10。
原因在於,在函數test()內部定義的函數innertest()中執行瞭assign函數,該函數在最頂層全局層次中的變量i賦值10,但是該層中並沒有該變量,於是就就在最頂層.GlobalEnv中創建瞭該變量i並給其賦值,這樣在不同的函數層次中都有變量i,優先引用離自己最近的同級(已順序執行)或者上級層次中的變量,所以i出現瞭三個不同的輸出值。
以上為個人經驗,希望能給大傢一個參考,也希望大傢多多支持WalkonNet。如有錯誤或未考慮完全的地方,望不吝賜教。
推薦閱讀:
- None Found