一、值傳遞
在R語言中,一切皆為對象,同時在調(diào)用函數(shù)的時候也采用值傳遞的方式,即作為參數(shù)的對象會被復(fù)制,然后將副本傳遞給函數(shù)
例如:
> f<-function(df2){
+?? df2$a<-c(1,2,3)
+ }
> df<-data.frame(a=c(4,5,6))
> f(df)
> df
? a
1 4
2 5
3 6
這里將數(shù)據(jù)框作為參數(shù)傳遞給函數(shù)的時候,函數(shù)內(nèi)部的修改將不會影響原對象。這是因為調(diào)用f()函數(shù)時采用的時值傳遞的方法;df2中保持的不是指向原始數(shù)據(jù)df的引用,而是復(fù)制數(shù)據(jù)框df,df2指向的是副本數(shù)據(jù)框
如果我們想讓函數(shù)內(nèi)部的改動影響到函數(shù)外部,則需要在函數(shù)f()內(nèi)部用返回值修改語句,然后再將函數(shù)的返回值的修改結(jié)果賦值給原來的變量
例如:
> f<-function(df2){
+?? df2$a<-c(1,2,3)
+?? return(df2)
+ }
> df<-data.frame(a=c(4,5,6))
> df<-f(df)
> df
? a
1 1
2 2
3 3
因此我們可以得出結(jié)論,除了特殊對象以外,對象狀態(tài)不會被函數(shù)直接修改,無論哪種函數(shù)能能保證參數(shù)傳遞的對象不被修改
PS:這一部分我覺得結(jié)合C++中指針那一塊的內(nèi)容食用更佳
二、對象不變性
R中的對象通常是不變的,在編程中,值不變意味著數(shù)值不能被修改
例如:
> a<-list()
> a$b<-c(1,2,3)
這則代碼實(shí)際上進(jìn)行的步驟是先復(fù)制a,創(chuàng)建新對象a',然后向?qū)ο骯'添加屬性b,再將c(1,2,3)填充到b,最后讓變量名指向a'。
而并非在a中直接開辟一個新屬性b,讓后將c(1,2,3)復(fù)制給b
我們利用對象復(fù)制追蹤函數(shù)tracemem()進(jìn)行查看
> a<-list()
> tracemem(a)
[1] "<000001D6746E3A80>"
> tracemem(a$b<-c(1,2,3))
[1] "<000001D6771B61E8>"
我們可以發(fā)現(xiàn)內(nèi)存地址進(jìn)行了更改,意味著其進(jìn)行了復(fù)制導(dǎo)致內(nèi)存地址增加
所以在R語言里使用循環(huán)語句是很不明智的,因為會導(dǎo)致內(nèi)存占用不斷增加吃掉太多資源,從而讓效率降低,因此我們還是推薦使用向量來代替實(shí)現(xiàn)循環(huán)語句文章來源:http://www.zghlxwxcb.cn/news/detail-838364.html
例如我們要實(shí)現(xiàn)1~1000000全體加1文章來源地址http://www.zghlxwxcb.cn/news/detail-838364.html
循環(huán)語句
> v<-1:1000000
> for(i in 1:1000000)
+?? v[i]<-v[i]+1
執(zhí)行完畢后會發(fā)現(xiàn)內(nèi)存急速擴(kuò)大
利用向量
> v<-1:1000000
> v<-v+1
這樣會快很多,而且占用資源更低
到了這里,關(guān)于第三章:R語言編程 第五節(jié):值傳遞&對象不變性的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!